FAISS는 페이스북에서 개발한 대용량 벡터 검색 라이브러리로, 밀집 벡터의 유사도를 빠르게 계산하고 클러스터링하는 데 사용된다. 주로 텍스트, 이미지, 음성 등 비정형 데이터를 벡터 형태로 변환하여 유사도 기반 검색 을 수행하는 데 활용된다.
chromadb 처럼 로컬에 저장해놓고 사용이 가능하다 하여 테스트해 봤다.
from langchain_huggingface import HuggingFaceEmbeddings
import os
# 허깅페이스 임베딩 모델명 설정
embedding_model_name = "sentence-transformers/paraphrase-xlm-r-multilingual-v1"
# 허깅페이스 토큰 설정
huggingface_token = os.getenv("HUGGINGFACE_API_KEY")
# 허깅페이스 임베딩 모델 초기화
embeddings = HuggingFaceEmbeddings(
model_name=embedding_model_name,
model_kwargs={"device": "mps"},
encode_kwargs={"normalize_embeddings": True}
)
# 허깅페이스 임베딩 모델을 반환하는 함수
def getEmbeddingHuggingface():
return embeddings
% pip install pytorch faiss-cpu
from langchain_text_splitters import RecursiveCharacterTextSplitter
from embedding.huggingface_768 import getEmbeddingHuggingface
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.vectorstores.faiss import FAISS
# PDF 파일 로드
loader = PyPDFLoader("./prince.pdf")
pages = loader.load()
# 문서 분할
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=450,
chunk_overlap=100,
length_function=len
)
split_docs = text_splitter.split_documents(pages)
# 임베딩 모델 불러오기
embedding_model = getEmbeddingHuggingface()
# FAISS 벡터 저장소에 문서 저장
try:
vectorstore = FAISS.from_documents(
documents=split_docs,
embedding=embedding_model
)
# 인덱스를 로컬에 저장 (예: ./faiss_index)
vectorstore.save_local("faiss_index")
print("Documents processed and FAISS index saved successfully")
except Exception as e:
print(f"Error processing documents: {e}")
insert 후에는 이런 파일들이 생긴다.
from langchain.chains import RetrievalQA
from langchain import hub
from langchain_community.vectorstores.faiss import FAISS
from langchain_community.llms import Ollama
from embedding.huggingface_768 import getEmbeddingHuggingface
# 1. 허깅페이스 임베딩 로드
embeddings = getEmbeddingHuggingface()
# 2. FAISS 인덱스를 저장한 경로
faiss_index_path = "faiss_index"
vectorstore = FAISS.load_local(
folder_path=faiss_index_path,
embeddings=embeddings,
allow_dangerous_deserialization=True
)
# 유사도 검색 테스트. ok
#docs = vectorstore.similarity_search("아이들에게 손수건은?")
#print(docs[0])
# 3. Retriever 설정
retriever = vectorstore.as_retriever()
# 4. LLM 설정
llm = Ollama(model="llama3.1:8b")
# 5. 프롬프트 가져오기
prompt = hub.pull("rlm/rag-prompt")
# 6. 체인 구성
chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=retriever,
chain_type_kwargs={"prompt": prompt}
)
# 7. 체인 실행
result = chain({"query": "소행성 B612호는 무엇인가?"})
print(result["result"])
결과는 이렇게... llama3:8b 치곤 괜찮은거 같은데 이건 테스트를 많이 해봐야겠다.
from langchain.chains import RetrievalQA
from langchain import hub
from langchain_community.vectorstores.faiss import FAISS
from langchain_community.llms import Ollama
from embedding.huggingface_768 import getEmbeddingHuggingface
from langchain.prompts import PromptTemplate
# 1. 허깅페이스 임베딩 로드
embeddings = getEmbeddingHuggingface()
# 2. FAISS 인덱스를 저장한 경로
faiss_index_path = "faiss_index"
vectorstore = FAISS.load_local(
folder_path=faiss_index_path,
embeddings=embeddings,
allow_dangerous_deserialization=True
)
# 3. Retriever 설정
retriever = vectorstore.as_retriever()
# 4. LLM 설정
llm = Ollama(model="exaone3.5:7.8b")
# 5. 커스텀 프롬프트 정의
custom_prompt = PromptTemplate(
input_variables=["context", "question"],
template="""
당신은 매우 정밀한 질문 응답 시스템입니다. 다음의 문맥을 참고하여 사용자의 질문에 답하세요.
문맥:
{context}
질문:
{question}
정확하고 간결한 답변:
""".strip()
)
# 6. 체인 구성
chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=retriever,
chain_type_kwargs={"prompt": custom_prompt}
)
# 7. 체인 실행
result = chain({"query": "소행성 B612호는 무엇인가?"})
print(result["result"])