인공지능/LLM 서비스 개발

벡터 데이터베이스

Ryuzy 2025. 2. 18. 10:52
728x90
반응형

1. 벡터 데이터베이스

벡터 데이터베이스(Vector Database)는 데이터를 수치화한 벡터 형태로 저장하고, 유사한 벡터를 빠르게 검색할 수 있도록 설계된 데이터베이스입니다. 주로 문서, 이미지, 음성, 동영상 등의 비정형 데이터를 임베딩(embedding) 기법을 사용해 벡터로 변환한 후 저장하며, 최근접 이웃 검색(Nearest Neighbor Search, NNS) 알고리즘을 통해 입력된 벡터와 가장 유사한 벡터를 효율적으로 찾습니다. 대표적인 벡터 데이터베이스로는 FAISS, Milvus, Pinecone, Weaviate 등이 있으며, RAG(Retrieval-Augmented Generation) 시스템에서 검색 성능을 높이기 위해 자주 사용됩니다.

 

 

2. 벡터 데이터베이스 검색

벡터 데이터베이스에서 검색을 수행할 때, 일반적으로 유사도 검색(Similarity Search)과 MMR(Maximal Marginal Relevance) 검색 두 가지 방식이 사용됩니다. 두 방법 모두 RAG(Retrieval-Augmented Generation) 시스템에서 중요한 역할을 합니다.

 

파이스 유사도 검색

FAISS(Facebook AI Similarity Search)는 Meta(에서 개발한 오픈소스 벡터 검색 라이브러리로, 대규모 벡터 데이터를 효율적으로 검색할 수 있도록 설계되었습니다. 특히 유클리드 거리(Euclidean Distance)와 코사인 유사도(Cosine Similarity) 기반의 최근접 이웃 검색(Nearest Neighbor Search, NNS)을 최적화하여 빠른 검색 속도를 제공합니다. FAISS는 GPU 가속을 지원하며, 수십억 개의 벡터에 대해 고속 검색이 가능하므로, 이미지 검색, 추천 시스템, RAG(Retrieval-Augmented Generation) 등 다양한 AI 애플리케이션에서 널리 사용됩니다. 또한, IVF(Inverted File Index), HNSW(Hierarchical Navigable Small World) 등 다양한 인덱싱 기법을 제공하여 메모리 사용량을 줄이고 검색 속도를 더욱 향상시킬 수 있습니다.

!pip install langchain-community

 

from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
from langchain.callbacks import get_openai_callback
from IPython.display import JSON

 

text = """생성형 인공지능 또는 생성형 AI는 프롬프트에 대응하여 텍스트, 이미지, 기타 미디어를 생성할 수 있는 일종의 인공지능 시스템이다.
단순히 기존 데이터를 분석하는 것이 아닌, 새로운 콘텐츠를 만드는 데 초점을 맞춘 인공지능 분야를 말한다. 2022년경부터 본격적으로 유명해지기 시작했다.
데이터 원본을 통한 학습으로 소설, 이미지, 비디오, 코딩, 음악, 미술 등 다양한 콘텐츠 생성에 이용된다. 한국에서는 2022년 Novel AI 등, 그림 인공지능의 등장으로 주목도가 높아졌으며, 해외에서는 미드저니, 챗GPT등 여러 모델을 잇달아 공개하면서 화제의 중심이 되었다.
보통 딥러닝 인공지능은 학습 혹은 결과 출력 전 원본 자료를 배열 자료형[2] 숫자 데이터로 변환하는 인코딩 과정이 중요한데, 생성 AI의 경우 인공지능의 출력 데이터를 역으로 그림, 글 등의 원하는 형태로 변환시켜주는 디코딩 과정 또한 필요하다.
사실상 인공지능의 대중화를 이끈 기술로써, 해당 기술이 인공지능에 대한 사람들의 전반적인 인식을 매우 크게 바꿔놨다고 해도 과언이 아니다.
"""
#CharacterTextSplitter을 이용한 청킹
splitter = CharacterTextSplitter(
separator="\n",
chunk_size=300,
chunk_overlap=50,
length_function=len
)

#주어진 문장 청킹
chunks = splitter.split_text(text)
print(chunks)

 

api_key = 'sk-proj 본인의 API 키'

 

!pip install faiss-cpu
!pip install tiktoken

 

OpenAI Embedding Model

OpenAI Embedding Model은 텍스트 데이터를 고차원 벡터로 변환하는 임베딩(Embedding) 모델로, 주어진 문장이나 단어의 의미적 유사성을 벡터 공간에서 표현할 수 있도록 합니다. OpenAI의 임베딩 모델은 주로 **코사인 유사도(Cosine Similarity)나 유클리드 거리(Euclidean Distance)**를 활용하여 텍스트 간 유사도를 측정하며, 검색, 추천 시스템, 문서 클러스터링, RAG(Retrieval-Augmented Generation) 등의 AI 애플리케이션에서 사용됩니다. 대표적인 모델로는 text-embedding-ada-002가 있으며, 이는 성능과 비용 효율성이 뛰어나 벡터 데이터베이스(Pinecone, Chroma, FAISS 등)와 함께 활용됩니다.

#임베딩 모델
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002", api_key=api_key)
#텍스트 임베딩을 FAISS FAISS(Vector Store)에 저장
knowledge_base = FAISS.from_texts(chunks, embeddings)
print(knowledge_base)

 

question = "생성형 AI란?"
references = knowledge_base.similarity_search(question)

 

from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(model="gpt-3.5-turbo", api_key=api_key)
chain = load_qa_chain(llm, chain_type="stuff")
with get_openai_callback() as cb:
    response = chain.run(input_documents=references, question=question)
    print(cb)
    
print(response)

 

크로마 유사도 검색

크로마(Chroma)는 빠르고 가벼운 오픈소스 벡터 데이터베이스로, LLM 기반 애플리케이션에서 검색 및 유사도 기반 검색을 쉽게 구현할 수 있도록 설계되었습니다. Python 기반으로 사용이 간편하며, 데이터 저장 및 검색을 위해 코사인 유사도, 유클리드 거리, 내적(Dot Product) 등의 거리 측정 방식을 지원합니다. Chroma는 LangChain, OpenAI API 등과의 연동이 용이하여 RAG(Retrieval-Augmented Generation) 시스템 구축에 자주 사용되며, 로컬 및 클라우드 환경에서 간편하게 실행할 수 있는 것이 장점입니다. 또한, in-memory 및 persistent 저장 방식을 지원하여 성능과 데이터 지속성을 유연하게 조절할 수 있습니다.

!pip install langchain-community
!pip install pypdf

 

from langchain.document_loaders import PyPDFLoader

# PDF 가져오기
loaders = [
    PyPDFLoader("스마트농업_육성사업_추진현황과_개선과제.pdf"),
    PyPDFLoader("차세대 한국형 스마트팜 개발.pdf")
]
docs = []
for loader in loaders:
    docs.extend(loader.load())

 

# Splitter를 이용한 청킹
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size = 1500,
    chunk_overlap = 150
)

