news 2026/11/4 8:52:43

别拿名次当分数:用Rerank做判定模型的失败复盘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别拿名次当分数:用Rerank做判定模型的失败复盘

周六下午,我盯着终端里的日志,上面的数字难看得很。第 16 个实验跑完了,F1 依旧在 0.6 附近晃悠。想了很久,最后在技术群里认输:“rerank 配小模型,复现不了那个判定模型,我投了。”

不是标题党,是真的输了。我手上这个任务很常见:给定一个 query 和一段文档,判断文档是不是真正满足这个 query——相关还是不相关,通过还是不通过。本质是一个二分类判定模型,不是召回也不是精排。约束是不能用大模型 API,只能用开源小模型,最好普通显卡就能转起来。当时我把主意打到了 rerank 头上。

逻辑是这样的:rerank 的核心是交叉编码器,query 和文档拼在一起过 Transformer,语义交互吃得很透,在检索里的提分效果肉眼可见。它既然这么懂语义,我为什么不直接拿它的分数当判定分数?再配一个小模型做前置过滤,纯开源、少标注、低成本,这不就齐活了?

理想很丰满,现实很打脸。两天,16 个实验,从 zero-shot 试到微调,从阈值搜索试到分数校准,甚至把高斯过程回归都用上了,最好的成绩也离目标差一截。这篇文章不是教程,是一个完整的失败记录,我会把实验设计、核心现象和底层原因都拆开来讲。如果你也在打“用 rerank 做判定”的主意,看完应该能少走两天弯路。

1. 为什么我会想到用 rerank 做判定模型

1.1 判定模型的本质:要的是及格线,不是名次

判定模型的经典任务就是二分类或多分类,输出的是一个“该样本属于哪个类、满足不满足条件”的绝对判断。拿我的任务举例:判定“文档是否真正回答 query”,模型面对的是 Ground Truth 标签,它学习的最终目标是让“通过/不通过”的决策正确率最大化。这样的模型,天然需要输出一个可以被比较的绝对测度——0.7 的通过概率和 0.3 的通过概率,代表着两种不同的置信程度,而且这两个数字在不同样本之间是可比的。

rerank 呢?它学的是相对序。训练数据长什么样?某一次搜索里,用户点了结果 A 没点结果 B,所以 A 应该在 B 前面;某次问答里,文档 C 比文档 D 更贴合 query,所以 C 排在 D 前面。它的优化目标是 NDCG、MRR 这类排序指标,Loss 也是 pairwise 或者 listwise 的形式。模型关心的是候选集内部“谁在谁前面”,根本不关心第二条文档绝对地“有多好”。

我说得通俗一点。你高中班上有个同学,你只知道他每次模考名次都在你前面,但你不知道他总分是 650 还是 400,也不知道 480 分算不算过一本线。rerank 就是那个只见过名次、没见过分数的考生。你把它拉来当“判定模型”,问它“这条文档有没有资格及格”,它只能给你一个相对位置的感觉,不能给你一个绝对的分数。

1.2 交叉编码器的“语义理解”给了人错误的安全感

既然 rerank 有这个问题,为什么我一开始还是想用它?因为交叉编码器太诱人了。它把 query 和 doc 拼成一个序列,过完整的 Transformer,attention 可以同时看到 query 的每一个 token 和 doc 的每一个 token。对比双塔结构的 embedding 模型,它理解的是真正的语义交互,而不是两个向量的余弦相似度。在很多 RAG 评测里,rerank 能把召回结果从 top-20 提升到 top-5,效果非常猛。

于是我会产生一种错觉:这模型是真的“懂”语义的。既然懂,那它输出一个分数,我为什么不能把它当成置信度?当时的思考特别顺滑:分数高等于更相关等于满足要求;分数低等于不相关等于不满足。这中间只差一个阈值。而阈值这种东西,拿验证集一搜不就有了吗?

这个推理的危险之处在于,它把“模型内部理解能力强”和“模型的输出具有绝对度量意义”划了等号。实际上,交叉编码器理解语义很强,但不代表它被训练成了一个绝对评分器。它的打分函数只要能维持相对顺序就完成任务了,至于分数本身科学不科学、稳定不稳定,训练目标根本不关心。

