[LangChain] 5. Retrieval - VectorStores

김제현·2024년 1월 21일
0

LangChain

목록 보기
5/6
post-thumbnail

VectorStores

  • RAG에 임베딩 모델을 통해 수치화된 텍스트들을 벡터 저장소에 저장하고 유사 문장을 찾아주는 것
  • Vectorstore에는 여러 종류가 존재하지만, 대표적으로 Chroma, FAISS가 있다.
  • Pure vector databases: DB들이 가지고 있는 툴들이 만이 들어가있는
    vector libraries: 벡터 유사도를 측정

Chroma

  • 대표적인 오픈소스 벡터 저장소이다. 기본적으로 VectorStore는 벡터를 일시적으로 저장한다. 텍스트와 임베딩 함수를 지정하여 from_documents()함수에 보내면, 지정된 임베딩 함수를 통해 텍스트를 벡터로 변환하고, 이를 임시 db로 생성한다. 그리고 similarity_search()함수에 쿼리를 지정해주면 이를 바탕으로 가장 벡터 유사도가 높은 벡터를 찾고 이를 자연어 형태로 출력한다.

    pip install chromadb tiktoken transformers sentence_transformers

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.embeddings.sentence_transformer import SentenceTransformerEmbeddings
from langchain.vectorstores import Chroma
from langchain.document_loaders import TextLoader
from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("/Users/kimjehyeon/study/강의대화1.pdf")
pages = loader.load_and_split()

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}
hf = HuggingFaceEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

# 문서들을 Chroma VectorStore에 저장
db = Chroma.from_documents(docs, hf)

# query
query = "1대1 대화 방법이 뭔가요?"

# 이것과 관련된 내용
docs = db.similarity_search(query)

print(docs[0].page_content)
  • 문서들을 hf라는 huggingface 임베딩을 통해서 임베딩화 시키고 그것을 chroma 객체를 통해서 vector 저장을 한 것고 그 문장과 유사도가 높은 문장을 출력하는 것이다.

  • 대부분의 경우에서 내가 활용하고자 하는 문서를 나만의 디스크에 저장하고 필요할 때마다 호출해야한다. 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)
  • persist_directory를 통해 경로를 설정
  • 쿼리와 유사한 문서(청크)를 불러올 때, 유사도를 함께 제공하는 함수 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.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.document_loaders import TextLoader
import tiktoken
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import PyPDFLoader

tokenizer = tiktoken.get_encoding("cl100k_base")

def tiktoken_len(text):
    tokens = tokenizer.encode(text)
    return len(tokens)

loader = PyPDFLoader("/Users/kimjehyeon/study/강의대화1.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 = "1대1 대화 하는 방법이 뭐야?"
docs = db.similarity_search(query)
print(docs[0].page_content)

0개의 댓글