1. 왜 FAISS가 중요한가?
대규모 문서에서 유사한 정보를 검색하는 것은 AI 애플리케이션에서 필수적인 기능이다. 전통적인 방법(예: TF-IDF, BM25)은 단순한 키워드 매칭에 의존하여 문맥을 제대로 반영하지 못한다. 반면 **FAISS(Facebook AI Similarity Search)**를 활용하면 벡터 검색을 통해 고차원 의미를 고려한 초고속 검색이 가능하다.
FAISS는 특히 다음과 같은 경우에 강력하다.
• 수백만 개 이상의 문서를 실시간으로 검색해야 하는 경우
• 질문-응답 시스템(QA), 추천 시스템, 챗봇을 구축하는 경우
• LLM(Large Language Model)과 연동하여 RAG(Retrieval-Augmented Generation) 시스템을 만들려는 경우
이번 글에서는 FAISS가 어떻게 작동하는지, 그리고 LangChain과 함께 벡터 검색 기반 문서 검색 시스템을 구축하는 방법을 살펴보자.
2. FAISS 개념 이해: 벡터 검색이란?
LLM이 문서를 이해하고 검색하려면 텍스트 데이터를 벡터로 변환해야 한다. 이를 **임베딩(Embedding)**이라 하며, 각 문장은 다차원 공간에서 하나의 점으로 표현된다. FAISS는 이런 벡터들을 효율적으로 저장하고 초고속 검색이 가능하도록 최적화된 라이브러리다.
FAISS가 특히 뛰어난 이유는 다음과 같다.
• L2 거리 기반 최근접 이웃(Nearest Neighbor) 검색
• 수억 개의 벡터를 저장해도 빠른 인덱싱 및 검색 속도
• CPU/GPU 최적화로 대규모 벡터 검색 성능 극대화
3. FAISS + LangChain을 활용한 문서 검색 시스템 구축
이제 실제로 FAISS를 활용하여 PDF 문서를 벡터화하고, LangChain을 통해 문서 검색 시스템을 구축하는 과정을 살펴보자.
📌 Step 1: 필요한 라이브러리 설치
다음 패키지를 설치해야 한다.
pip install langchain faiss-cpu openai pypdf sentence-transformers
📌 Step 2: PDF 문서 로드 및 텍스트 추출
먼저, PDF 문서에서 텍스트를 추출해야 한다.
from langchain.document_loaders import PyPDFLoader
# PDF 문서 로드
pdf_path = "example.pdf" # 분석할 PDF 파일
loader = PyPDFLoader(pdf_path)
documents = loader.load()
# 첫 번째 문서 확인
print(documents[0].page_content)
이렇게 하면 PDF 문서의 내용을 documents 리스트에 저장할 수 있다.
📌 Step 3: 문서를 임베딩(Embedding) 벡터로 변환
텍스트 데이터를 벡터로 변환하려면, OpenAI 또는 Sentence Transformers를 사용할 수 있다. 여기서는 무료로 사용할 수 있는 sentence-transformers를 활용해 보자.
from langchain.embeddings import HuggingFaceEmbeddings
# 임베딩 모델 로드 (한국어 포함 지원)
embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
# 첫 번째 문서 벡터화
text_sample = documents[0].page_content
vector = embedding_model.embed_query(text_sample)
print("벡터 차원:", len(vector))
이제 텍스트가 다차원 벡터로 변환되었으며, 이 벡터를 기반으로 검색할 수 있다.
📌 Step 4: FAISS를 활용한 벡터 저장 및 검색
이제 FAISS를 사용하여 벡터 데이터베이스를 구축하고 검색을 수행해 보자.
from langchain.vectorstores import FAISS
# 문서 데이터를 벡터화하여 FAISS에 저장
faiss_index = FAISS.from_documents(documents, embedding_model)
# FAISS 인덱스를 로컬에 저장 (추후 빠른 로드 가능)
faiss_index.save_local("faiss_index")
📌 Step 5: 유사한 문서 검색하기
이제 사용자가 입력한 질문과 가장 유사한 문서를 FAISS에서 검색해 보자.
# 저장된 FAISS 인덱스 불러오기
faiss_index = FAISS.load_local("faiss_index", embedding_model)
# 검색할 질문 입력
query = "계약서에서 위약금 조항을 어떻게 확인하나요?"
# FAISS를 통해 유사 문서 검색
search_results = faiss_index.similarity_search(query, k=3)
# 검색 결과 출력
for i, doc in enumerate(search_results):
print(f"결과 {i+1}:")
print(doc.page_content)
print("="*80)
이제 사용자가 입력한 질문과 가장 유사한 문서 3개를 검색할 수 있다.
4. FAISS의 성능을 극대화하는 방법
FAISS를 사용할 때, 성능을 극대화하는 몇 가지 핵심 기술이 있다.
1️⃣ IVF(InvList File) 인덱싱을 활용한 검색 속도 향상
FAISS는 기본적으로 L2 거리 기반 검색을 사용하지만, IVF(인버스 리스트 파일) 인덱싱을 적용하면 속도를 더욱 빠르게 만들 수 있다.
import faiss
# 128차원 벡터를 저장할 IVF 인덱스 생성 (클러스터 개수 100)
d = 128 # 벡터 차원
nlist = 100 # 클러스터 개수
quantizer = faiss.IndexFlatL2(d)
index = faiss.IndexIVFFlat(quantizer, d, nlist)
# 학습 데이터로 클러스터링
index.train(vector_data) # vector_data는 벡터 리스트
index.add(vector_data) # 인덱스에 벡터 추가
2️⃣ GPU 가속을 활용한 대규모 검색
FAISS는 GPU 연산을 지원하므로 수천만 개의 벡터를 초고속 검색할 수 있다.
import faiss
# CPU -> GPU 변환
gpu_index = faiss.index_cpu_to_gpu(faiss.StandardGpuResources(), 0, index)
# GPU에서 벡터 검색 실행
D, I = gpu_index.search(query_vector, k=5)
5. FAISS와 LangChain을 활용한 실전 적용 사례
FAISS는 실제로 대용량 데이터를 빠르게 검색해야 하는 다양한 AI 프로젝트에 사용된다.
1. LLM 기반 RAG(Retrieval-Augmented Generation)
• FAISS를 사용하여 외부 문서를 검색하고, LLM의 컨텍스트를 보강
• ChatGPT와 결합하여 문맥을 더 잘 반영하는 챗봇 제작
2. 기업용 문서 검색 시스템
• 내부 정책 문서, 계약서, 기술 매뉴얼을 벡터화하여 검색
3. AI 기반 추천 시스템
• 유사한 뉴스 기사, 논문, 제품을 추천하는 서비스
결론
FAISS는 대규모 문서 검색 및 추천 시스템을 구축할 때 필수적인 벡터 검색 엔진이다. 특히 LangChain과 결합하면 강력한 RAG 기반 검색 시스템을 구축할 수 있다.
'개발' 카테고리의 다른 글
Redis의 숨겨진 강자: RedisJSON과 RedisSearch로 NoSQL 초고속 검색 및 분석하기 (0) | 2025.03.05 |
---|---|
DuckDB: OLAP에 특화된 초고속 컬럼형 데이터베이스, SQLite를 대체할 차세대 솔루션 (0) | 2025.03.05 |
LangChain의 고급 활용: LangGraph로 멀티 에이전트 워크플로우 구축하기 (0) | 2025.03.05 |
Python의 yield와 send(): 잘 몰랐던 제너레이터의 강력한 숨은 기능 (0) | 2025.02.19 |
SQLAlchemy “Subquery ORM”: ORM에서 서브쿼리를 최적화하는 숨겨진 기법 (0) | 2025.02.19 |