1.3 任务约束:为什么一开始绕开微调

还有一个现实原因:我没有大量标注数据。这次的判定任务,人工标注样本一共几百条。几百条去微调一个 7B 模型,大概率过拟合;拿去微调 BERT 类模型,效果倒是稳,但当时心里预期是“应该用不上,rerank 直接就够了吧”。这个误判直接导致我头两天在错误的方向上冲。

另外还有一个来自行业氛围的推力。那段时间开源小模型讨论很热,经常有人问“现在开源小模型有好用的么”。确实,Qwen2.5、Llama-3.2 这些,写摘要、做角色扮演、跑函数调用,都已经有模有样。我心里难免会想:小模型加一个聪明的 rerank,强强联合,判定任务还拿不下?后来的事实是:聊天好用和判断靠谱,完全是两码事。

2. 第一天的 6 个实验:从直出到裸奔

2.1 环境与基线配置

有必要先交代一下环境,方便你对照复现。两张 4090,离线推理用 vLLM 起的小模型服务,rerank 用的是 BGE 系列的 cross-encoder。候选小模型我测了 Qwen2.5-1.5B Instruct、Qwen2.5-3B Instruct、Qwen2.5-7B Instruct,以及一个 DeBERTa-v3-base 做微调对照。数据统一走一套 prompt 模板:

你是一个严谨的判定模型。根据问题和文档,判断文档是否真正回答了问题。 只能输出 yes 或 no,不要输出其他内容。 问题:{query} 文档:{doc} 回答:

这里有个小细节,我后来发现:模型输出如果不做约束,会给你一堆解释,什么“文档提到了相关内容,因此可以认为……”之类的。解析这些文本做判断,比解析 yes/no 麻烦得多。所以实验里我做了 constrained decoding,强制模型只能从 yes/no 两个 token 里选。用 vLLM 的 guided_decoding 或者 Outlines 库都能实现。这一点算是第一天最明确的收获:生成式小模型做判定,必须锁死输出空间,否则它自己发挥起来,你的解析逻辑根本跟不上。

2.2 实验 1-4:小模型直接判定的表现

第一批实验就是让 1.5B、3B、7B 轮流上阵。结果很有意思,也很有挫败感。

1.5B 的 zero-shot 几乎等于乱猜,验证集 F1 大概 0.52,也就是比抛硬币好一点点。而且它特别喜欢说 yes,一遇到“文档里沾了点边”的情况就放行。3B 稍好一点,F1 将近 0.58,但遇到否定句式、条件约束多的 query 就崩。举个例子,query 是“哪些情况不能提取公积金”,文档逐条列了提取条件,3B 会抓住“公积金可提取”这几个词直接放行,完全没看到“不能”这个否定。

7B 明显正常多了,F1 能到 0.67 左右。但离我预期的 0.85 还是差着一大截。这里我要说一句公道话:7B 的表现让我看到开源小模型确实在进步,但“好用”是相对的,在严谨判定上它的稳定性依然不够。同一个样本,你把 prompt 里“只能输出 yes 或 no”改成“请给出结论”,它的判断就会飘。

few-shot 也试了,给 3B 塞了 5 个手工挑选的示例,F1 勉强涨到 0.61,但是换个示例顺序就掉到 0.55。这种方差让人觉得不踏实:你根本不知道模型学会的是判断逻辑,还是学会了模仿示例的格式和倾向。

2.3 实验 5-6:rerank 裸打分,阈值问题直接暴露

第一批的重头戏是 rerank 裸打分。我用 bge-reranker-v2-m3 给每条样本的 (query, doc) 算一个分数,一开始按直觉设 score 大于 0 判定为相关。结果 F1 只有 0.60 出头,比 7B 还差。于是我做了一件很自然的事:在验证集上搜索最优阈值,把 F1 拉到 0.64。

