Reranker 模块
请求示例见 docs/QUICKSTART.md §3.5。扩展规范见 docs/DEVELOPER_GUIDE.md §7。部署与调优实战见 reranker/DEPLOYMENT_AND_TUNING.md。ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF 的专项接入与调优结论见 reranker/GGUF_0_6B_INSTALL_AND_TUNING.md。
Reranker 服务提供统一的 /rerank API,支持可插拔后端(BGE、Jina Reranker v3、Qwen3-vLLM、Qwen3-Transformers、Qwen3-GGUF、DashScope 云重排)。调用方通过 HTTP 访问,不关心具体后端。
当前结论
在当前项目的线上形态里,首选后端是 qwen3_vllm_score,次选后端是 qwen3_vllm。
原因不是“LLM.score() 理论上更高级”,而是这轮优化后,qwen3_vllm_score 在当前硬件和依赖栈上形成了一套更干净、更稳定、也更快的组合:
- 模型:
Qwen/Qwen3-Reranker-0.6B - GPU:Tesla T4 16GB
- CUDA:12.8
- PyTorch:
2.10.0+cu128 - vLLM-score 环境:
vllm==0.18.0 - attention:由 vLLM 运行时自动选择后端实现;在已验证的 T4 栈上日志可见
FLASHINFER
后端总览
| 后端 | 当前定位 | 结论 |
|---|---|---|
qwen3_vllm_score |
主推荐 | 走 vLLM LLM.score() 的 pooling / classify 路径:对每条 (query, doc) 直接产出相关分,不经 causal LM 的整步 generate。相对 qwen3_vllm(generate(max_tokens=1) + yes/no 的 logprob 推导),省去每对样本上大词表 softmax / 采样约束那一层的常规开销,语义与 cross-encoder 式 rerank 更一致;在当前栈与 T4 上延迟表现最好 |
qwen3_vllm |
次推荐 | 稳定、成熟、好排障,是很好的 fallback 和对照组 |
jina_reranker_v3 |
新增本地方案 | 按官方推荐使用 AutoModel(..., trust_remote_code=True) + model.rerank(query, docs),更接近 Jina 原生 listwise rerank 用法 |
qwen3_transformers |
兼容方案 | |
qwen3_transformers_packed |
特定场景方案 | T可能实现还有问题,没调好 |
qwen3_gguf / qwen3_gguf_06b |
低显存 / 功能兜底 | 更适合资源受限场景,不适合作为当前主在线方案 |
dashscope_rerank |
云服务方案 | 运维简单,但依赖外部服务和网络 |
目录与入口
reranker/server.py:FastAPI 服务,启动时按配置加载一个后端reranker/backends/:后端实现与工厂backends/__init__.py:get_rerank_backend(name, config)backends/jina_reranker_v3.py:Jina 官方model.rerank(...)接法backends/qwen3_vllm_score.py:当前最优的本地 GPU rerankerbackends/qwen3_vllm.py:次优的本地 GPU rerankerbackends/qwen3_transformers.py:Transformers 基线实现backends/qwen3_transformers_packed.py:packed 推理实现backends/qwen3_gguf.py:GGUF + llama.cpp 后端backends/dashscope_rerank.py:DashScope 云端重排后端
scripts/setup_reranker_venv.sh:按后端创建独立 venvscripts/start_reranker.sh:启动 reranker 服务scripts/smoke_qwen3_vllm_score_backend.py:qwen3_vllm_score本地 smokescripts/benchmark_reranker_random_titles.py:随机标题压测脚本scripts/run_reranker_vllm_instruction_benchmark.sh:历史矩阵脚本
环境基线
当前验证环境:
- GPU:
Tesla T4 16GB - Driver / CUDA:
570.158.01 / 12.8 - Python:
3.12.3 torch:2.10.0+cu128transformers:4.51+qwen3_vllm_score环境:vllm==0.18.0qwen3_vllm环境:vllm>=0.8.5
独立 venv 约定:
qwen3_vllm->.venv-rerankerqwen3_vllm_score->.venv-reranker-scorejina_reranker_v3->.venv-reranker-jinaqwen3_transformers->.venv-reranker-transformersqwen3_transformers_packed->.venv-reranker-transformers-packedqwen3_gguf->.venv-reranker-ggufqwen3_gguf_06b->.venv-reranker-gguf-06bbge->.venv-rerankerdashscope_rerank->.venv-reranker-dashscope不同后端的 CUDA / vLLM / llama.cpp 依赖耦合很深,混装后更难定位性能和兼容性问题
qwen3_vllm_score 和 qwen3_vllm 分了两个环境,是因为qwen3_vllm_score使用了vllm 0.18,但是后面经过测试两者性能相同。所以其实可以共用一个环境。不过没有动力合并回去。
安装与部署
1. 创建后端环境
qwen3_vllm_score:
./scripts/setup_reranker_venv.sh qwen3_vllm_score
qwen3_vllm:
./scripts/setup_reranker_venv.sh qwen3_vllm
jina_reranker_v3:
./scripts/setup_reranker_venv.sh jina_reranker_v3
2. 基础检查
nvidia-smi
./.venv-reranker-score/bin/python -c "import torch, vllm; print(torch.cuda.is_available(), torch.cuda.get_device_name(0), vllm.__version__)"
./.venv-reranker/bin/python -c "import torch, vllm; print(torch.cuda.is_available(), torch.cuda.get_device_name(0), vllm.__version__)"
3. 启动服务
./scripts/start_reranker.sh
4. Smoke
PYTHONPATH=. ./.venv-reranker-score/bin/python scripts/smoke_qwen3_vllm_score_backend.py --gpu-memory-utilization 0.2
jina_reranker_v3
该后端参考 Jina 官方模型卡接入,使用:
from transformers import AutoModel
model = AutoModel.from_pretrained(
"jinaai/jina-reranker-v3",
dtype="auto",
trust_remote_code=True,
)
results = model.rerank(query, documents)
服务内实现补了几件工程化工作:
- 统一适配
/rerank协议,返回与输入 docs 对齐的scores - 对空文档与重复文档做预处理,避免重复推理
- 支持
top_nhint,并保留原始输入顺序输出 - 保留
cache_dir/device/dtype/batch_size等配置项
推荐配置:
services:
rerank:
backends:
jina_reranker_v3:
model_name: "jinaai/jina-reranker-v3"
device: null
dtype: "float16"
batch_size: 64
max_doc_length: 160
max_query_length: 64
sort_by_doc_length: true
cache_dir: "./model_cache"
trust_remote_code: true
T4 实测建议:
dtype优先使用float16;在当前机器上auto会加载成bfloat16,明显更慢- 在线短文本商品重排建议从
batch_size: 64起步;它比更大的 listwise block 更快,但会牺牲一部分“完整 listwise”排序一致性 - 若你更看重接近完整 listwise 的排序结果,可提高到
batch_size: 125,代价是延迟明显上升 max_doc_length: 160、max_query_length: 64更适合当前商品标题 / 短 query 场景
当前最优方案:qwen3_vllm_score
关键实现点
qwen3_vllm_score.py 里值得关注的地方:
runner/convert保持 auto:走 pooling / classify 与LLM.score()的推荐接法(vLLM 0.17+)hf_overrides:把原始 Qwen3 reranker 权重按官方要求映射到Qwen3ForSequenceClassificationLLM(...)仅使用本后端所需的模型与并行等参数;attention 后端由 vLLM 内部按运行环境选用deduplicate_with_positions(...):先去重,再回填原始顺序sort_by_doc_length:减少 padding 浪费infer_batch_size:控制服务层分批enable_prefix_caching:(作用每检验过)self._infer_lock:避免当前进程模型下并发调用破坏 vLLM engine 稳定性
Attention 与算力路径(现状)
- vLLM 根据 GPU 算力架构与当前 wheel 中的实现(如随发行版提供的 flashinfer 等)自动选用 attention 路径。
- 在 Tesla T4(
sm_75) + vLLM 0.18.x 的已验证环境中,服务日志中可见选用FLASHINFER。
attention后端对比
| 后端 | 计算能力要求 | 特点 | 适用场景 |
|---|---|---|---|
| FLASH_ATTN (FA2/FA3/FA4) | ≥ 8.0 (Ampere+) | 最高性能,手写 CUDA 内核 | A100/H100 等高端卡 |
| FLASHINFER | 7.x-9.x (JIT) | 灵活定制,支持多种变体 | 需要特殊 attention mask |
| TRITON_ATTN | 任意 | 纯 Triton,跨平台,零依赖 | 旧 GPU / AMD / fallback |
| XFORMERS | 任意 | 替代方案,灵活性高 | 兼容性优先 |
推荐配置
当前项目统一使用 standard,README 也按这个基线描述:
services:
rerank:
backend: "qwen3_vllm_score"
backends:
qwen3_vllm_score:
model_name: "Qwen/Qwen3-Reranker-0.6B"
use_original_qwen3_hf_overrides: true
engine: "vllm"
max_model_len: 256
tensor_parallel_size: 1
gpu_memory_utilization: 0.20
dtype: "float16"
enable_prefix_caching: true
enforce_eager: false
infer_batch_size: 100
sort_by_doc_length: true
instruction_format: standard
instruction: "Rank products by query with category & style match prioritized"
关键实现点
AutoTokenizer.apply_chat_template(...)SamplingParams(max_tokens=1, allowed_token_ids=[yes, no])generate(...)后从最后一步 logprobs 计算 yes/no 概率- 同样具备去重、按长度排序、分批推理、前缀缓存、单进程锁等优化
推荐配置
services:
rerank:
backends:
qwen3_vllm:
model_name: "Qwen/Qwen3-Reranker-0.6B"
engine: "vllm"
max_model_len: 256
tensor_parallel_size: 1
gpu_memory_utilization: 0.20
dtype: "float16"
enable_prefix_caching: true
enforce_eager: false
infer_batch_size: 100
sort_by_doc_length: true
instruction_format: standard
instruction: "Rank products by query with category & style match prioritized"
benchmark 建议流程
推荐流程:
- 确认目标 backend 已切换到正确配置
./scripts/start_reranker.shcurl http://127.0.0.1:6007/health- 跑 benchmark 脚本
- 保存 JSON 和 Markdown 结果
- 记录当时的 GPU 占用情况和
nvidia-smi
常见问题
1. 为什么第一次启动很慢
- 模型加载
- torch.compile
- CUDA graph capture
- flashinfer / triton JIT
3. qwen3_vllm_score 的 attention 要在哪里调
由 vLLM 在运行时按 GPU 与版本自动选择;与延迟和稳定性更直接相关、且建议在仓库里动的,是 max_model_len、infer_batch_size、gpu_memory_utilization、去重、排序分批、prefix cache 等。
代码阅读建议
reranker/backends/qwen3_vllm_score.pyreranker/backends/qwen3_vllm.pyscripts/start_reranker.shscripts/setup_reranker_venv.shconfig/config.yaml里的services.rerank.backends.*
性能测试、对比
ll tests/reranker_performance/
curl1.sh
curl1_simple.sh
rerank_performance_compare.sh