#splitter를 이용한 문서 청킹
splits = text_splitter.split_documents(docs)
print(splits)

 

from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
#임베딩 모델 생성
embedding = OpenAIEmbeddings(model="text-embedding-ada-002", openai_api_key="sk-proj-본인의 API키")

 

!pip install chromadb
!pip install tiktoken

 

#크로마 벡터 영구 저장소 지정
persist_directory = 'data/'

#벡터 저장소
vectordb = Chroma.from_documents(
    documents=splits,
    embedding=embedding,
    persist_directory=persist_directory
)

print(vectordb._collection.count())

 

question = "한국형 스마트팜이란?"

docs = vectordb.similarity_search(question,k=3)  #return 받고자하는 문서의 수를 3개로 지정

# 문서 길이 확인
print(len(docs))

# 첫번째 문서의 콘텐츠 확인
print(docs[0].page_content)

 

question = "필요한 ICT 기술은?"

docs = vectordb.similarity_search(question,k=5) #return 받고자하는 문서의 수를 5개로 지정

# 처음 2개의 결과 확인
print(docs[0])
print('\n\n', docs[1])

 

MMR

MMR(Maximal Marginal Relevance) 검색은 벡터 데이터베이스에서 검색된 결과의 유사성과 다양성을 균형 있게 조정하는 검색 기법입니다. 일반적인 유사도 검색은 가장 유사한 벡터만 반환하지만, MMR은 이미 선택된 결과와의 중복을 줄이면서도 쿼리와 관련성이 높은 항목을 선택하여 검색 결과의 다양성을 확보합니다. 이를 통해 RAG(Retrieval-Augmented Generation) 시스템에서 중복된 정보를 줄이고, 보다 풍부하고 균형 잡힌 문서를 검색할 수 있도록 돕습니다. MMR은 유사도와 중복 방지를 조절하는 λ(람다) 값을 사용하여 검색 결과의 다양성을 조정할 수 있으며, 특히 LLM 기반의 문서 검색 및 챗봇 응답 생성에 효과적으로 활용됩니다.

!pip install langchain-community
!pip install chromadb
!pip install tiktoken

 

texts = [
    """ChatGPT 열풍으로 인해 생성형 AI에 대한 관심이 뜨겁다. 생성형 AI는 이용자의 특정 요구에 따라 결과를 능동적으로 생성해 내는 인공지능 기술이다.""",
    """특히, 생성형 AI는 대량의 데이터(Hyper-scale Data)를 학습하여 인간의 영역이라고 할 수 있는 창작의 영역까지 넘보고 있다.""",
    """베타 버전 출시2개월 만에 MAU(월간 활성 이용자 수)가 무려 1억 명을 넘어섰다. 또한 구글, 메타 등 글로벌 빅테크 기업들이 앞다투어 천문학적인 규모의 투자와 유사 서비스 출시 계획을발표하고 있다.""",
    """이 서비스의 핵심은 서비스 이용자의 질문을 이해하고 분석하여 수많은 정보 중 답이 될 만한 필요정보를 스스로 찾아서 이를 적절히 요약과 정리해 제공하는 것이다 """,
    """특히 앞서 질문한 내용의 맥락을 잇거나 구체적인 사례를 들어 질문할수록 더 정확한 답을 얻을 수 있는데, 이는 마치 사람과 대화하는 것처럼 맥락을 이해하여 답을 제공한다는 점에서 이전과 차원이 다른 정보 검색 서비스를 체감하게 한다."""
]

 

from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings

embedding = OpenAIEmbeddings(model="text-embedding-ada-002", openai_api_key="sk-proj-본인의 API키")

 

smalldb = Chroma.from_texts(texts, embedding=embedding)
question = "생성형 AI에 대해 언급된 내용은?"

 

smalldb.max_marginal_relevance_search(question,k=2, fetch_k=3)

 

# similarity searcha 검색 결과
question = "생성형 AI 핵심 기능은?"
docs_ss = smalldb.similarity_search(question,k=2)
print(docs_ss[0].page_content[:100])
print('\n\n', docs_ss[1].page_content[:100])

 

#Maximum Marginal Relevance(MMR) 검색
docs_mmr = smalldb.max_marginal_relevance_search(question,k=2)
print(docs_mmr[0].page_content[:100])
print('\n\n',docs_mmr[1].page_content[:100])
728x90
반응형