上級 12 分最適化

rerankerを自身のシステムに追加する pipeline

端的な回答

reranker とは、質問と本文のペアを再検証し、ベクトル検索で得られた候補を再順位付けするクロスエンコーダーです。広範な範囲(20 から 100 本文)を取得し、モデルに渡すのは 3 から 5 の最良候補です。フランス語では、BAAI/bge-reranker-v2-m3(Apache 2.0 ライセンス、約 5.68 億パラメータ)が、ローカル環境や GPU、あるいはパラメータ量が小さい場合でも CPU 上で利用可能な最も簡単な起点となります。

エンベディングは質問に近いパッセージを見つけますが、必ずしも質問に答えるパッセージを見つけるわけではありません。リランカーは、各質問とパッセージのペアを単一の計算で評価することで、この欠点を補正します。このガイドでは、コストに見合う場合、フランス語でどのモデルを選ぶべきか、30行でどのように統合するか、そして独自のドキュメントで結果が本当に改善されることをどのように確認するかを説明します。

著者 Mohamed Meguedmi·更新 2026-09-30·Windows・macOS・Linuxでテスト済み

#Reranker:RAGパイプラインにおける役割

リランカーは質問と一つの文章を受け取り、両方を併せて読んで関連性スコアを返します。その後、候補をスコアの高い順に並べ、上位のものだけを言語モデルに渡します。ローカルのRAGパイプラインでは、ベクトルデータベース(ChromaDB、Qdrant、Weaviate)とLLMの間にリランカーを挿入します。たとえば、ベクトル検索で30件の文章を取得し、リランカーがそのうち5件を選びます。BAAIの公式説明では、エンベディングモデルとは異なり、リランカーは質問と文書を入力として受け取り、ベクトルではなく類似度を直接出力するとされています。効果が最もはっきり表れるのは、正解が候補の中にあるものの、上位に来ていない場合です。大まかな話題は合っていても具体的な質問には答えていない文章が上位を占めると、モデルは的外れな回答や、事実に基づかない回答を生成してしまいます。正解が候補に含まれていなければ、リランカーには何もできません。検索するのではなく、並べ替えるだけだからです。

埋め込みは、質問の内容とは独立に各文書のベクトルを生成し、ベクトル間の距離で話題の全体的な近さを測ります。そのため、同じテーマの 2 つの文章は、片方にしか答えが含まれていなくても、近いスコアになることがあります。クロスエンコーダーはペア全体を見て、求められている日付、名前、条件が文章中に含まれているかを確認します。この個別の判定ではより正確ですが、コストも高くなります。文書ごとに 1 回計算するだけではなく、ペアごとに Transformer を 1 回通す必要があるためです。

i
比喩
埋め込みは、あなたを適切な棚に導き、20冊の本を差し出す図書館員です。リランカーは、あなたの質問を頭に浮かべながら、その20冊の本をめくり、答えとなる3冊を上に置く専門家です。

#バイエンコーダーとクロスエンコーダー:なぜ両方を組み合わせるのか

ローカルRAGキット

あなたのドキュメント、あなたのAI:あなたのPDF、メモ、メールを扱う信頼性の高いローカルRAG。何もクラウドに送信しません。

  • 永久に利用できるオンラインスペース
  • PDF + ファイル
  • 生涯アップデート
バイエンコーダー(エンベディング)
質問と各文書を別々にエンコードします。文書のベクトルはインデックス作成時に一度だけ計算されるため、検索ではベクトルを比較するだけで済みます。高速で、数百万の文章断片を扱うのに適しています。
クロスエンコーダー(リランカー)
質問と文章の一節を一緒にエンコードし、スコアを出力します。計算結果は一切再利用できず、質問と候補の組み合わせごとに計算し直す必要があります。精度は高いものの、コーパス全体に適用することはできません。

Sentence Transformers のドキュメントには、次のような論理が述べられています。数千または数百万のペアを評価するのはかなり遅いため、リトリーバーを使用して候補セット(例えば約100件)を生成し、その後にクロスエンコーダーで再ランキングを行います。この2段階のスキームは、従来の検索エンジンと同じものです。また、主な調整項目についても説明されています。取得する候補の数は、リコール(広く取得するほど、正解が含まれる可能性が高まる)とレイテンシ(追加の各候補はクロスエンコーダーでの1回の処理コストを伴う)の両方を左右します。

#フランス語向けにはどのリランキングモデルを選ぶべきか

選択は3つの基準で決まります:言語、ライセンス、メモリ。以下のサイズの数値はHugging Faceのデータシートから来ています。ファイルサイズは重みの精度に依存することに注意してください。bge-reranker-v2-m3はF32(パラメータあたり約4バイト)、mxbaiはF16です。

