pip install faiss-cpu
/ poetry add faiss-cpu
# 벡터 저장소에 문서를 저장할 때 적용할 임베딩 모델
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
embeddings_model = HuggingFaceEmbeddings(model_name="BAAI/bge-m3")
.IndexFlatL2(임베딩차원)
으로 index 를 생성한다. # 벡터 저장소 생성
import faiss
from langchain_community.docstore.in_memory import InMemoryDocstore
from langchain_community.vectorstores import FAISS
# FAISS 인덱스 초기화 (유클리드 거리 사용)
faiss_index = faiss.IndexFlatL2(len(embeddings_model.embed_query("hello world")))
print("FAISS 인덱스 초기화 완료")
- 출력
FAISS 인덱스 초기화 완료
# FAISS 벡터 저장소의 벡터 차원 수 (임베딩 차원 수)
faiss_index.d
- 출력
1024
# FAISS 벡터 저장소 생성
faiss_db = FAISS(
embedding_function=embeddings_model,
index=faiss_index, # 벡터 검색을 위한 데이터 구조를 정의
docstore=InMemoryDocstore(), # 문서 저장소 객체를 지정 - 문서의 원본 내용과 메타데이터를 보관
index_to_docstore_id={}, # 인덱스와 문서 간의 연결을 관리 (매핑 딕셔너리)
)
# 저장된 문서의 갯수 확인
faiss_db.index.ntotal
- 출력
0
vector_store.add_documents(documents, ids)
from langchain_core.documents import Document
# 문서 데이터 - (텍스트, 소스)
documents = [
("인공지능은 컴퓨터 과학의 한 분야입니다.", "AI 개론"),
("머신러닝은 인공지능의 하위 분야입니다.", "AI 개론"),
("딥러닝은 머신러닝의 한 종류입니다.", "딥러닝 입문"),
("자연어 처리는 컴퓨터가 인간의 언어를 이해하고 생성하는 기술입니다.", "AI 개론"),
("컴퓨터 비전은 컴퓨터가 디지털 이미지나 비디오를 이해하는 방법을 연구합니다.", "딥러닝 입문")
]
# Document 객체 생성
doc_objects = []
for content, source in documents:
doc = Document(
page_content=content,
metadata={"source": source},
)
doc_objects.append(doc)
# 순차적 ID 리스트 생성
doc_ids = [f"DOC_{i}" for i in range(1, len(doc_objects) + 1)]
# 문서를 벡터 저장소에 저장
added_doc_ids = faiss_db.add_documents(documents=doc_objects, ids=doc_ids)
# 벡터 저장소에 저장된 문서를 확인
print(f"{len(added_doc_ids)}개의 문서가 성공적으로 벡터 저장소에 추가되었습니다.")
print(added_doc_ids)
- 출력
5개의 문서가 성공적으로 벡터 저장소에 추가되었습니다.
['DOC_1', 'DOC_2', 'DOC_3', 'DOC_4', 'DOC_5']
# 저장된 문서의 갯수 확인
faiss_db.index.ntotal
- 출력
5
# 저장된 인덱스 확인
faiss_db.index_to_docstore_id
- 출력
{0: 'DOC_1', 1: 'DOC_2', 2: 'DOC_3', 3: 'DOC_4', 4: 'DOC_5'}
# 저장된 문서 검색
faiss_db.docstore.search('DOC_1')
- 출력
Document(id='DOC_1', metadata={'source': 'AI 개론'}, page_content='인공지능은 컴퓨터 과학의 한 분야입니다.')
vector_store.delete(ids)
# 문서 id를 지정하여 삭제
faiss_db.delete(ids=["DOC_5"])
- 출력
True
# 저장된 문서 객체를 확인
faiss_db.docstore._dict
- 출력
{'DOC_1': Document(id='DOC_1', metadata={'source': 'AI 개론'}, page_content='인공지능은 컴퓨터 과학의 한 분야입니다.'),
'DOC_2': Document(id='DOC_2', metadata={'source': 'AI 개론'}, page_content='머신러닝은 인공지능의 하위 분야입니다.'),
'DOC_3': Document(id='DOC_3', metadata={'source': '딥러닝 입문'}, page_content='딥러닝은 머신러닝의 한 종류입니다.'),
'DOC_4': Document(id='DOC_4', metadata={'source': 'AI 개론'}, page_content='자연어 처리는 컴퓨터가 인간의 언어를 이해하고 생성하는 기술입니다.')}
similarity_search
query = "인공지능과 머신러닝의 차이점은 무엇인가요?"
results = faiss_db.similarity_search(
query,
k=2,
filter={"source": "AI 개론"}
)
print("유사도 검색 결과:")
for doc in results:
print(f"- {doc.page_content} [출처: {doc.metadata['source']}]")
- 출력
유사도 검색 결과:
- 머신러닝은 인공지능의 하위 분야입니다. [출처: AI 개론]
- 인공지능은 컴퓨터 과학의 한 분야입니다. [출처: AI 개론]
similarity_search_with_score
query = "딥러닝은 어떤 분야에서 사용되나요?"
results = faiss_db.similarity_search_with_score(
query,
k=2,
filter={"source": "AI 개론"}
)
print("점수가 포함된 유사도 검색 결과:\n")
for doc, score in results:
print(f"- 점수: {score:.4f}")
print(f" 내용: {doc.page_content}")
print(f" [출처: {doc.metadata['source']}]")
print()
- 출력
점수가 포함된 유사도 검색 결과:
- 점수: 0.8442
내용: 머신러닝은 인공지능의 하위 분야입니다.
[출처: AI 개론]
- 점수: 0.9845
내용: 인공지능은 컴퓨터 과학의 한 분야입니다.
[출처: AI 개론]
similarity_search_with_relevance_scores
query = "딥러닝은 어떤 분야에서 사용되나요?"
results = faiss_db.similarity_search_with_relevance_scores(
query,
k=2,
filter={"source": "AI 개론"}
)
print(f"쿼리: {query}")
print("\n검색 결과 (관련성 점수 포함):")
for doc, score in results:
print(f"- 관련성 점수: {score:.4f}")
print(f" 내용: {doc.page_content}")
print(f" [출처: {doc.metadata['source']}]")
print()
- 출력
쿼리: 딥러닝은 어떤 분야에서 사용되나요?
검색 결과 (관련성 점수 포함):
- 관련성 점수: 0.4031
내용: 머신러닝은 인공지능의 하위 분야입니다.
[출처: AI 개론]
- 관련성 점수: 0.3038
내용: 인공지능은 컴퓨터 과학의 한 분야입니다.
[출처: AI 개론]
Chroma
의 경우 저장소 생성시 collection_name
과 persist_directory
로 이름과 저장 경로를 설정했었으나 FAISS
의 경우 생성 후 별도 저장 / 로드folder_path
와 index_name
으로 경로와 이름 설정 가능# 로컬에 저장
faiss_db.save_local("faiss_ai_sample_index")
▶ 위와 같은 형태로 저장된 모습
# 로컬에 저장된 FAISS 벡터 저장소 불러오기
faiss_db2 = FAISS.load_local(
"faiss_ai_sample_index", embeddings_model, allow_dangerous_deserialization=True
)