到这里,问题已经初见端倪。验证集最优阈值是 0.37,可一旦换到测试集,用同一个固定阈值,F1 直接掉到 0.58。我第一反应是“阈值过拟合了”,多搜几个区间、多搞点分位数总行吧?后来才发现根本不是阈值的问题,是分数本身不具备跨集稳定性。同样一句话,在验证集上的分布和在测试集上的分布天差地别,你搜出来的最优阈值只是那几百条样本的巧合产物。

我把第一天的实验结果整理成了表。

编号方法关键配置验证集F1现象
1Qwen2.5-1.5B zero-shot固定模板 + constrained decoding约0.52偏向yes,判断接近随机
2Qwen2.5-3B zero-shot同上约0.58否定句式、条件约束理解差
3Qwen2.5-7B zero-shot同上约0.67相对正常,稳定性仍差
4Qwen2.5-3B few-shot5个示例约0.61示例顺序敏感,方差大
5bge-reranker-v2-m3score > 0约0.60直接当判断分数,不如预期
6bge-reranker-v2-m3验证集最优阈值约0.64阈值切到测试集即失效

第一天的结论,表面上看起来是“阈值没选好、小模型不稳”,但实际上已经藏着一个更深的问题:rerank 的分数不是一个稳定的绝对度量。只是我当时的认知还不够,把问题归结到阈值上,于是有了第二天那一堆校准和融合实验。

3. 第二天的 10 个实验:校准、融合、微调、锚点,能试的都试了

3.1 实验 7-9:分数融合与真正意义的微调

第二天早上,我先把最直觉的融合方案跑了一遍。小模型生成答案时本身有 logits,rerank 也有分数,两个加权的想法非常自然。实验 7 就是让“小模型 logits 的 sigmoid 值”和“rerank 分数的 min-max 归一化值”做加权求和。权重从 0.1 到 0.9 网格搜索,结果最好 F1 约 0.66。这个数字很令人沮丧:融合的上限基本就是两个模型的 max,加权没有创造出新的能力。

接下来我开始怀疑一个一直没做的事:微调。实验 8 是拿几百条标注数据微调 DeBERTa-v3-base 做二分类。结果它直接跑到 F1 0.78,这个成绩比我前两天所有“聪明”方案都高。我当时脑子里只有一个想法:分类任务就该用分类模型,我在这儿跟排序模型较什么劲?

为了验证这个想法,实验 9 用 Qwen2.5-3B 做了 LoRA 微调,但这次不是生成式微调,而是把模型最后一层换成了二分类头,用交叉熵训练。F1 约 0.72,低于 DeBERTa。数据量太少是一方面,另一个原因我后面会讲:生成式预训练模型的 representation 不一定适合直接接分类头,它习惯的是“预测下一个 token”,不是“把语义压到一个标签上”。

3.2 实验 10-12:锚点对比、特征化和多任务

实验 10 是我当时觉得最有可能突破的方案:锚点对比。既然 rerank 是学 pairwise 的,那我就顺着它的训练方式走。固定一组人工挑选的正例锚点和负例锚点,把待判定文档分别和正锚、负锚组成 pair,用 rerank 分别打分,两个分数的差作为判定依据。逻辑上讲,如果文档和正锚的 pair 得分高,那它应该更接近正类。

这个方案在验证集上 F1 到了 0.66,但有两个致命问题。第一,锚点非常敏感,换一组锚点,分数差能到 0.08。第二,它导致推理时间变成原来的倍数级,每一条样本要跑两次 rerank,线上请求的延迟根本顶不住。这种方案只能算实验室玩具,不能落地。

实验 11 我换了个思路:不把 rerank 分数当最终判决,而是当特征。把 rerank 分数、小模型给出的 logits、文档长度、query 与 doc 的 token 重叠数、关键词命中率等一起喂给一个逻辑回归。F1 到了 0.68,虽然比裸打分好,但也就那样。这至少说明,rerank 分数里确实有判别信息,但它需要被其他特征修正,不能独当一面。

实验 12 是更硬核的做法:把 reranker 的 backbone 拿出来,加一个二分类 head,做多任务学习——一个 head 走原来的 pairwise 排序 loss,一个 head 走 pointwise 分类 loss。F1 到 0.70。这个方案已经跟“用 rerank 做判定”关系不大了,本质是用 rerank 模型的结构微调出一个分类模型。这也印证了一件事:想要绝对判定能力,就得用 pointwise 的监督信号去训,不能指望 pairwise 预训练模型天生具备。