ローカルで利用できるリランカー(Hugging Faceのモデルカード、2026年9月)
モデル言語公表されたサイズライセンスフランス語での性能評価
BAAI/bge-reranker-v2-m3多言語6 億パラメータ、F32 の重み(約 2.3 GB)Apache 2.0標準の選択肢:多言語対応、軽量、関連ツールが充実
BAAI/bge-reranker-v2-gemma多言語30億のパラメータ、F32の重み(約10GB)Apache 2.0専用GPUを備えた、要求水準の高い用途に限定。Gemma-2Bベースのリランカー。
mixedbread-ai/mxbai-rerank-large-v1英語4億パラメータ、F16重みApache 2.0フランス語のコーパスには使用を避けるべき:モデルカードには英語と記載
Cohere Rerank多言語ホスティングされたサービス商用100%ローカルのパイプラインには不向き:テキストの該当箇所がマシンの外部に送信される

bge-reranker-v2-m3 のモデルカードでは、軽量なリランカーとして、強力な多言語対応能力、デプロイの容易さ、高速な推論を特徴として紹介しています。一方、bge-reranker-v2-gemma のモデルカードは、多言語コンテキスト向けであり、英語および多言語環境で良好な結果を示すとされています。よく見られる誤解に対する二つの重要な補正があります。まず、bge-reranker-v2-m3 のファイルサイズは 560 MB ではなく 2 GB 以上です(F32 形式で 568M パラメータ)。次に、mxbai-rerank-large-v1 は英語専用モデルであり、フランス語のドキュメントには推奨されません。半精度で読み込まれた場合、m3 モデルの重みは約 1.1 GB を占めます(568M パラメータ × 2 バイト、本ガイドの計算による)。これに、処理されるバッチのアクティベーションが追加されます。

→
埋め込みモデルとリランクモデルは独立しています
一方を変更しても、もう一方のインデックスを作り直す必要はありません。リランカーが読むのは各パッセージのテキストだけで、ベクトルを読むことはありません。埋め込みモデルを選ぶ際は、フランス語向け埋め込みモデルの専用ガイドを参照してください。

#reranker前後のパイプライン

ビフォー/アフター
AVANT :
  Question → Embedding → Base vectorielle (top-5) → LLM

APRÈS :
  Question → Embedding → Base vectorielle (top-20 à top-50)
                       → Reranker (top-5) → LLM

On récupère large, puis on ordonne finement.

2つのパラメータが全体を支配します。k_retrieve はベクトルデータベースが返す候補の数、k_final はLLMに渡されるパッセージの数です。k_final は3から5が、70億から140億パラメータのほとんどのローカルモデルに適しています。それを超えると、文脈ウィンドウが埋まるだけで実質的な利得はなく、プロンプトの処理時間も増加します。k_retrieve はコーパスの難易度に依存します。まず20を試すのがよく、質問が曖昧な場合や、コーパスに類似パッセージが多い場合は50から100が適しています。文脈ウィンドウに関するガイドでは、プロンプト内の追加パッセージのコストについて詳しく説明しています。

#実装:sentence-transformers、FlagEmbedding、llama.cpp

#sentence-transformersを使用する場合

CrossEncoderクラスはモデルを読み込み、ペアを評価します。rankメソッドは質問とドキュメントのリストを直接受け取り、最も関連性の高いドキュメントを返します。top_kパラメータで結果の件数を制限できます(指定しない場合は、すべてのドキュメントが返されます)。

CrossEncoder.rank
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)

def retrieve_and_rerank(question, k_retrieve=20, k_final=5):
    # 1. Récupération par embedding (ChromaDB, Qdrant, etc.)
    candidats = embedding_search(question, top_k=k_retrieve)  # liste de textes

    # 2. Scoring par le cross-encoder, tri et coupe en une seule étape
    resultats = reranker.rank(question, candidats, top_k=k_final, batch_size=16)
    # resultats = [{'corpus_id': 3, 'score': 0.91}, ...]
    return [candidats[r['corpus_id']] for r in resultats]

#モデルの開発者によるライブラリ、FlagEmbeddingを使う

モデルの説明ページでは、FlagEmbedding ライブラリを使っています。そこでは、normalize=True を指定するとシグモイド関数で生のスコアを0~1の範囲に変換できること、また use_fp16=True を指定すると、品質がわずかに下がる代わりに計算が速くなることが説明されています。生のスコアには絶対的な尺度がなく、内容が無関係な文章では負の値になることが多い点を覚えておいてください。しきい値を設定する場合を除けば、重要なのは順位だけです。

FlagReranker
from FlagEmbedding import FlagReranker

reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True)
score = reranker.compute_score(['ma question', 'un passage'], normalize=True)  # entre 0 et 1

#llama.cpp を使用し、Python なしで

