如何自托管 reranker
托管 rerank API 很方便,但自托管能带来零按次成本、数据完全可控,以及在自己 GPU/CPU 集群上的可预测延迟。本文从第一次 CrossEncoder 调用,到生产级微服务的实操路径。
何时值得自托管
- 调用量大。每个查询对 50–100 个 chunk 重排序,按千条文档计费的 API 成本会迅速累积。
- 数据驻留。查询与文档不出你的 VPC。
- 自定义微调。可随时换上领域微调 checkpoint,无需等厂商。
如果需要多语言效果、又不想多运维,托管 API —— Cohere、Voyage,国内则有阿里云百炼和硅基流动 —— 算上所有成本可能仍然更便宜。成本计算器可以按你的量级算价格;另见按场景选择。
选择模型
| 模型 | 规模 | 许可证 | 最适合 |
|---|---|---|---|
| bge-reranker-v2-m3 | ~568M | Apache 2.0 | 默认之选 —— 多语言,小到能在 CPU 上跑 |
| gte-multilingual-reranker-base | 306M | Apache 2.0 | 更小的多语言选择(70 多种语言,8K 上下文) |
| Qwen3-Reranker-4B | ~4B | Apache 2.0 | 有 GPU 时的默认之选 —— 在 Qwen 的测试中,三个尺寸里英文和指令跟随表现最好 |
| mxbai-rerank-base-v2 | ~494M | Apache 2.0 | 多语言(含中文);mxbai v2 里体量与质量最均衡的一款 |
| jina-reranker-v3.5 | ~0.6B | CC BY-NC 4.0 | Listwise、长上下文 —— 未获许可时仅限非商用 |
先用 bge-reranker-v2-m3,它在 CPU 上就能跑。有 GPU 时,在你的标注数据上把 Qwen3-Reranker-4B 和它或 mxbai-rerank-base-v2 做 A/B 对比 —— 不要以为排行榜上的顺序能照搬到你的数据。2026 年 10 月之前,这张表推荐的是 bge-reranker-base,那是 BAAI 2023 年只支持中英文的模型。
sentence-transformers 快速上手
pip install sentence-transformers torch
from sentence_transformers import CrossEncoder
model = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)
query = "How do I add reranking to RAG?"
docs = [
"Retrieve 50–100 candidates, rerank with a cross-encoder, keep top 5.",
"London is the capital of the United Kingdom.",
]
pairs = [(query, d) for d in docs]
scores = model.predict(pairs) # higher = more relevant
ranked = sorted(zip(scores, docs), reverse=True)
把文档对批量处理 —— 一次 predict() 给 50 篇文档打分,比单独前向 50 次快得多。max_length=512 会截断更长的内容,所以要把段落切到合适长度,别让段落末尾被悄悄丢掉。
服务化方案
嵌入应用进程
在 FastAPI / Flask RAG 服务内加载模型。低 QPS 最简单;水平扩展副本即可。
独立 rerank 微服务
暴露 POST /rerank,请求体 { query, documents[] }。多个应用 Pod 共享一块 GPU。
# Minimal FastAPI sketch
from fastapi import FastAPI
from sentence_transformers import CrossEncoder
app = FastAPI()
model = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)
@app.post("/rerank")
def rerank(body: dict):
q, docs = body["query"], body["documents"]
scores = model.predict([(q, d) for d in docs])
order = sorted(range(len(docs)), key=lambda i: -scores[i])
return {"results": [{"index": i, "score": float(scores[i])} for i in order]}
服务不一定要自己写:Hugging Face 的 Text Embeddings Inference 和 Infinity 都能把 cross-encoder 部署成 rerank 接口 —— gte-multilingual-reranker-base 的模型卡里有两者的 Docker 命令。先确认你的模型在服务端的支持列表里。
ONNX 导出与 C++ 运行时见 Hugging Face 模型卡。仅浏览器实验可用我们的 在线 Demo(xsmall ONNX 构建)。
运维清单
- GPU:每次查询要重排几十段以上时就值得上 GPU。确定配置前,请在你自己的硬件上实测 p50 / p95 —— 模型卡很少公布延迟,我们也不引用自己没测过的数字。
- 显存:fp16 下光权重就要每个参数约 2 字节 —— bge-reranker-v2-m3 的 568M 参数约 1.1 GB,4B 模型约 8 GB —— 再加上随批大小和段落长度增长的激活值。
- 预热:启动时跑一次 dummy predict,避免冷启动延迟尖峰。
- 监控:在标注子集上跟踪 p95 延迟与 NDCG —— 评测 reranker。
- 降级:rerank 服务不可用时,透传向量 top-k,不要让整条 RAG 请求失败。