3.3 实验 13-16:校准、集成与最后的认输

接下来的四个实验,我开始跟“分数校准”死磕。实验 13 是动态阈值,不是固定一个数,而是按分数分布取分位数。效果跟固定阈值没有本质区别,测试集该失效还是失效。

实验 14 上了一个更有理论味道的方法:对 rerank 分数做校准。先试了 isotonic regression,效果一般,因为校准样本太少。后来想到高斯过程回归——它在小样本、非线性映射场景下的拟合能力不错,适合把“排序分数”这种形状不明的变量映射到“概率”上。校准完的分数确实看起来更平滑、更像概率了,F1 却几乎没有提升。原因也简单:校准只改变阈值,不改变排名。排序模型还是那个排序模型,校准只是给它穿了一件“概率”的外衣。

实验 15 是集成。我把 bge-reranker-v2-m3、另一个开源的 cross-encoder、还有微调后的 DeBERTa 一起投票,F1 到了 0.79。这个数字终于过了我自己拍脑袋定的 0.75 心理线,但代价是部署三套模型,延迟和成本直接爆炸。而且它已经彻底退出“rerank 配小模型”的框了,真正托底的是那个微调分类模型。

实验 16 是压垮我的最后一根稻草。我违规换了一个更大的模型跑同一条 pipeline,F1 轻松到 0.84 以上,任务难度完全可控。也就是说,不是任务不可做,不是我标注数据不够,是“开源小模型 + rerank”这个组合本身不具备稳定复现判定模型的能力。于是我认输了。

第二天的实验结果我也整理了一下。

编号方法关键配置验证集F1现象
7logits + score 加权融合权重网格搜索约0.66上限约等于两者max
8微调 DeBERTa-v3-base二分类head约0.78分类模型直接碾压各种“聪明方案”
9Qwen2.5-3B LoRA 二分类分类head + CE约0.72数据少,提升有限
10正负锚点对比双次rerank约0.66锚点敏感、延迟翻倍
11rerank分数做特征 + LR手工特征约0.68分数有信息量,但只能当特征
12rerank backbone多任务pairwise + pointwise约0.70实质已是微调分类模型
13动态分位数阈值按分布取阈值约0.64不解决跨集失效
14分数校准isotonic + 高斯过程回归约0.65分数变平滑,F1没变
15多模型集成投票双rerank + DeBERTa约0.79托底的是DeBERTa,不是rerank
16大模型同管线7B以上 / API约0.84任务可做,路线错了

4. 认输的底层原因:排序分数与判定分数之间隔着一条认知鸿沟

4.1 一个让我彻底明白的反直觉现象

在讲数学之前,先讲一个实验现象。有一次我在调试时,拿同一条 (query, doc) 分别放进两个候选集里算 rerank 分数。第一个候选集里全是弱负例——那些明显不沾边的文档;第二个候选集里塞了几个强负例——语义高度相似但没答到点上的文档。结果同一条样本,在弱负例环境里得分 1.2,在强负例环境里得分 2.8。

这个现象当时看得我头皮发麻。如果 rerank 的分数真的是文档和 query 之间的绝对相关度,那它不应该因为周围是谁而改变。但现实是它变了,而且变化很剧烈。这说明它学到的更接近一个“相对竞争力”信号:在一个都强的候选集里,你再好也可能被压在下面;在一个都弱的候选集里,你再差也能出头。

4.2 pairwise 与 pointwise:两种优化目标,两种世界观

从训练目标来解释就更清楚了。排序模型用 pairwise loss 训练时,样本是一个三元组 (q, d+, d-),loss 只在“正样本得分是不是比负样本得分高”上有约束。只要 d+ 的分数大于 d-,loss 就是 0,模型完全没有义务告诉你,d+ 的分数到底是 0.6 还是 0.9。

