Avancé 12 minOptimisation

Ajouter un reranker à son pipeline

Réponse directe

Un reranker est un cross-encoder qui relit chaque couple question-passage et réordonne les candidats renvoyés par la recherche vectorielle : on récupère large (20 à 100 passages), on garde les 3 à 5 meilleurs pour le modèle. En français, BAAI/bge-reranker-v2-m3 (licence Apache 2.0, environ 568 millions de paramètres) est le point de départ le plus simple, en local, sur GPU ou même sur CPU si le volume reste modeste.

Les embeddings retrouvent des passages proches d'une question, pas forcément des passages qui y répondent. Le reranker corrige ce défaut en jugeant chaque couple question-passage dans un seul calcul. Ce guide explique quand il vaut son coût, quel modèle choisir en français, comment le brancher en trente lignes, et comment vérifier sur vos propres documents qu'il améliore vraiment les résultats.

Par Mohamed Meguedmi·Màj 2026-09-30·Testé sur Windows, macOS, Linux

#Reranker : à quoi il sert dans un pipeline RAG

Un reranker prend la question et un passage, les lit ensemble et renvoie un score de pertinence ; on trie ensuite les candidats par score décroissant et on ne transmet au modèle de langage que les meilleurs. Dans un pipeline RAG local, on l'insère entre la base vectorielle (ChromaDB, Qdrant, Weaviate) et le LLM : la recherche vectorielle rapatrie par exemple 30 passages, le reranker en retient 5. La fiche officielle de BAAI le décrit ainsi : contrairement à un modèle d'embedding, le reranker reçoit la question et le document en entrée et produit directement une similarité, au lieu d'un vecteur. Le gain est le plus net quand la bonne réponse se trouve dans les candidats mais pas en tête : des passages qui parlent du bon sujet général sans répondre à la question précise occupent les premières places, et le modèle génère alors une réponse à côté ou inventée. Si la bonne réponse n'est pas dans les candidats, un reranker ne peut rien : il ne cherche pas, il trie.

Un embedding produit un vecteur pour chaque document, indépendamment de la question posée, et la distance mesure une proximité globale de sujet. Deux passages sur le même thème peuvent donc obtenir des scores voisins alors qu'un seul contient la réponse. Le cross-encoder regarde le couple en entier : il voit si la date, le nom ou la condition demandés figurent dans le passage. C'est plus précis sur ce jugement local, et plus coûteux, parce qu'il faut un passage dans le transformer par couple au lieu d'un seul calcul par document.

i
La métaphore
L'embedding est le bibliothécaire qui vous conduit au bon rayon et vous tend vingt livres. Le reranker est l'expert qui feuillette ces vingt livres avec votre question en tête et pose sur le dessus les trois qui répondent.

#Bi-encoder et cross-encoder : pourquoi on combine les deux

Le kit RAG Local

Tes documents, ton IA : un RAG local fiable sur tes PDF, notes et mails — sans rien envoyer dans le cloud.

  • Espace en ligne à vie
  • PDF + fichiers
  • Mises à jour à vie
Bi-encoder (embedding)
Encode la question et chaque document séparément ; les vecteurs des documents sont calculés une fois à l'indexation, la recherche se réduit à une comparaison de vecteurs. Rapide, adapté à des millions de passages.
Cross-encoder (reranker)
Encode la question et le passage ensemble et sort un score. Aucun calcul n'est réutilisable : il faut le refaire pour chaque question et chaque candidat. Précis, mais impossible à appliquer à tout le corpus.

La documentation de Sentence Transformers énonce le raisonnement : évaluer des milliers ou des millions de couples serait plutôt lent, on utilise donc le retriever pour produire un ensemble de candidats, par exemple une centaine, que le cross-encoder réordonne. Le schéma en deux étages est le même que celui des moteurs de recherche classiques. Il explique aussi le réglage principal : le nombre de candidats récupérés pilote à la fois le rappel (plus on prend large, plus on a de chances de contenir la bonne réponse) et la latence (chaque candidat supplémentaire coûte un passage dans le cross-encoder).

#Quel modèle de reranking choisir en français

