Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Reranking

検索を2段階に分ける手法。

  1. Retrieval(候補生成):高速だが粗い方法(BM25、ベクトル検索、hybrid search)で候補を広めに取る(top-50〜100など)

  2. Reranking(並べ替え):遅いが精度の高いモデルで候補だけを採点し直し、上位だけをLLMに渡す

全文書を精密なモデルで採点するのは遅すぎるので、候補を絞ってから精密に採点するという分担。導入が簡単で効果が大きく、RAGの精度改善の中でも費用対効果が高い。

なぜ必要か

ので、本当に関連する少数のchunkを上位に持ってくることが重要になる。

Bi-encoderとCross-encoder

Bi-encoder(検索用)

クエリと文書を 別々に エンコードしてベクトルにし、内積やコサイン類似度で比較する。

s(q,d)=sim(E(q),E(d))s(q, d) = \text{sim}(E(q), E(d))

文書のベクトルは事前に計算しておけるので高速。ただしクエリと文書の単語同士の相互作用を見られないので精度に限界がある。

Cross-encoder(reranking用)

クエリと文書を 連結して 1つのTransformerに入力し、関連度スコアを直接出力する。

s(q,d)=f([CLS] q [SEP] d)s(q, d) = f([\text{CLS}]\ q\ [\text{SEP}]\ d)

attentionでクエリと文書の全トークンが相互作用するので精度が高い。ただし文書ごとに毎回モデルを通す必要があり、事前計算できないので候補の再採点にしか使えない。

BERTをこの形でpassage rerankingに使ったのが monoBERT(Nogueira & Cho (2019). Passage Re-ranking with BERT)。

Late interaction(ColBERT)

Khattab & Zaharia (2020). ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT

bi-encoderとcross-encoderの中間。クエリと文書を別々にエンコードするが、1本のベクトルにまとめず トークンごとのベクトル を保持し、次のMaxSimでスコアを計算する。

s(q,d)=∑i∈qmax⁡j∈dqi⊤djs(q, d) = \sum_{i \in q} \max_{j \in d} \mathbf{q}_i^\top \mathbf{d}_j

クエリの各トークンについて、最も似ている文書トークンとの類似度をとって合計する。文書側のベクトルは事前計算できるので速く、トークンレベルの相互作用も見られるので精度も高い。代わりにインデックスのサイズが大きくなる。

画像のまま文書ページを検索するColPaliもこの仕組みを使っている。

LLMによるreranking

LLM自体にrerankingさせる方法もある。

精度は高いが遅くて高価。専用のcross-encoderで十分なことも多い。

代表的なモデル・サービス

  • 商用API:Cohere Rerank、Voyage AI rerankerなど

  • オープンモデル:BAAI/bge-reranker 系(多言語)、日本語特化の hotchpotch/japanese-reranker 系など

実装上のポイント

  • 候補数(retrieval段のk)を増やすとrecallは上がるが、rerankingのレイテンシが線形に増える

  • rerankerのスコアに閾値を設けて、関連の低いchunkはLLMに渡さないという使い方もできる

  • rerankerは入力長の上限が短い(512トークン程度)ものも多いので、chunk のサイズと合わせて選ぶ