Guide · 使用教程
FlashRank Python 教程:候选文档重排、中文评估与延迟测试
固定真实多语言 ONNX 模型,验证候选来源与 token 长度,记录本地延迟,并保留中文退款问题排序失败的例子。
这篇教程会完成什么
你会在 Python 中给一组中文候选片段重排,保留来源信息,拒绝超长输入,并分别测量初始化和推理耗时。示例使用公开的合成退款文本,不连接向量数据库、不调用付费模型 API,也不自动执行退款或其他业务操作。
先明确一个实际结果:这次多语言模型把“关闭自动续费不会自动退款”的片段放在“七天内且未使用可申请退款”的直接规则之前。程序成功返回,不代表答案证据排对了。下面会保留这个现象,说明工程校验与质量验收应该分开。
资料与本地验证日期为 2026-10-21,固定 FlashRank 0.2.10、Python 3.11,使用 ms-marco-MultiBERT-L-12 的 ONNX 路径。本文没有统一中文检索基准,四条合成文本不能证明模型在真实业务中的好坏,也不能给出生产 p95。
开始前需要准备
准备可运行 Python 3.11 的环境、能安装依赖及下载模型的网络,以及持久可写的模型缓存目录。其他 Python 与操作系统组合先检查 ONNX Runtime 是否提供对应安装包。本次默认 Python 3.14 没有成功解析到所需 ONNX Runtime 包,改用 3.11 后完成安装;这不是对所有平台的兼容性判断。
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install 'flashrank==0.2.10'
python -m pip freeze > requirements.lock.txt
首次模型初始化可能下载权重,之后才有条件验证缓存下的本地运行。不要把库代码 Apache-2.0 直接套到权重上:prithivida/flashrank 文件仓库标注 CC-BY-SA-4.0,并说明署名与回链要求,具体上游模型也应核对。缓存应来自可信来源,生产环境固定文件版本并校验完整性,不临时加载不明模型包。
第一步:先确认候选已被召回
重排只处理传入的候选,不负责遍历整个知识库。这里直接构造四条片段,模拟检索器已经找出的结果。真实应用要先根据认证身份执行访问控制,限制来源和版本,之后才把允许的候选送进重排。
本文函数中的租户一致性检查只是额外防错:tenant 必须来自服务端可信会话,不能相信请求里随便提交的租户名;候选的 meta 也必须来自可信数据库记录。相同字段不等于用户具有访问权。示例不实现登录、数据库过滤或完整授权。
第二步:保存完整脚本
将下面代码保存为 rerank_demo.py。它只支持本例的 pairwise ONNX 模型;先复制模型 tokenizer 并关闭截断,用查询与候选的组合输入检查真实 token 长度。候选上限 30、返回上限 10 是本例的应用限制,不是 FlashRank 的官方通用限额。
FlashRank 当前 pairwise 实现会添加分数并改变候选顺序,因此传入深复制,避免污染调用方的数据。返回后检查 ID、原文和来源未变,并把数值分数转为普通 Python 浮点数以便 JSON 序列化。
copy
json
math
os
time
importlib.metadata version
flashrank Ranker, RerankRequest
tokenizers Tokenizer
():
(query, ) query.strip():
ValueError()
(tenant, ) tenant.strip():
ValueError()
(top_k) <= top_k <= :
ValueError()
<= (candidates) <= :
ValueError()
ranker.llm_model :
ValueError()
counter = Tokenizer.from_str(ranker.tokenizer.to_str())
counter.no_truncation()
counter.no_padding()
limit = ranker.tokenizer.truncation[]
originals = {}
p candidates:
(p, ):
ValueError()
cid, text, meta = p.get(), p.get(), p.get()
(cid, ) cid cid originals:
ValueError()
(text, ) text.strip():
ValueError()
(meta, ) meta.get() != tenant:
ValueError()
meta.get() meta.get():
ValueError()
(counter.encode(query, text).ids) > limit:
ValueError()
originals[cid] = p
started = time.perf_counter()
ranked = ranker.rerank(RerankRequest(query=query, passages=copy.deepcopy(candidates)))
elapsed_ms = (time.perf_counter() - started) *
(ranked) != (candidates) {p[] p ranked} != (originals):
RuntimeError()
p ranked:
original = originals[p[]]
p[] != original[] p[] != original[]:
RuntimeError()
p[] = (p[])
math.isfinite(p[]):
RuntimeError()
(a[] < b[] a, b (ranked, ranked[:])):
RuntimeError()
ranked[:top_k], elapsed_ms
():
texts = [
(, ),
(, ),
(, ),
(, ),
]
[(=cid, text=text, meta=(tenant_id=, source=, version=)) cid, text texts]
__name__ == :
model = os.environ.get(, )
start = time.perf_counter()
ranker = Ranker(model_name=model, cache_dir=os.environ.get(, ), max_length=)
init_ms = (time.perf_counter() - start) *
candidates = fixtures()
before = copy.deepcopy(candidates)
query =
rows, first_ms = checked_rerank(ranker, query, candidates, )
timings = [checked_rerank(ranker, query, candidates, )[] _ ()]
candidates == before
(json.dumps((flashrank=version(), model=model, initialization_ms=(init_ms, ), first_rerank_ms=(first_ms, ), warm_rerank_ms=[(t, ) t timings], results=rows, input_unchanged=), ensure_ascii=, indent=))
常见问题
- 本例调用付费模型 API 吗?
- 没有。使用本地 ONNX 模型和合成文本,第一次准备权重可能联网,最终集成检查阻断 socket 外连。
- 为什么推荐 Python 3.11?
- 本次默认 Python 3.14 未找到所需 ONNX Runtime 安装包,3.11 环境完成了安装与运行;其他平台应独立检查兼容性。
- 本例中文问题排序正确吗?
- 没有完全正确。取消续费片段排在直接退款规则前面,所以教程保留失败,强调接口成功不等于质量提升。
- tenant_id 一致就证明没有越权吗?
- 不能。函数只做防错检查,可信身份、数据库过滤和完整授权仍由应用负责。
- 九项检查通过说明什么?
- 说明真实模型接口、输入不变与指定坏数据拒绝约束成立,不证明检索质量提升或生产尾延迟达标。
- 如何处理超过 token 预算的候选?
- 先明确拒绝、重新切分或可审计的截断策略,并保留来源关系;本例选择拒绝,不静默丢掉尾部。