検索を2段階に分ける手法。
Retrieval(候補生成):高速だが粗い方法(BM25、ベクトル検索、hybrid search)で候補を広めに取る(top-50〜100など)
Reranking(並べ替え):遅いが精度の高いモデルで候補だけを採点し直し、上位だけをLLMに渡す
全文書を精密なモデルで採点するのは遅すぎるので、候補を絞ってから精密に採点するという分担。導入が簡単で効果が大きく、RAGの精度改善の中でも費用対効果が高い。
なぜ必要か¶
LLMに渡せるchunk数には限りがある(コンテキスト長・コスト・レイテンシ)
LLMは長いコンテキストの中間にある情報を見落としやすい(Liu et al. (2023). Lost in the Middle: How Language Models Use Long Contexts)
ので、本当に関連する少数のchunkを上位に持ってくることが重要になる。
Bi-encoderとCross-encoder¶
Bi-encoder(検索用)¶
クエリと文書を 別々に エンコードしてベクトルにし、内積やコサイン類似度で比較する。
文書のベクトルは事前に計算しておけるので高速。ただしクエリと文書の単語同士の相互作用を見られないので精度に限界がある。
Cross-encoder(reranking用)¶
クエリと文書を 連結して 1つのTransformerに入力し、関連度スコアを直接出力する。
attentionでクエリと文書の全トークンが相互作用するので精度が高い。ただし文書ごとに毎回モデルを通す必要があり、事前計算できないので候補の再採点にしか使えない。
BERTをこの形でpassage rerankingに使ったのが monoBERT(Nogueira & Cho (2019). Passage Re-ranking with BERT)。
Late interaction(ColBERT)¶
bi-encoderとcross-encoderの中間。クエリと文書を別々にエンコードするが、1本のベクトルにまとめず トークンごとのベクトル を保持し、次のMaxSimでスコアを計算する。
クエリの各トークンについて、最も似ている文書トークンとの類似度をとって合計する。文書側のベクトルは事前計算できるので速く、トークンレベルの相互作用も見られるので精度も高い。代わりにインデックスのサイズが大きくなる。
画像のまま文書ページを検索するColPaliもこの仕組みを使っている。
LLMによるreranking¶
LLM自体にrerankingさせる方法もある。
Pointwise:各文書について「関連するか?」を個別に採点させる
Listwise:候補のリストを渡して関連度順に並べさせる。RankGPT(Sun et al. (2023). Is ChatGPT Good at Search? Investigating Large Language Models as Re-Ranking Agents)では、候補をsliding windowで少しずつ並べ替えることで長いリストにも対応している
精度は高いが遅くて高価。専用のcross-encoderで十分なことも多い。
代表的なモデル・サービス¶
商用API:Cohere Rerank、Voyage AI rerankerなど
オープンモデル:
BAAI/bge-reranker系(多言語)、日本語特化のhotchpotch/japanese-reranker系など