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 기반 검색 시스템을 구축할 수 있다.
 

+ Recent posts