VectorStore는 자연어 → 숫자 처리한 후 이들을 저장하는 벡터 저장소입니다.
벡터 저장소는 임베딩된 데이터를 인덱싱하여, input으로 받아들이는 query와의 유사도를 빠르게 출력합니다.
대표적으로 FAISS, Chroma가 존재합니다.

- Pure vector DB
- Vector lib
Chroma
Chroma는 대표적인 오픈소스 벡터 저장소입니다.
!pip install chromadb tiktoken transformers sentence_transformers openai langchain pypdf
기본적으로 VectorStore는 벡터를 일시적으로 저장합니다. 텍스트와 임베딩 함수를 지정하여 from_documents() 함수에 보내면, 지정된 임베딩 함수를 통해 텍스트를 벡터로 변환하고, 이를 임시 db로 생성합니다.
그리고 similarity_search() 함수에 쿼리를 지정해주면 이를 바탕으로 가장 벡터 유사도가 높은 벡터를 찾고 이를 자연어 형태로 출력합니다.
import tiktoken
from langchain.text_splitter import RecursiveCharacterTextSplitter
tokenizer = tiktoken.get_encoding("cl100k_base")
def tiktoken_len(text):
tokens = tokenizer.encode(text)
return len(tokens)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.document_loaders import PyPDFLoader
# load the document and split it into chunks
loader = PyPDFLoader("/content/drive/MyDrive/LLM자료/[이슈리포트 2022-2호] 혁신성장 정책금융 동향.pdf")
pages = loader.load_and_split()
# split it into chunks
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0, length_function = tiktoken_len)
docs = text_splitter.split_documents(pages)
# create the open-source embedding function
from langchain.embeddings import HuggingFaceEmbeddings
model_name = "jhgan/ko-sbert-nli"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
hf = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
# load it into Chroma
db = Chroma.from_documents(docs, hf)
# query it
query = "6대 먹거리 산업은?"
docs = db.similarity_search(query)
# print results
print(docs[0].page_content)
그런데, 대부분의 경우에서는 내가 활용하고자 하는 문서를 나만의 디스크에 저장하고 필요할 때마다 호출해야 합니다. persist() 함수를 통해 벡터저장소를 로컬 저장하고, Chroma 객체를 선언할 때 로컬 저장소 경로를 지정하여 필요할 때 다시 불러올 수 있습니다.
# save to disk
db2 = Chroma.from_documents(docs, hf, persist_directory="./chroma_db")
docs = db2.similarity_search(query)
# load from disk
db3 = Chroma(persist_directory="./chroma_db", embedding_function=hf)
docs = db3.similarity_search(query)
print(docs[0].page_content)
쿼리와 유사한 문서(청크)를 불러올 때, 유사도를 함께 제공하는 함수 similarity_search_with_score()를 제공합니다. 이를 통해서 내가 얻은 유사한 문장들의 유사도를 비교할 수 있으며, 특정 유사도 이상의 문서만 출력하도록 하는 등 다양한 활용이 가능합니다.
docs = db3.similarity_search_with_relevance_scores(query, k=3)
print("가장 유사한 문서:\\n\\n {}\\n\\n".format(docs[0][0].page_content))
print("문서 유사도:\\n {}".format(docs[0][1]))
FAISS
Facebook AI 유사성 검색(Faiss)은 고밀도 벡터의 효율적인 유사성 검색 및 클러스터링을 위한 라이브러리입니다. 여기에는 모든 크기의 벡터 집합에서 검색하는 알고리즘이 포함되어 있으며, RAM에 맞지 않을 수 있는 벡터까지 검색할 수 있습니다. 또한 평가 및 매개변수 조정을 위한 지원 코드도 포함되어 있습니다.
pip install faiss-cpu # For CPU Installation
from langchain.vectorstores import FAISS
loader = PyPDFLoader("/content/drive/MyDrive/LLM자료/[이슈리포트 2022-2호] 혁신성장 정책금융 동향.pdf")
pages = loader.load_and_split()
# split it into chunks
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0, length_function = tiktoken_len)
docs = text_splitter.split_documents(pages)
from langchain.embeddings import HuggingFaceEmbeddings
model_name = "jhgan/ko-sbert-nli"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
ko = HuggingFaceEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
db = FAISS.from_documents(docs, ko)
query = "인공지능 산업구조는 어떻게 구성되어있어?"
docs = db.similarity_search(query)
print(docs[0].page_content)
docs_and_scores = db.similarity_search_with_score(query)
docs_and_scores
db.save_local("faiss_index")
new_db = FAISS.load_local("faiss_index", ko)
query = "인공지능 산업구조는 어떻게 구성되어있어?"
docs = new_db.similarity_search_with_relevance_scores(query, k=3)
print("질문: {} \\n".format(query))
for i in range(len(docs)):
print("{0}번째 유사 문서 유사도 \\n{1}".format(i+1,round(docs[i][1],2)))
print("-"*100)
print(docs[i][0].page_content)
print("\\n")
print(docs[i][0].metadata)
print("-"*100)
query = "인공지능 산업구조는 어떻게 구성되어있어?"
docs = new_db.max_marginal_relevance_search(query,k=3,fetch_k = 10, lambda_mult = 0.3)
print("질문: {} \\n".format(query))
for i in range(len(docs)):
print("{}번째 유사 문서:".format(i+1))
print("-"*100)
print(docs[i].page_content)
print("\\n")
print(docs[i].metadata)
print("-"*100)
print("\\n\\n")
'LLM > LLM 공부' 카테고리의 다른 글
Retriever (0) | 2025.03.07 |
---|---|
Retrieval-Text Embeddings (0) | 2025.03.07 |
Retrieval - Text Splitters (0) | 2025.03.07 |
Retrieval - Document Loaders (0) | 2025.03.07 |
PromptTemplate에 대해 (0) | 2025.03.07 |