Le choix se joue sur trois critères : la langue, la licence et la mémoire. Les chiffres de taille ci-dessous viennent des fiches Hugging Face ; notez que la taille du fichier dépend de la précision des poids, F32 pour bge-reranker-v2-m3 (environ 4 octets par paramètre), F16 pour mxbai.

Rerankers utilisables en local (fiches Hugging Face, septembre 2026)
ModèleLanguesTaille annoncéeLicenceVerdict pour le français
BAAI/bge-reranker-v2-m3Multilingue0,6 milliard de paramètres, poids en F32 (environ 2,3 Go)Apache 2.0Choix par défaut : multilingue, léger, bien outillé
BAAI/bge-reranker-v2-gemmaMultilingue3 milliards de paramètres, poids en F32 (environ 10 Go)Apache 2.0À réserver aux cas exigeants avec GPU dédié ; reranker à base de Gemma-2B
mixedbread-ai/mxbai-rerank-large-v1Anglais0,4 milliard de paramètres, poids en F16Apache 2.0À éviter pour un corpus français : la fiche indique l'anglais
Cohere RerankMultilingueService hébergéCommercialHors sujet pour un pipeline 100 % local : les passages quittent votre machine

La fiche de bge-reranker-v2-m3 le présente comme un reranker léger, doté de fortes capacités multilingues, facile à déployer et rapide en inférence ; la fiche de bge-reranker-v2-gemma le destine aux contextes multilingues, avec de bons résultats en anglais comme en multilingue. Deux corrections utiles par rapport à ce qu'on lit souvent : le fichier de bge-reranker-v2-m3 pèse plus de 2 Go, pas 560 Mo (568 millions de paramètres en F32), et mxbai-rerank-large-v1 est un modèle anglophone, à ne pas retenir pour des documents en français. Une fois chargé en demi-précision, le modèle m3 occupe environ 1,1 Go pour les poids (568 millions de paramètres × 2 octets, calcul de ce guide), auxquels s'ajoutent les activations du lot traité.

→
Modèle d'embedding et reranker sont indépendants
Vous pouvez changer l'un sans réindexer l'autre : le reranker ne lit que le texte des passages, jamais leurs vecteurs. Pour choisir le modèle d'embeddings, voir le guide dédié aux modèles d'embeddings français.

#La pipeline avant et après reranker

Avant / après
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.

Deux paramètres gouvernent l'ensemble : k_retrieve, le nombre de candidats que la base vectorielle renvoie, et k_final, le nombre de passages transmis au LLM. Un k_final de 3 à 5 convient à la plupart des modèles locaux de 7 à 14 milliards de paramètres ; au-delà, on remplit la fenêtre de contexte sans gain net, et le temps de traitement du prompt augmente. Le k_retrieve dépend de la difficulté du corpus : 20 est un bon premier essai, 50 à 100 si les questions sont vagues ou si le corpus contient beaucoup de passages voisins. Le guide sur la fenêtre de contexte détaille ce que coûtent des passages supplémentaires dans le prompt.

#Implémentation : sentence-transformers, FlagEmbedding, llama.cpp

#Avec sentence-transformers

La classe CrossEncoder charge le modèle et évalue des couples. Sa méthode rank accepte directement la question et la liste des documents et renvoie les meilleurs ; le paramètre top_k limite le nombre de résultats (sans lui, tous les documents sont renvoyés).

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]

#Avec FlagEmbedding, la bibliothèque des auteurs du modèle

La fiche du modèle utilise la bibliothèque FlagEmbedding. Elle précise que le score brut peut être ramené entre 0 et 1 par une fonction sigmoïde avec normalize=True, et que use_fp16=True accélère le calcul au prix d'une légère baisse de qualité. Retenez que le score brut est une valeur sans échelle absolue, souvent négative pour les passages hors sujet ; seul l'ordre compte, sauf si vous fixez un seuil.

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

#Avec llama.cpp, sans Python

