bge-reranker-v2-m3: BAAI's multilingual reranker as an API
bge-reranker-v2-m3 is a 568M-parameter cross-encoder from BAAI that scores how well each document answers a query. It is built on the same multilingual training as the bge-m3 embedding model and released under Apache 2.0 in March 2024. It is the model that comparison articles keep recommending when Cohere-class reranking gets too expensive. It is served on this platform's rerank route. One JSON request carries your query and your shortlist. Back comes the shortlist reordered by relevance score. This page gives the exact contract, the metering law, and the context-window numbers with their owners. It also maps the self-host dead ends the model card does not mention.
Last verified: 2026-09-25
What it is
A reranker answers a narrower question than a generator or an embedder. Given this query and these 20 documents already pulled by something else, which ones actually answer it? bge-reranker-v2-m3 does this as a cross-encoder. The query and the document go through the model together in one pass. It emits a relevance score for that pair. Apply a sigmoid and the score lands in a 0 to 1 range. That joint reading is what makes rerankers better judges than vector similarity. It is also what makes them more expensive per pair. You cannot precompute the document side the way embeddings do.
The practical pattern is two stages, and BAAI's model card evaluates exactly this arrangement:
- An embedding retriever (the card's evaluation uses bge-en-v1.5, e5-mistral, bge-zh-v1.5, and bge-m3) pulls the top 100 candidates from the corpus.
- The reranker rescores those 100 query-document pairs and you keep the top 3 to 5.
The identity facts that matter for planning:
| Fact | Value | Owner of the number |
|---|---|---|
| Parameters | 568M | Hugging Face model metadata |
| Weights size | 2.27 GB | Hugging Face model metadata |
| License | Apache 2.0 | model card |
| Window per query-document pair | 8,192 tokens | model config (8,194 position embeddings) |
| Default truncation in FlagReranker | 512 tokens | FlagEmbedding library default |
| Languages | multilingual, via the bge-m3 base | model card |
| Score range | 0 to 1 after sigmoid | model card usage notes |
Two context numbers deserve their own sentence, because pages conflict on them. Each pair gets 8,192 tokens from the model itself. The position-embedding count in its published configuration confirms it. The 512 limit that several guides quote is not the model. It is the default truncation in the FlagReranker convenience class and the model card's own transformers snippet. Both are official. They answer different questions. On this platform's route, whole documents travel in the request body. The route scores them against the model's window.
Within the BGE family there is a real decision to make. The BGE documentation gives the rule. This model appears in three of its recommendation bullets. The bullets cover multilingual use, Chinese-or-English corpora, and efficiency. For saving resources and extreme efficiency, the docs point to the smaller bge-reranker-base and bge-reranker-large. For better performance they point to the heavier bge-reranker-v2-minicpm-layerwise and bge-reranker-v2-gemma. bge-reranker-v2.5-gemma2-lightweight is the newest multilingual entrant in that tier. The docs' closing advice is to test on your real use case and pick the best speed-quality trade. If you are already retrieving with bge-m3, this model is its designed companion on the rerank stage.
On this platform the model answers the bge-reranker-v2-m3 alias on the rerank route. The model answers calls today on this platform, measured 2026-09-09, metered per search from a prepaid wallet. The models index reflects the catalog as it stands. The rerank category page covers the route family.
Use cases
The model's profile is a modest cross-encoder that judges rather than generates. That profile points at a specific set of jobs:
- RAG shortlist reordering. The standard deployment: your retriever's top 100 becomes the reranker's input, and only the top few reach the prompt. This is the arrangement the model card evaluates, and it is where reranking pays for itself: fewer, better chunks in context.
- Search relevance tuning. Where you control the ranking function, a cross-encoder score on the top results lifts the ordering that keyword or vector matching produced, without reindexing anything.
- Filtering agent tool outputs and crawl results. Anything that produces a pile of candidate texts and needs the best two: rerank, cut, proceed. One request handles the whole pile.
- Multilingual corpora. The bge-m3 base covers dozens of languages, which is the official reason this model exists as the multilingual pick. Mixed-language document sets are its home turf.
- Deduplication-adjacent scoring. Pairwise relevance scores between near-duplicate candidates give you a principled keep-or-drop signal rather than threshold guessing.
Self-host it or call the API
The weights are Apache 2.0, so the local road is open, and for some teams it is the right one. The honest decision rule:
Self-host when a machine is already there and traffic is steady. Self-host when you need the FlagEmbedding or transformers-level control (custom truncation, fine-tuning the reranker on your own labeled pairs). Self-host when data must not leave a boundary you control.
Call the API when you want the parts that are boring to build. The self-host road for this specific model has documented potholes. They are worth knowing before you choose it:
- Ollama has no rerank endpoint. Neither /api/rerank nor /v1/rerank exists in Ollama's API, so integrations such as Dify that call for a rerank route fail against it, and the community mirror of the weights on Ollama's library serves embedding-shaped calls instead of scores. The gap is Ollama-specific rather than llama.cpp-wide: llama.cpp's server exposes /v1/rerank when started with its rerank flag, and the GGUF builds of this model run through it.
- LM Studio maps it to the wrong endpoint. It serves the model under /v1/embeddings semantics, which silently breaks rerank integrations such as Dify that call it expecting a scoring route.
- The 512 default bites quietly. Copy the card's example code and long documents get truncated at 512 tokens without an error.
Among the local routes that work are BAAI's FlagEmbedding library (the FlagReranker class, where you can raise the truncation limit) and plain transformers with AutoModelForSequenceClassification. Hugging Face's text-embeddings-inference server also works; its /rerank endpoint is tagged for this model family. vLLM's scoring mode for cross-encoders works too. So does llama.cpp's llama-server. It exposes /v1/rerank when started with its rerank flag and runs the GGUF builds of this model. What none of those give you is the metering and wallet layer around the model. That is the part a hosted route adds.
API usage
The route is POST /v1/rerank with a Bearer key from the console. The body accepts exactly four fields:
| Field | Required | Meaning |
|---|---|---|
model | yes | bge-reranker-v2-m3 |
query | yes | the question or search string |
documents | yes | the shortlist as an array of strings; empty is rejected with a 400 before anything bills |
top_n | no | return only the top N scored documents |
The response is a results array, each entry carrying the index of a document from your request and its relevance_score:
{
"results": [
{ "index": 0, "relevance_score": 0.98 },
{ "index": 1, "relevance_score": 0.11 }
]
}
Three laws of this route that save debugging time:
- One search per request. Metering counts a rerank request as one search regardless of how many documents it carries: 2 documents and 100 documents bill the same single unit. The corpus size is recorded unpriced with the usage row, so the count is visible without costing.
- Retries can replay. The
Idempotency-Keyheader carries full replay semantics on this JSON route: a retry with the same key returns the stored response instead of executing and billing again. - Unknown fields are rejected. The parser accepts the four fields above and nothing else; anything extra fails with a parameter error rather than being silently ignored.
curl
curl -X POST "https://api.ironstratum.com/v1/rerank" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bge-reranker-v2-m3",
"query": "what is the two-stage retrieval pattern",
"documents": [
"Retrieve top candidates with an embedding model, then rescore them with a cross-encoder reranker.",
"The giant panda is a bear species endemic to China."
],
"top_n": 2
}'
python
import os
import requests
resp = requests.post(
"https://api.ironstratum.com/v1/rerank",
headers={"Authorization": "Bearer " + os.environ["KEY"]},
json={
"model": "bge-reranker-v2-m3",
"query": "what is the two-stage retrieval pattern",
"documents": [
"Retrieve top candidates with an embedding model, then rescore them with a cross-encoder reranker.",
"The giant panda is a bear species endemic to China.",
],
"top_n": 2,
},
timeout=30,
)
resp.raise_for_status()
for hit in resp.json()["results"]:
print(hit["index"], hit["relevance_score"])
openai-sdk
The OpenAI SDK has no rerank resource. Its low-level request method reaches the route with the same client you already configure for chat:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ironstratum.com/v1",
api_key=os.environ["KEY"],
)
result = client.post(
"/rerank",
cast_to=dict,
body={
"model": "bge-reranker-v2-m3",
"query": "what is the two-stage retrieval pattern",
"documents": [
"Retrieve top candidates with an embedding model, then rescore them with a cross-encoder reranker.",
"The giant panda is a bear species endemic to China.",
],
"top_n": 2,
},
)
for hit in result["results"]:
print(hit["index"], hit["relevance_score"])
An existing integration changes by exactly two lines: the base URL and the model id.
Benchmarks
Two evidence layers, both dated.
Our hosted lane. Verified 2026-09-09 during the platform's measurement window. The records are the task-17 verification logs, the launch catalog section D, and the measurement comments kept beside the model's row.
| Metric | Value | Basis |
|---|---|---|
| Route round-trip | 200 OK through the live route | E1 lane proof, plus the clone-window 7/7 lane logs |
| Metering exactness | exactly 1 search per request, corpus size recorded unpriced | usage-row assertions against the billing ledger |
| In-flight ceiling | 8 concurrent requests on the hosted lane | E5b measured seat ceilings, shipped as the monitor default |
| First-response p95, single flight | about 0.9 s | E4 seat-monitor observation (single-flight window; read it as observed, not promised) |
| Weights integrity | full-precision BAAI tree, pinned by its sha256 digest | deploy manifest pins table |
These are service-planning numbers from one verification window, not a standing SLA. What they establish is simple. The route, the metering, and the billing ledger agree on what a search is.
The model itself. From the official model card, evaluation date March 2024. BAAI reports results on BEIR, C-MTEB retrieval, MIRACL, and a LlamaIndex evaluation. Every run reranks the top 100 candidates from a retrieval model. It then measures the lift in the final ordering. The multilingual MIRACL run reranks bge-m3 retrieval, the model's designed companion. The card presents these as charts rather than tables, so this page does not re-quote numbers from them. The card's qualitative claim is the official one here. Reranking the retriever's top 100 improves the final top ordering across those benchmarks. Independent secondary comparisons exist with their own numbers. They disagree with each other and occasionally with the model's own metadata. That is why none of them appear here.
For context on where a 568M cross-encoder sits: the same official family page positions it as the lightweight, multilingual, fast-inference pick. The LLM-based family members sit above it on quality. They sit far above it on serving cost.
Getting started
- Create an account on the console. Signup is email-based behind a single invite code while the platform is in its beta phase; the console is where the wallet and your API keys live.
- Create an API key. One key per project is the intended shape: a key is a rotation and revocation boundary, and a leaked one is disabled without touching the others.
- Check the rate. Per-search metering means the pricing page quotes the per-search rate; a rerank request costs the same single metered search whether it carries 5 documents or 100.
- Make the first call. Copy the curl tab, substitute your key, and rerank something small. If the scores come back in the order you expected, every larger case is just a bigger
documentsarray.
The models index lists the rest of the catalog. The rerank page covers this route family.