于是经过训练之后,模型内部可能把所有候选的分数都挤在一个狭窄区间里,只需要通过微小的流动性区分相对次序。你硬要给这些分数设一个绝对阈值,就像要求一个只打过“谁分数高谁赢”的人去当考官,告诉他“80 分算优秀,60 分算及格”——他根本没经历过绝对尺度,怎么可能给得准?

判定模型则不同。pointwise 分类的目标是让预测的概率贴近真实标签,每一条样本都独立施加约束,学出来的分数自然具备绝对意义。一个是“我比他好”,一个是“我到底够不够好”,这就是 rerank 不能直接当判定模型的根因之一。

4.3 校准为什么救不了排序分数

也许你会说,既然分数分布不稳定,那我拿一批标注数据学一个校准函数,把 score 映射到概率,不就行了?实验 14 已经证明这条路走不通,原因有两层。

第一层,校准函数是固定的,但排序分数的分布是随候选集漂移的。今天线上候选集平均质量是 0.6,明天变成 0.8,同一个文档的分数可能从 1.2 飘到 2.8。校准函数是在旧分布上拟合的,到了新分布上当然失效。这就是为什么实验 14 中,即使我用高斯过程回归把校准函数拟得再平滑,F1 依然没有起色。

第二层,排序分数的非线性不是简单的单调变换。有时候强负例会把正例的分数压低,但压低的幅度跟候选集里有多少个强负例有关,不是单个样本能决定的。这导致校准问题本身就有点病构:你要预测的目标是一个受周围样本影响的值,又想拟合出一个与周围样本无关的全局函数,这本身就矛盾。

4.4 顺手聊聊开源小模型的“虚火”

最后说回“现在开源小模型有好用的么”这个流行话题。我的结论是:看场景。写代码、写摘要、做角色扮演,Qwen2.5、Llama-3.2 这些确实好用。但做严谨判定,它们的表现就像一个聪明但爱脑补的实习生——它能给你一个看似合理的答案,却不能保证答案的边界稳定。

尤其生成式模型,它的输出是逐 token 采样的,末尾的分类概率受 prompt 措辞影响极大。我把 prompt 里的“文档是否真正回答了问题”改成“文档是否与问题相关”,1.5B 模型在 200 条样本上就有 30 多条结论翻转。这种敏感性在聊天场景里感受不明显,在判定场景里是致命的。

如果你非要让生成式小模型做判定,我的建议是:constrained decoding 锁死输出、多次采样取众数、在 prompt 里加清晰的判定标准。但这些只是缓解手段,治不了“模型没有稳定绝对测度”的病根。

5. 认输之后的替代路线,以及这趟弯路的真实收获

5.1 任务本质决定技术路线,别跟 loss 对赌

我现在会先问一个问题:你的输出会被怎么使用?如果这是一个“判断文档是否满足条件”的场景,输出会被当作一个独立、可比的置信度来使用,那请直接选 pointwise 分类模型,比如微调 DeBERTa,或者给 7B 模型加分类头做 LoRA。如果这是一个“把候选结果从好到坏排序”的场景,用户只会看 top-k,那 rerank 就是最合适的,直接选它。

两者的分界线不是模型规模,而是优化目标。pairwise 模型永远不能替代 pointwise 模型,就像你让一个教练只看“队伍排名”来判断“这支队伍有没有夺冠实力”,排名能说明一部分问题,但绝不等于绝对实力。

5.2 如果你实在想用 rerank 做判定,至少按这个姿势来

我不拦着你踩坑,但可以把坑填浅一点:

  • 把 rerank 分数当特征,不要当结果。喂给 LR、GBDT 这类模型,跟其他特征组合,效果会比裸分数好很多。
  • 用锚点对比时,多做鲁棒性测试。换三组以上不同难度的正负锚点,如果结果抖动超过几个点,说明这个方案根本立不住。
  • 做分数校准时,优先考虑分位数校准,样本充足用 isotonic regression,样本少可以尝试高斯过程回归。但要记住,校准解决的是“分数形变”,解决不了“分数漂移”。
  • 监控候选集分布。如果你线上的候选集质量和训练时不一致,rerank 分数整体漂移几乎必然发生,任何固定阈值和校准函数都会跟着失效。

