Reciprocal Rank Fusion (RRF)
Reciprocal Rank Fusion(RRF)은 복수의 retriever가 반환한 결과를 병합할 때, 절대 점수 대신 각 retriever에서의 순위(rank)를 기반으로 통합 점수를 계산하는 방식이다. 점수 스케일 차이를 완전히 무시하기 때문에 Score Fusion의 정규화 문제를 원천적으로 해결하며, 실용적이면서도 강건한(robust) 성능으로 널리 채택된다.
핵심 공식
RRF 점수는 각 retriever에서의 순위에 역수를 취해 합산한다.
$$\text{RRF}(d) = \sum_{r \in R} \frac{1}{k + \text{rank}_r(d)}$$
- $R$: retriever 집합
- $\text{rank}_r(d)$: retriever $r$에서 문서 $d$의 순위 (1-indexed)
- $k$: 순위 영향력을 조절하는 상수 (일반적으로 60)
k=60은 경험적으로 검증된 기본값이다. 상위 랭크의 영향력을 완화해 단일 retriever에서 1위인 문서가 다른 retriever에서 전혀 등장하지 않더라도 지나치게 유리해지지 않도록 한다.
구현
def reciprocal_rank_fusion(
results: list[list[Document]],
k: int = 60
) -> list[Document]:
rrf_scores: dict[str, float] = {}
doc_map: dict[str, Document] = {}
for result_list in results:
for rank, doc in enumerate(result_list, start=1):
rrf_scores[doc.id] = rrf_scores.get(doc.id, 0) + 1 / (k + rank)
doc_map[doc.id] = doc
ranked_ids = sorted(rrf_scores, key=rrf_scores.get, reverse=True)
return [doc_map[id] for id in ranked_ids]Score Fusion과의 비교
| 항목 | Score Fusion | RRF |
|---|---|---|
| 입력 | 정규화된 점수 | 순위 |
| 스케일 문제 | 정규화 필요 | 없음 |
| 이상값 민감도 | 높음 | 낮음 |
| 직관성 | 높음 | 중간 |
| 튜닝 파라미터 | 가중치 + 정규화 방법 | k값 하나 |
| 실전 성능 | 케이스에 따라 다름 | 대체로 안정적 |
RRF의 강점은 단순성과 강건성이다. 정규화 방법이나 retriever별 가중치를 튜닝하지 않아도 안정적인 성능을 낸다.
k 값의 효과
k 값이 클수록 순위의 영향력이 평탄해진다. k=0이면 1위 문서가 압도적으로 유리하고, k가 커질수록 10위와 1위의 점수 차이가 줄어든다.
k=0: rank 1 → 1.0, rank 10 → 0.10 (10배 차이)
k=60: rank 1 → 0.016, rank 10 → 0.014 (1.14배 차이)
k=60에서는 상위 랭크 간 점수 차이가 크지 않으므로, 여러 retriever에서 중간 순위에 반복 등장하는 문서가 한 retriever에서만 1위인 문서를 앞설 수 있다. 이 특성이 앙상블 효과를 만든다.
가중치 부여 (Weighted RRF)
retriever별로 중요도 차이를 두고 싶을 때 가중 RRF를 사용한다.
def weighted_rrf(
results: list[list[Document]],
weights: list[float],
k: int = 60
) -> list[Document]:
rrf_scores: dict[str, float] = {}
doc_map: dict[str, Document] = {}
for result_list, weight in zip(results, weights):
for rank, doc in enumerate(result_list, start=1):
rrf_scores[doc.id] = rrf_scores.get(doc.id, 0) + weight / (k + rank)
doc_map[doc.id] = doc
ranked_ids = sorted(rrf_scores, key=rrf_scores.get, reverse=True)
return [doc_map[id] for id in ranked_ids]실전 활용
RRF는 Hybrid Retrieval(BM25 + Dense)의 결과 병합에서 사실상 표준으로 사용된다. Elasticsearch, Weaviate, Qdrant 등 주요 벡터 DB가 Hybrid Search 기능에 RRF를 내장하고 있다.
관련 개념
- Score Fusion: 정규화된 절대 점수를 가중합산하는 병합 방식
- Naive Merge: 순위·점수 없이 단순 concatenation하는 방식
- Reranker-centric: RRF 등으로 1차 병합 후 reranker로 최종 정렬하는 방식