forked from teddylee777/langchain-kr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
acb23b3
commit ed902df
Showing
4 changed files
with
1,050 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
Oops, something went wrong.