两天的实验排期,16 组配置,从 rerank 权重到小模型选型再到判定阈值,我几乎把能想到的组合都跑了一遍。结果很直接:没有复现出那个判定模型。但这个过程里踩到的坑、看到的边界、摸清的取舍逻辑,比一个"成功复现"的结论值钱得多。这篇就把整个实验链路摊开讲——为什么选 rerank 配合小模型、16 个实验分别卡在哪、哪些方向其实一开始就该放弃、以及最后我为什么认输。如果你也在琢磨用检索增强加轻量模型做判定类任务,或者纠结开源小模型到底能不能扛住这种场景,这篇应该能帮你省下至少一天半的试错时间。
1. 判定模型这个任务,到底难在哪
1.1 判定和生成是两码事
很多人一上来就把判定模型当成"让模型输出是或否"的生成任务,这个理解偏差会直接带偏整个技术选型。生成任务追求的是流畅、合理、信息完整,模型可以自由发挥;判定任务追求的是稳定、可复现、边界清晰,同一个输入跑十次必须给出同一个结论。这两者的优化目标几乎是对立的。
我这次要复现的判定模型,核心逻辑是:给一段查询和一组候选文档,判断哪些文档真正满足查询意图。听起来像排序,但比排序更严格——排序允许"相对更好",判定要求"绝对达标"。这就意味着模型不仅要理解语义相关性,还要能识别出那些"看起来相关但实际不满足约束"的干扰项。
举个具体例子。查询是"适合小样本仿真数据预测的模型",候选文档里有一篇讲高斯过程回归的,语义上高度相关,但如果这篇文档只讲了理论没讲小样本场景下的参数设置,那它就不该被判为满足。这种细粒度的边界判断,恰恰是小模型最容易翻车的地方。
1.2 为什么想到用 rerank 配合小模型
思路本身不复杂。判定任务可以拆成两步:第一步用检索把候选集缩小,第二步用模型做精细判断。rerank 模型天生就是干第二步的——它接收查询和文档对,输出一个相关性分数。如果把这个分数经过阈值映射成判定结果,理论上就能复现判定模型。
选小模型的原因更现实:判定任务往往需要低延迟、高并发、可本地部署。大模型效果可能更好,但推理成本和响应时间在判定场景里往往是不可接受的。开源小模型这几年进步明显,参数量从 1B 到 7B 都有能打的选手,配合 rerank 做两阶段判定,看起来是一条性价比很高的路径。
我当时的预期是:rerank 负责粗筛和打分,小模型负责在边界样本上做二次确认,两者配合应该能逼近判定模型的效果。这个预期后来被证明过于乐观了。
1.3 判定任务的三个硬指标
在动手之前,我先明确了三个必须同时满足的指标,这也是后面 16 个实验的评估基准:
- 准确率:判定结果和人工标注的一致率,目标 90% 以上
- 一致性:同一输入多次推理结果完全一致,不允许有随机波动
- 延迟:单次判定端到端控制在 500ms 以内,这是判定场景的硬约束
这三个指标里,一致性是最容易被忽视但最致命的。很多小模型在温度参数不为零时,输出会有微小波动,放到判定任务里就是灾难——同一个查询两次判定结果不同,下游系统根本没法用。
2. 16 个实验的完整排布与变量设计
2.1 实验矩阵是怎么搭出来的
两天时间要跑 16 个实验,必须提前把变量矩阵设计清楚,否则就是瞎跑。我把变量分成四组:
| 变量组 | 具体变量 | 取值 |
|---|---|---|
| rerank 模型 | 模型类型 | 交叉编码器、双编码器 |
| 小模型 | 参数量 | 1.5B、3B、7B |
| 判定策略 | 阈值方式 | 固定阈值、动态阈值 |
| 融合方式 | rerank 与小模型关系 | 串联、并联、加权 |
16 个实验就是从这个矩阵里挑出最有代表性的组合。我没有做全排列,因为全排列是 2×3×2×3=36 组,两天根本跑不完。我优先选了那些"理论上最可能work"和"理论上最可能失败"的组合,这样无论结果如何都能获得最大信息量。
2.2 每个实验的固定流程
为了保证可比性,每个实验都走同一套流程:
- 准备 200 条标注好的查询-文档对,其中正例 80 条、负例 120 条,负例里特意混入了 40 条"高相似度干扰项"
- 用 rerank 模型对全部候选打分,记录分数分布
- 按设定的判定策略生成判定结果
- 小模型对边界样本(分数在阈值附近的)做二次判定
- 汇总准确率、一致性、延迟三个指标
这个流程里最关键的是第 4 步的"边界样本"定义。我一开始把边界定义为分数在阈值±0.1 范围内的样本,后来发现这个范围太宽,导致小模型要处理的样本太多,延迟直接爆掉。调整到±0.03 之后才勉强可控。
2.3 实验编号与配置对照
为了后面讲清楚,这里先把 16 个实验的编号和核心配置列出来:
- E01-E04:交叉编码器 rerank + 1.5B 小模型,阈值策略分别为固定 0.5、固定 0.6、动态分位数、动态均值
- E05-E08:交叉编码器 rerank + 3B 小模型,阈值策略同上
- E09-E12:双编码器 rerank + 3B 小模型,阈值策略同上
- E13-E16:交叉编码器 rerank + 7B 小模型,阈值策略同上
这个排布的逻辑是:先固定 rerank 类型,看小模型参数量和阈值策略的影响;再固定小模型,看 rerank 类型的影响。这样能分离出每个变量的独立贡献。
3. 跑下来最先暴露的问题:rerank 分数不是判定分数
3.1 分数分布的真相
第一个实验 E01 跑完,我就发现了一个根本性问题:rerank 输出的相关性分数,分布和判定所需的分数完全不是一回事。
rerank 分数是相对分数,它的绝对值没有意义,只有相对排序有意义。也就是说,同一批候选里,分数 0.8 的文档确实比 0.6 的相关,但 0.8 本身不代表"满足判定条件"。不同查询之间的分数不可比,甚至同一查询不同批次的分数也可能因为候选集变化而漂移。
我实测下来,E01 的分数分布是这样的:正例分数集中在 0.7-0.95,负例分数集中在 0.3-0.7,中间有大量重叠。如果直接卡 0.5 阈值,准确率只有 72%,远低于 90% 的目标。
3.2 固定阈值为什么必然失败
E01 到 E04 用的是固定阈值,结果全部不理想。根本原因在于:判定边界不是全局固定的,而是随查询变化的。
有的查询语义宽泛,正例分数普遍偏高,阈值应该上调;有的查询语义严格,正例分数偏低,阈值应该下调。固定阈值等于假设所有查询的判定边界一致,这个假设在真实数据上不成立。
E03 和 E04 尝试了动态阈值,分别用分位数和均值来定阈值。分位数策略是把当前候选集分数的某个分位点作为阈值,均值策略是用分数均值加减标准差。这两个策略比固定阈值好一些,准确率提到了 78% 左右,但还是不够。
这里有个反直觉的点:动态阈值虽然更合理,但它引入了新的不稳定性。同一查询如果候选集变了,阈值就变了,判定结果也跟着变。这在一致性指标上是扣分项。
3.3 小模型二次判定救了多少
E02 和 E05 的对比很能说明问题。E02 是 1.5B 小模型做二次判定,E05 是 3B。在边界样本上,1.5B 的判定准确率只有 65%,3B 提到了 74%,7B(E13)到了 79%。
这个提升幅度说明小模型确实能捕捉到 rerank 分数捕捉不到的语义细节,但代价是延迟。1.5B 单次推理约 80ms,3B 约 180ms,7B 约 420ms。加上 rerank 本身的耗时,E13 的端到端延迟已经逼近 600ms,超过了 500ms 的硬约束。
更麻烦的是,小模型在边界样本上的判定本身也不稳定。我做了 5 次重复推理,3B 模型在约 12% 的边界样本上给出了不一致的结果。这个不一致率在判定场景里是不可接受的。
4. 小模型选型的现实约束
4.1 参数量和能力的非线性关系
16 个实验里,小模型参数量是最直观的变量。但实测下来,参数量和判定能力不是线性关系,而是有明显的台阶。
1.5B 到 3B 是一个台阶,判定准确率提升约 9 个百分点;3B 到 7B 是另一个台阶,提升约 5 个百分点,但延迟翻倍还多。从性价比看,3B 是拐点,但 3B 的绝对准确率又不够。
这里有个容易被忽略的点:小模型的判定能力高度依赖训练数据分布。我用的这几个开源小模型,预训练数据里判定类任务的比例很低,所以它们在边界样本上的表现普遍偏弱。这不是参数量能完全弥补的。
4.2 量化对小模型判定的影响
为了压延迟,我试过对 3B 模型做 4bit 量化。结果很直接:延迟从 180ms 降到 110ms,但判定准确率从 74% 掉到 68%,一致性也变差了,不一致率从 12% 升到 19%。
量化对生成任务的影响可能还能接受,但对判定任务来说,精度损失直接体现在边界判断上。那些本来就需要精细语义区分的样本,量化后基本判不准。所以在这个场景里,量化这条路走不通。
4.3 本地部署的硬件现实
热词里有人问"二手笔记本电脑 32G 内存能跑小模型的推荐",我正好用一台 32G 内存的机器做了对照测试。结论是:7B 模型在 32G 内存上能加载,但推理速度很勉强,单次判定延迟在 800ms 以上,而且内存占用接近 28G,系统已经开始频繁换页。
3B 模型在 32G 内存上比较舒服,延迟可控,内存占用约 12G。1.5B 更轻,但能力不够。所以如果硬件是 32G 内存这个级别,3B 是上限,7B 不要考虑。
5. 判定策略的深层矛盾
5.1 串联和并联的本质区别
E05 到 E08 用的是串联策略:rerank 先打分,小模型只处理边界样本。E09 到 E12 用的是并联策略:rerank 和小模型各自独立判定,最后加权融合。
串联的优点是延迟低,因为小模型只处理少量样本;缺点是边界样本的定义很敏感,定义宽了延迟高,定义窄了漏判多。并联的优点是判定更全面,缺点是延迟高,因为每个样本都要过两个模型。
实测下来,串联在延迟上有明显优势,但准确率受边界定义影响太大;并联准确率略高,但延迟直接翻倍。在 500ms 的硬约束下,并联基本不可行。
5.2 加权融合的权重怎么定
E09 到 E12 里我试了三种权重:rerank 权重 0.7、0.5、0.3。结果是 0.5 附近最好,但提升幅度很小,只有 1-2 个百分点。这说明 rerank 和小模型的判定结果高度相关,融合带来的增益有限。
更关键的是,加权融合引入了一个新的超参数,而这个超参数在不同查询上的最优值不一样。全局固定的权重,本质上和固定阈值是同一个问题。
5.3 一致性问题的根源
所有实验里,一致性问题始终没有彻底解决。根源在于:判定任务要求确定性输出,但小模型的推理过程本身带有随机性。
即使把温度设为 0,由于浮点运算的累积误差和批处理顺序的差异,输出仍可能有微小波动。在生成任务里这种波动无所谓,但在判定任务里,一个样本的判定结果翻转就是错误。
我试过用多次推理投票来提升一致性,但这样延迟直接乘以投票次数,不可接受。也试过固定随机种子,但只能保证单机单次运行一致,跨批次仍然有波动。
6. 那些我试过但走不通的方向
6.1 用 grep 做本地小模型检索
热词里提到"grep 在本地小模型",我确实试过用 grep 做候选集的粗筛。思路是用关键词匹配先缩小范围,再让 rerank 和小模型处理。
结果很失望。grep 只能做字面匹配,对语义变体完全无能为力。查询"适合小样本仿真数据预测的模型",grep 匹配不到只讲"高斯过程回归"但没提"小样本"的文档。粗筛阶段就漏掉了大量正例,后面再怎么精细判定都救不回来。
grep 唯一有用的场景是候选集极大、需要快速排除明显无关项的时候。但即便如此,它的召回损失也往往得不偿失。
6.2 高斯过程回归做判定
热词里还有"适合小样本仿真数据预测的模型高斯过程回归",我认真考虑过用高斯过程回归来做判定。理论上,高斯过程回归能给出预测的不确定性,这对判定边界很有价值。
但实际试下来,高斯过程回归的输入必须是数值特征,而判定任务的输入是文本。要把文本转成数值特征,又得依赖 embedding 模型,这就绕回了原点。而且高斯过程回归的计算复杂度是 O(n³),候选集一大就跑不动。
这个方向不是不对,而是不适合这个场景。如果判定任务的输入本身就是数值型的仿真数据,高斯过程回归会是个好选择。
6.3 卡帕西知识库那套思路能不能搬
热词里"卡帕西的知识库可以用小模型做吗"这个问题,我也想过。那套思路的核心是用高质量数据加精细微调,让小模型在特定领域达到接近大模型的效果。
但判定任务和知识库问答有个本质区别:知识库问答的正确答案是开放的,判定任务的正确答案是封闭的(是或否)。封闭任务的容错率更低,小模型在边界上的任何偏差都会被放大。
而且微调需要标注数据,我手头只有 200 条标注样本,这个量级做微调远远不够。要微调出稳定的判定能力,至少需要几千条高质量标注,这个成本我承担不起。
7. 认输之后,我重新理解了这件事
7.1 判定模型的本质是数据问题不是模型问题
16 个实验跑完,我最大的收获是:判定模型的效果瓶颈不在模型选型,而在数据质量。
rerank 和小模型都是工具,它们能做的只是把已有的语义信息提取出来。如果标注数据本身边界模糊,如果负例里的干扰项定义不清,再好的模型也判不准。我复盘时发现,那 40 条高相似度干扰项里,有近三分之一我自己都难以确定该判正还是判负。
这意味着,即使模型判"错"了,也不一定是模型的错,可能是标注标准本身就不一致。判定任务的第一步应该是把判定标准定义清楚,而不是急着上模型。
7.2 小模型在判定场景的边界在哪
经过这轮实验,我对小模型在判定场景的能力边界有了比较清晰的认识:
- 3B 以下的小模型,只能做粗粒度判定,边界样本基本靠猜
- 3B 到 7B 之间,能做中等粒度判定,但一致性无法保证
- 7B 以上,判定能力明显提升,但延迟和硬件成本开始不可接受
如果判定任务的边界清晰、干扰项少,3B 配合好的 rerank 有可能达标。但如果边界模糊、干扰项多,小模型这条路基本走不通,要么上大模型,要么回到规则和人工。
7.3 如果重来一次我会怎么做
如果重新做这个项目,我会调整顺序:
- 先花一天时间把判定标准写清楚,找三个人独立标注同一批样本,看标注一致率。如果一致率低于 85%,说明标准本身有问题,先改标准再谈模型
- 用规则加简单统计做一版 baseline,看看不依赖模型能做到什么程度。很多时候 baseline 已经够用了
- 如果 baseline 不够,再考虑 rerank 加小模型。而且要先做小规模验证,确认边界样本上小模型确实有增益,再扩大实验
- 一致性指标要单独设计测试,不能等到最后才发现问题
这个顺序的核心逻辑是:先确认问题定义清楚,再确认简单方法不够用,最后才上复杂方案。我这次是反过来的,先上了复杂方案,跑了两天才发现根子在数据上。
7.4 一个意外的收获
虽然判定模型没复现出来,但这两天的实验让我对 rerank 分数的理解深了很多。rerank 分数作为相对排序指标是可靠的,但作为绝对判定指标是不可靠的。这个认知在后续做检索排序任务时非常有用。
另外,我也摸清了 32G 内存机器跑小模型的实际边界:3B 是舒适区,7B 是极限区,再大就别想了。这个经验对做本地部署的同行应该有帮助。
最后说一句实在话:认输不丢人,跑了两天才认输也不丢人。丢人的是明明方向不对还硬撑,把时间浪费在不可能work的组合上。16 个实验里,真正有价值的不是那些接近成功的,而是那些明确告诉你"此路不通"的。知道哪里走不通,比知道哪里走得通更重要。