Skip to content

Commit

Permalink
2024.08.31 1차 코드 정리
Browse files Browse the repository at this point in the history
  • Loading branch information
teddylee777 committed Aug 31, 2024
1 parent acb23b3 commit ed902df
Show file tree
Hide file tree
Showing 4 changed files with 1,050 additions and 0 deletions.
203 changes: 203 additions & 0 deletions 11-Reranker/01-Cross-Encoder-Reranker.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "a0e0e30e",
"metadata": {},
"source": [
"# Cross Encoder Reranker\n",
"\n",
"## 개요\n",
"\n",
"Cross encoder reranker는 검색 증강 생성(RAG) 시스템의 성능을 향상시키기 위해 사용되는 기술입니다. 이 문서는 Hugging Face의 cross encoder 모델을 사용하여 retriever에서 reranker를 구현하는 방법을 설명합니다.\n",
"\n",
"## 주요 특징 및 작동 방식\n",
"\n",
"1. **목적**: 검색된 문서들의 순위를 재조정하여 질문에 가장 관련성 높은 문서를 상위로 올림\n",
"2. **구조**: 질문과 문서를 동시에 입력으로 받아 처리\n",
"3. **작동 방식**:\n",
" - 질문과 문서를 하나의 입력으로 사용하여 유사도를 직접 출력\n",
" - Self-attention 메커니즘을 통해 질문과 문서를 동시에 분석\n",
"4. **장점**:\n",
" - 더 정확한 유사도 측정 가능\n",
" - 질문과 문서 사이의 의미론적 유사성을 깊이 탐색\n",
"5. **한계점**:\n",
" - 연산 비용이 높고 시간이 오래 걸림\n",
" - 대규모 문서 집합에 직접 적용하기 어려움\n",
"\n",
"## 실제 사용\n",
"\n",
"- 일반적으로 초기 검색에서 상위 k개의 문서에 대해서만 reranking 수행\n",
"- Bi-encoder로 빠르게 후보를 추출한 후, Cross encoder로 정확도를 높이는 방식으로 활용\n",
"\n",
"## 구현\n",
"\n",
"- Hugging Face의 cross encoder 모델 또는 BAAI/bge-reranker와 같은 모델 사용\n",
"- LangChain 등의 프레임워크에서 CrossEncoderReranker 컴포넌트를 통해 쉽게 통합 가능\n",
"\n",
"## Reranker의 주요 장점\n",
"\n",
"1. 더 정확한 유사도 측정\n",
"2. 심층적인 의미론적 유사성 탐색\n",
"3. 검색 결과 개선\n",
"4. RAG 시스템 성능 향상\n",
"5. 유연한 통합\n",
"6. 다양한 사전 학습 모델 선택 가능\n",
"\n",
"## Reranker 사용 시 문서 수 설정\n",
"\n",
"- 일반적으로 상위 5~10개 문서에 대해 reranking 수행\n",
"- 최적의 문서 수는 실험과 평가를 통해 결정 필요\n",
"\n",
"## Reranker 사용시 Trade-offs\n",
"\n",
"1. 정확도 vs 처리 시간\n",
"2. 성능 향상 vs 계산 비용\n",
"3. 검색 속도 vs 관련성 정확도\n",
"4. 시스템 요구사항 충족\n",
"5. 데이터셋 특성 고려"
]
},
{
"cell_type": "markdown",
"id": "62f6a69f",
"metadata": {},
"source": [
"간단한 예시를 통해 Cross Encoder Reranker의 구현 방법을 설명하겠습니다."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e17956b",
"metadata": {},
"outputs": [],
"source": [
"# 문서 출력 도우미 함수\n",
"def pretty_print_docs(docs):\n",
" print(\n",
" f\"\\n{'-' * 100}\\n\".join(\n",
" [f\"Document {i+1}:\\n\\n\" + d.page_content for i, d in enumerate(docs)]\n",
" )\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3b1db61",
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.document_loaders import TextLoader\n",
"from langchain_community.vectorstores import FAISS\n",
"from langchain_huggingface import HuggingFaceEmbeddings\n",
"from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
"\n",
"# 문서 로드\n",
"documents = TextLoader(\"./data/appendix-keywords.txt\").load()\n",
"\n",
"# 텍스트 분할기 설정\n",
"text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)\n",
"\n",
"# 문서 분할\n",
"texts = text_splitter.split_documents(documents)\n",
"\n",
"# 임베딩 모델 설정\n",
"embeddingsModel = HuggingFaceEmbeddings(\n",
" model_name=\"sentence-transformers/msmarco-distilbert-dot-v5\"\n",
")\n",
"\n",
"# 문서로부터 FAISS 인덱스 생성 및 검색기 설정\n",
"retriever = FAISS.from_documents(texts, embeddingsModel).as_retriever(\n",
" search_kwargs={\"k\": 10}\n",
")\n",
"\n",
"# 질의 설정\n",
"query = \"Word2Vec 에 대해서 알려줄래?\"\n",
"\n",
"# 질의 수행 및 결과 문서 반환\n",
"docs = retriever.invoke(query)\n",
"\n",
"# 결과 문서 출력\n",
"pretty_print_docs(docs)"
]
},
{
"cell_type": "markdown",
"id": "74468bcf",
"metadata": {},
"source": [
"이제 기본 `retriever`를 `ContextualCompressionRetriever`로 감싸보겠습니다. `CrossEncoderReranker`는 `HuggingFaceCrossEncoder`를 사용하여 반환된 결과를 재정렬합니다."
]
},
{
"cell_type": "markdown",
"id": "eef9113d",
"metadata": {},
"source": [
"- 다국어 지원 BGE Reranker: [bge-reranker-v2-m3](https://huggingface.co/BAAI/bge-reranker-v2-m3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7951de8f",
"metadata": {},
"outputs": [],
"source": [
"from langchain.retrievers import ContextualCompressionRetriever\n",
"from langchain.retrievers.document_compressors import CrossEncoderReranker\n",
"from langchain_community.cross_encoders import HuggingFaceCrossEncoder\n",
"\n",
"# 모델 초기화\n",
"model = HuggingFaceCrossEncoder(model_name=\"BAAI/bge-reranker-v2-m3\")\n",
"\n",
"# 상위 3개의 문서 선택\n",
"compressor = CrossEncoderReranker(model=model, top_n=3)\n",
"\n",
"# 문서 압축 검색기 초기화\n",
"compression_retriever = ContextualCompressionRetriever(\n",
" base_compressor=compressor, base_retriever=retriever\n",
")\n",
"\n",
"# 압축된 문서 검색\n",
"compressed_docs = compression_retriever.invoke(\"Word2Vec 에 대해서 알려줄래?\")\n",
"\n",
"# 문서 출력\n",
"pretty_print_docs(compressed_docs)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f2238413",
"metadata": {},
"outputs": [],
"source": [
"compressed_docs"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "langchain-kr-lwwSZlnu-py3.11",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit ed902df

Please sign in to comment.