Le serveur llama.cpp propose un point d'accès de reranking, désactivé par défaut. La documentation indique qu'il exige un modèle de reranking, cite bge-reranker-v2-m3 en exemple, et se lance avec les options --embedding et --pooling rank. Il faut une version GGUF du modèle. C'est l'option à retenir si votre pile est déjà construite autour de llama.cpp et que vous voulez éviter d'installer PyTorch. Vérifiez l'option exacte dans la version installée : la documentation prévient que ce point d'accès pourrait évoluer.

llama-server (à adapter à votre version)
llama-server -m bge-reranker-v2-m3-Q8_0.gguf --embedding --pooling rank --reranking --port 8081

#Avec 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],
)

#Coût : latence, mémoire, longueur des passages

Aucun chiffre de latence n'est garanti : elle dépend de la carte, de la précision (FP16 ou FP32), du nombre de candidats et de la longueur des passages. Retenez les proportions. Le temps de reranking croît linéairement avec le nombre de couples : passer de 20 à 100 candidats multiplie le travail par cinq. Il croît aussi avec la longueur du passage, puisque chaque couple est encodé en entier. Mesurez sur votre machine avec vos passages plutôt que de vous fier à un chiffre de blog : chronométrez cent requêtes réelles, et regardez le temps médian et le pire cas.

Nombre de candidats
Premier levier. Commencez à 20, mesurez le rappel, montez à 50 seulement si des bonnes réponses restent hors du lot.
Précision
use_fp16=True (FlagEmbedding) ou un chargement en demi-précision réduit la mémoire et accélère le calcul, avec, selon la fiche du modèle, une légère baisse de performance.
Taille de lot
La méthode rank de sentence-transformers traite 32 couples par lot par défaut. Baissez à 8 ou 16 si la mémoire manque, montez si le GPU est sous-utilisé.
Longueur maximale
512 tokens par couple (valeur max_length des exemples officiels). Un passage plus long est tronqué : si vos chunks dépassent cette taille, la fin du passage n'est pas lue. Raccourcissez les chunks avant d'augmenter la limite.
CPU ou GPU
Sur CPU, le reranker fonctionne, mais chaque requête de 20 à 50 candidats se paie en secondes ; c'est acceptable pour un assistant documentaire interne, moins pour un chat interactif.
→
Passer le reranker quand il est inutile
Sur un corpus petit et propre (quelques dizaines de pages bien découpées), le top-5 vectoriel contient souvent déjà la réponse. Mesurez d'abord, et ne gardez le reranker que si le rappel progresse.

#Reranker et découpage : les deux réglages interagissent

Un cross-encoder juge un passage entier. Si le passage mélange trois sujets, son score sera moyen pour les trois questions correspondantes ; s'il est trop court, il perd le contexte qui permettrait de le reconnaître comme réponse. Le découpage en passages de taille moyenne, avec un léger recouvrement, donne au reranker de la matière sans dépasser sa longueur maximale. Si vous changez la taille des chunks, refaites le test de rappel : le meilleur k_retrieve et le gain du reranker changent avec lui. Le guide sur les stratégies de chunking détaille ces choix.

Autre interaction : la recherche hybride. Lorsque la recherche par mots-clés (BM25) et la recherche vectorielle sont fusionnées, le lot de candidats est plus varié, ce qui laisse au reranker plus de chances de retrouver une bonne réponse que chaque méthode seule aurait ratée. Le reranker est le dernier étage, l'hybride le second : ils se complètent plutôt qu'ils ne se remplacent.

#Mesurer le gain sur vos documents

Le gain annoncé dans les blogs varie du simple au quintuple selon le corpus, et aucune valeur générale ne vaut pour le vôtre. Sur un corpus très structuré (documentation technique propre), le vectoriel seul est déjà bon ; sur un corpus bruité (courriels, notes, PDF mal extraits), l'écart est plus marqué. Le seul moyen de le savoir est d'évaluer.

  1. 01
    Constituer 30 à 50 questions
    Prenez de vraies questions d'utilisateurs, avec pour chacune le passage qui contient la réponse (un identifiant suffit).
  2. 02
    Mesurer le rappel à 5 sans reranker
    Pour chaque question, regardez si le bon passage figure dans les 5 premiers résultats de la base vectorielle.
  3. 03
    Mesurer le rappel à 5 avec reranker
    Récupérez 20 candidats, reclassez-les, et comptez de nouveau les bons passages dans les 5 premiers.
  4. 04
    Comparer aussi la latence
    Notez le temps médian de bout en bout. Un gain de quelques points de rappel ne justifie pas forcément une seconde d'attente supplémentaire.
  5. 05
    Regarder les échecs
    Pour chaque question ratée, vérifiez si la bonne réponse était dans les 20 candidats. Si non, le problème est en amont : découpage, embeddings ou extraction du texte.