llama.cppサーバーは、デフォルトで無効化されているリランキング用のエンドポイントを提供しています。ドキュメントには、リランキングモデルが必要であり、例としてbge-reranker-v2-m3が挙げられており、--embeddingおよび--pooling rankオプションで起動すると記載されています。モデルのGGUFバージョンが必要です。llama.cppを基盤としたスタックが既に構築されており、PyTorchのインストールを避けたい場合に検討すべきオプションです。インストール済みバージョンで正確なオプションを確認してください。ドキュメントでは、このエンドポイントが変更される可能性があるとの注意喚起が行われています。

llama-server(ご自身のバージョンに合わせて調整してください)
llama-server -m bge-reranker-v2-m3-Q8_0.gguf --embedding --pooling rank --reranking --port 8081

#LlamaIndex と併用

SentenceTransformerRerank
from llama_index.core.postprocessor import SentenceTransformerRerank

reranker = SentenceTransformerRerank(model="BAAI/bge-reranker-v2-m3", top_n=5)

query_engine = index.as_query_engine(
    similarity_top_k=20,
    node_postprocessors=[reranker],
)

#コスト:遅延、メモリ、文章の該当箇所の長さ

レイテンシの保証値はありません。カード、精度(FP16またはFP32)、候補数、パッセージの長さに依存します。比率を把握してください。リランキングの時間はペア数に比例して増加します。候補を20から100に増やすと、処理量は5倍になります。各ペアが全体としてエンコードされるため、パッセージの長さによっても増加します。ブログの数字に頼るのではなく、ご自身のマシンで実際のパッセージを使って測定してください。100件の実際のリクエストを計時し、中央値と最悪ケースを確認してください。

候補数
最初に調整する項目です。候補数20から始めて再現率を測定し、適切な回答が候補に含まれていない場合に限って50に増やしてください。
精度
use_fp16=True(FlagEmbedding)を指定するか、半精度で読み込むと、メモリ使用量が減り、計算が高速化します。ただし、モデルの説明によると、性能はわずかに低下します。
バッチサイズ
sentence-transformersのrankメソッドはデフォルトで32ペアをバッチ単位で処理します。メモリが不足する場合は8または16に設定し、GPUが活用されていない場合はそれ以上に上げてください
最大長
512トークンペアあたり(公式例のmax_length値)。長さがこれ以上になる場合は、文の末尾が読み込まれず、切り捨てられます。このサイズを超えるチャンクは、上限を上げる前に短くしてから処理してください。
CPUまたはGPU
CPUでもリランカーは動作しますが、20〜50件の候補を処理するリクエストごとに秒単位の時間がかかります。社内の文書アシスタントでは許容できますが、対話型チャットでは許容しにくくなります。
→
不要な場合はリランカーをスキップする
小規模で整理されたコーパス(適切に分割された数十ページ程度)では、ベクトル検索の上位5件にすでに答えが含まれていることがよくあります。まず測定し、再現率が向上する場合にのみリランカーを使い続けてください。

#リランカーと分割:2つの設定は互いに影響する

クロスエンコーダーは文章の一区切りを全体として評価します。そこに3つの話題が混在していると、それぞれに対応する3つの質問に対して、いずれも中程度のスコアになります。逆に短すぎると、回答だと判断するために必要な文脈が失われます。適度な長さに分割し、区切りの前後を少し重複させれば、リランカーの最大入力長を超えずに、評価に十分な情報を与えられます。チャンクサイズを変更したら、再現率のテストをやり直してください。最適なk_retrieveとリランカーによる改善幅も、チャンクサイズに応じて変わります。チャンキング戦略のガイドでは、こうした選択について詳しく説明しています。

もう一つの組み合わせが、ハイブリッド検索です。キーワード検索(BM25)とベクトル検索を組み合わせると、候補がより多様になり、それぞれの手法を単独で使った場合には見逃していた適切な回答を、リランカーが見つけられる可能性が高まります。リランカーは最終段階、ハイブリッド検索は第2段階を担います。両者は互いに置き換わるものではなく、補完し合うものです。

#手元の文書で改善効果を測定する

ブログで報告されている効果はコーパスによって1倍から5倍まで幅があり、一般的な数値があなたの環境にも当てはまるとは限りません。非常に構造化されたコーパス(整った技術文書)ではベクトル検索だけでも十分ですが、ノイズの多いコーパス(メール、メモ、抽出状態の悪いPDF)では差がより顕著です。確認する唯一の方法は評価です。

  1. 01
    30〜50件の質問を用意する
    実際のユーザーの質問を用意し、それぞれに回答を含む文章の箇所を添えてください(識別子だけで十分です)。
  2. 02
    5の再ランク付けなしで再検索率を測定する
    各質問について、ベクトルデータベースの検索結果の上位5件に、適切な文章箇所が含まれているか確認してください。
  3. 03
    リランカー使用時のRecall@5を測定する
    候補を20件取得し、順位を付け直して、上位5件に含まれる適切な文章の数をもう一度数えてください。
  4. 04
    レイテンシも比較する
    エンドツーエンドの中央値時間を記録してください。リコールが数ポイント向上しても、追加の1秒の待機時間を正当化できるわけではありません。
  5. 05
    失敗の確認
    正しく答えられなかった質問ごとに、20件の候補に正しい答えが含まれていたかを確認してください。含まれていなければ、問題は前段階の分割、埋め込み、またはテキスト抽出にあります。
