리랭킹
Reranking
검색 결과를 재정렬하여 관련성을 높이는 기법. RAG 파이프라인에서 활용.
Reranking
검색 결과를 재정렬하여 관련성을 높이는 기법. RAG 파이프라인에서 활용.
리랭킹(Reranking)은 초기 검색 결과를 더 정교한 모델로 재정렬하여 관련성을 높이는 기법입니다. 첫 번째 단계에서 빠른 검색(sparse retrieval 또는 dense retrieval)으로 후보를 선별하고, 두 번째 단계에서 cross-encoder 같은 정밀 모델이 쿼리와 각 문서를 직접 비교하여 순위를 재조정합니다.
리랭킹이 등장한 배경은 검색 시스템의 정확도-속도 트레이드오프입니다. BM25 같은 sparse 검색은 빠르지만 의미를 놓치고, bi-encoder는 빠르지만 쿼리-문서 간 상호작용이 부족합니다. Cross-encoder는 정확하지만 느려서, 2단계 구조로 이 문제를 해결합니다. 2020년 BERT 기반 리랭커가 등장하며 주류가 되었습니다.
리랭킹의 핵심 원리는 cross-attention입니다. 쿼리와 문서를 함께 모델에 입력하면, 모델이 둘 사이의 세밀한 의미 관계를 파악합니다. bi-encoder가 각각을 독립적으로 임베딩하는 것과 달리, cross-encoder는 "이 문서가 이 쿼리에 얼마나 관련있는가"를 직접 스코어링합니다. 보통 top-20~100개 후보에 적용됩니다.
2024-2025년 RAG 시스템에서 리랭킹은 필수 구성요소가 되었습니다. Cohere Rerank API, Jina Reranker, BGE Reranker 등 상용 서비스가 성장 중이며, LLM 응답 품질을 10-30% 향상시킵니다. 특히 복잡한 질문이나 긴 문서에서 효과가 큽니다. LangChain, LlamaIndex 모두 리랭킹을 기본 지원합니다.
| 리랭커 | 모델 크기 | NDCG@10 | 속도 | 비용 |
|---|---|---|---|---|
| Cohere Rerank v3 | 비공개 | ~0.72 | ~100ms/1000문서 | $1/1K 검색 |
| BGE-reranker-large | 560M | ~0.70 | ~50ms/100문서 | 오픈소스 |
| Jina Reranker v2 | 137M | ~0.68 | ~30ms/100문서 | 무료티어 있음 |
| cross-encoder/ms-marco | 110M | ~0.65 | ~40ms/100문서 | 오픈소스 |
* 2025년 1월 기준, MS MARCO 벤치마크 참조
# RAG 파이프라인에서 리랭킹 적용
from sentence_transformers import CrossEncoder
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# 1단계: 벡터 검색으로 후보 추출
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(embedding_function=embeddings)
query = "LLM의 할루시네이션을 줄이는 방법"
initial_docs = vectorstore.similarity_search(query, k=20)
# 2단계: Cross-Encoder로 리랭킹
reranker = CrossEncoder('BAAI/bge-reranker-large')
# 쿼리-문서 쌍 생성
pairs = [[query, doc.page_content] for doc in initial_docs]
# 관련성 점수 계산
scores = reranker.predict(pairs)
# 점수로 재정렬
reranked = sorted(
zip(initial_docs, scores),
key=lambda x: x[1],
reverse=True
)
# 상위 5개 선택
top_docs = [doc for doc, score in reranked[:5]]
print("🔝 리랭킹 후 상위 문서:")
for i, (doc, score) in enumerate(reranked[:5]):
print(f"{i+1}. [점수: {score:.4f}] {doc.page_content[:80]}...")
# Cohere API 사용 예시
import cohere
co = cohere.Client("your-api-key")
results = co.rerank(
query=query,
documents=[doc.page_content for doc in initial_docs],
top_n=5,
model="rerank-v3.0"
)
for r in results.results:
print(f"순위 {r.index}: 점수 {r.relevance_score:.4f}")
"RAG 응답 품질이 낮은 건 검색 문제입니다. 벡터 검색 후 Cohere Rerank 적용하면 관련 문서 Hit Rate가 65%에서 85%로 올라갑니다. 월 비용은 1000달러 정도 예상되고요."
"리랭킹은 2-stage retrieval의 핵심입니다. Bi-encoder로 top-100 후보를 빠르게 추출하고, cross-encoder로 쿼리-문서 상호작용을 정밀 분석합니다. 속도는 약간 느려지지만 정확도가 크게 향상되어 LLM 컨텍스트 품질이 좋아집니다."
"BGE-reranker-large가 오픈소스 중에서는 최고인데, 프로덕션에서는 Cohere v3가 더 안정적이에요. 특히 다국어 쿼리에서 성능 차이가 큽니다. 비용 대비 효과를 따지면 상용 API가 낫습니다."
리랭킹은 있는 문서 중에서 재정렬합니다. 1단계에서 관련 문서가 없으면 리랭킹도 무의미합니다. 최소 k=20~50으로 시작하세요.
Cross-encoder는 O(n) 비용입니다. 1000개 문서 리랭킹은 수 초가 걸릴 수 있습니다. 100-200개가 적정선입니다.
1단계에서 k=50~100으로 충분히 추출하고, 리랭킹 후 top-5~10을 LLM에 전달하세요. 도메인 특화 리랭커 파인튜닝도 고려하세요.