Évaluer le rappel
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%}")
!
Limites du reranker
Il ne corrige ni un texte mal extrait d'un PDF, ni un découpage qui coupe la réponse en deux, ni une question ambiguë. Il peut aussi défavoriser des passages courts dont le score est bas alors qu'ils contiennent le bon chiffre : vérifiez les échecs au lieu de vous fier à la moyenne.

#Faut-il un reranker ? Repères de décision

Quand ajouter un reranker
SituationDécision
Corpus de quelques dizaines de documents propres, top-5 vectoriel déjà bonNon, mesurez d'abord
Bonne réponse fréquemment entre le 6e et le 30e rangOui : c'est le cas d'usage type
Questions vagues, corpus bruité ou très hétérogèneOui, avec 30 à 50 candidats
Chat interactif sur machine sans GPUPrudence : mesurez la latence sur CPU, réduisez à 10 à 20 candidats
Bonne réponse absente même des 50 premiers candidatsNon : corrigez d'abord le découpage, les embeddings ou l'extraction

#Questions fréquentes sur le reranking

FAQ
Un reranker remplace-t-il la recherche vectorielle ?+
Non. Il ne parcourt pas le corpus : il réordonne les quelques dizaines de candidats que la recherche vectorielle lui fournit. Sans premier étage rapide, il faudrait le faire tourner sur chaque passage de la base, ce qui serait beaucoup trop lent. Les deux étages se complètent : le vectoriel garantit le rappel, le reranker apporte la précision sur le haut du classement.
Quel reranker choisir pour des documents en français ?+
BAAI/bge-reranker-v2-m3 est le point de départ raisonnable : multilingue, sous licence Apache 2.0, d'environ 0,6 milliard de paramètres, donc utilisable sur une carte graphique modeste. Évitez mxbai-rerank-large-v1, dont la fiche indique l'anglais. Le modèle bge-reranker-v2-gemma, plus lourd, se justifie seulement si le premier ne suffit pas sur votre jeu de questions.
Combien de candidats faut-il reranker ?+
Commencez par 20 candidats et gardez 5 passages. Si, à l'évaluation, des bonnes réponses restent hors des 20, montez à 50. Chaque candidat supplémentaire ajoute un calcul, la latence croît donc à peu près linéairement. Au-delà de 100, le gain devient rare : c'est souvent le signe d'un problème de découpage ou d'embeddings.
Faut-il un GPU pour un reranker ?+
Non, mais il aide. Sur CPU, le modèle m3 fonctionne, avec un délai de l'ordre de la seconde ou plus pour un lot de candidats selon la machine : à mesurer chez vous. Cela reste acceptable pour un usage documentaire interne. Pour un chat fluide, un GPU même modeste, ou un modèle plus léger, change la sensation d'usage.
Peut-on utiliser un reranker avec Ollama ?+
Ollama sert le modèle de génération et les embeddings, mais le reranking se fait à part : avec sentence-transformers ou FlagEmbedding en Python, ou avec le serveur llama.cpp qui expose un point d'accès de reranking. Le reranker est un modèle distinct, chargé dans son propre processus, qui cohabite avec le modèle de génération si la mémoire le permet.
Comment savoir si le reranker améliore vraiment mes résultats ?+
Constituez 30 à 50 vraies questions avec le passage attendu, puis comparez le rappel dans les 5 premiers résultats avec et sans reranker, ainsi que la latence médiane. Sur un corpus propre, l'écart peut être faible ; sur un corpus bruité, il est plus net. Analysez ensuite les échecs pour trouver s'ils viennent d'en amont.
Ce guide vous a aidé ?

Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.