再現率の評価
def rappel_a_k(pipeline, questions, cibles, k=5):
    ok = 0
    for q, cible in zip(questions, cibles):
        ok += cible in [p.id for p in pipeline(q)[:k]]
    return ok / len(questions)

sans = rappel_a_k(pipeline_sans_reranker, questions, cibles)
avec = rappel_a_k(pipeline_avec_reranker, questions, cibles)
print(f"Sans : {sans:.0%}   Avec : {avec:.0%}")
!
rerankerの限界
PDFからうまく抽出できなかったテキストも、答えを途中で二つに分けてしまうチャンク分割も、曖昧な質問も修正できません。また、正しい数値を含んでいてもスコアが低い短い文章を低く評価してしまうことがあります。平均値に頼らず、失敗例を確認してください。

#リランカーが必要ですか?意思決定の基準

reranker を追加するタイミング
状況決定
整備された文書が数十件程度のコーパスで、ベクトル検索の上位5件がすでに良好いいえ、まず測定してください
適切な回答が6〜30位にあることが多いはい:これは典型的な使用例です
曖昧な質問、ノイズが多いコーパス、または内容が非常に多様なコーパスはい。候補数は30〜50件
GPUなしのマシンでのインタラクティブチャット注意:CPUでの処理遅延を測定し、候補を10〜20件に絞ってください。
上位50件の候補にも正しい答えが含まれていないいいえ:まずチャンク分割、埋め込み、または抽出を修正してください

#rerankingに関するよくある質問

FAQ
rerankerはベクトル検索を置き換えることができますか?+
いいえ。リランカーはコーパスを走査するのではなく、ベクトル検索から渡された数十件の候補を並べ替えます。高速な第1段階がなければ、データベース内のすべての文章区間に対してリランカーを実行する必要があり、遅すぎてしまいます。2つの段階は互いに補完し合います。ベクトル検索が再現率を保証し、リランカーがランキング上位の適合率を高めます。
フランス語のドキュメントに対してどのリランカーを選択すべきですか?+
BAAI/bge-reranker-v2-m3は、まず試すモデルとして妥当です。多言語に対応し、Apache 2.0ライセンスで、パラメータ数は約6億なので、比較的性能の低いグラフィックカードでも利用できます。mxbai-rerank-large-v1は避けてください。モデルの説明には対応言語として英語が記載されています。より重いbge-reranker-v2-gemmaを使うのが妥当なのは、ご自身の質問セットで最初のモデルでは不十分な場合だけです。
再ランク付けする候補数はいくつですか?+
まず候補を20件にし、その中から5つの文章を残してください。評価時に、正しい回答が20件の候補に含まれていない場合は、候補を50件に増やしてください。候補が1件増えるごとに計算が追加されるため、遅延はほぼ線形に増加します。100件を超えると、改善が得られることはまれになります。これは、チャンク分割や埋め込みに問題がある兆候であることが多いです。
rerankerにはGPUが必要ですか?+
いいえ、必須ではありませんが役立ちます。CPUでもm3モデルは動作します。候補の1バッチの処理には、マシンによって1秒程度か、それ以上かかるため、ご自身の環境で測定してください。社内の文書検索用途なら許容できる範囲です。快適なチャットには、比較的性能の低いGPUでも、あるいはより軽量なモデルでも、使用感が変わります。
Ollama と reranker を併用することは可能ですか?+
Ollamaは生成モデルと埋め込みを提供しますが、リランキングは別に行います。Pythonでsentence-transformersやFlagEmbeddingを使うか、リランキング用のエンドポイントを公開するllama.cppサーバーを使います。リランカーは生成モデルとは別のモデルで、専用のプロセスに読み込まれ、メモリ容量が許せば生成モデルと共存します。
リランカーによって結果が本当に改善しているか、どう確認できますか?+
実際の質問を30〜50件、取得されるべき文章とセットで用意してください。そのうえで、rerankerの有無による上位5件の検索結果の再現率(recall)とレイテンシの中央値を比較してください。ノイズの少ないコーパスでは差が小さい場合がありますが、ノイズの多いコーパスでは差がより明確になります。その後、失敗事例を分析し、原因が上流の処理にあるかどうかを確認してください。
このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。