5.3 开源小模型的正确打开方式

这次实验让我对开源小模型的定位有了更清晰的认识:

  • 如果你有 7B 级别可用,优先 7B,别在 1.5B、3B 上硬撑。判定任务对语义边界的要求远高于聊天,参数量的差距会直接体现在稳定性上。
  • 小模型最适合的场景是作为粗筛,把明显不对的样本快速过滤掉,把模糊样本送给精排模型或大模型。这个“粗筛加精判”的架构,在成本和效果之间是最优解。
  • 几百条样本的小数据场景,经典分类器往往比 LLM 更可靠。DeBERTa 微调在我的任务上赢了 Qwen2.5-3B LoRA,原因就是它本来就是为判别任务设计的,参数效率更高,不容易过拟合。

5.4 最后的一点个人体会

如果把这次踩坑的经验压缩成一句话,我会说:别拿名次当分数。做技术选型之前,先想清楚你要的是绝对判断还是相对排序。如果排错了,后面再多的调参、校准、融合、蒸馏,都是在给一个错误的地基添砖加瓦。

当然也不能说一无所获。至少我确认了三件事:开源小模型在判定任务上的边界在哪里、rerank 分数到底是个什么东西、以及未来遇到类似任务时,我应该从哪里开始做。把这些写出来,希望你能比我少跑两天弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 8:52:22

PostgreSQL角色管理:pg_user与pg_roles的差异解析

1. 问题背景与核心痛点在PostgreSQL数据库管理过程中,角色权限管理是DBA日常工作的核心环节。许多管理员习惯使用pg_user视图来查询用户信息,直到某天突然发现这个视图返回的结果不完整——它只显示了具有LOGIN权限的角色,而那些仅有其他权限…

作者头像 李华
网站建设 2026/11/4 8:52:22

DriveLiDAR4D:自动驾驶4D LiDAR场景生成框架,解决数据短缺与长尾场景

做自动驾驶的朋友,十有八九都被数据短缺折磨过。夜间下雨的十字路口、逆光下的行人鬼探头、高速上突然掉落的杂物,这些场景靠真实路采,要么等半年碰运气,要么花冤枉钱做定制测试。而LiDAR点云作为自动驾驶感知的核心模态之一&…

作者头像 李华
网站建设 2026/11/4 8:51:20

Jev判断模型:AI Agent的轻量级决策中枢

1. 这不是另一个大语言模型,而是一次底层逻辑的转向 最近朋友圈和科技圈都在刷“Jev”这个名字——不是因为又出了个能写诗编代码的新模型,而是因为它压根不生成一句话,却让整个AI Agent的响应链条快了一倍以上。我第一次看到这个标题时也愣了…

作者头像 李华
网站建设 2026/11/4 8:50:31

UE5源码内网迁移全流程与Linux环境配置指南

1. UE5源码版内网迁移方案概述 将Unreal Engine 5(UE5)源码版本迁移到内网环境是一个常见的开发需求,特别是在需要隔离开发环境或保护知识产权的情况下。这个过程看似简单,但实际操作中会遇到各种权限问题和依赖管理挑战。 核心迁…

作者头像 李华
网站建设 2026/11/4 8:49:30

蒙特卡洛树搜索(MCTS)原理与工程实现:从UCT到AlphaGo

如果只看技术盘点文章,蒙特卡洛树搜索(MCTS)通常会被列为一句话带过的“AlphaGo核心组件”。但真正自己动手写过一次MCTS之后,我才明白为什么所有教程都要单独拿一章讲它——这套只有四步循环的算法,几乎把“如何在信息…

作者头像 李华
网站建设 2026/11/4 8:48:08

MCP接口是什么?用USB-C比喻讲透AI连接ERP、MES的标准化协议

厂长们对"接口"这个词其实一点都不陌生。车间里的设备要联网,得有个网口;ERP要跟MES打通,得有个数据接口;就连扫码枪连电脑,也得插个USB。但最近半年,总有人跑来问:"MCP接口是个…

作者头像 李华