两个模型评委,同一批 961 条答案,同一套四选一的题面。其中一个评委在 961 次里,有一个选项一次都没选过。
不是因为那个选项没被打分。我读了原始 logprob:四个候选每次都在,那个选项的概率最高冲到过 0.3181,有 24 次是第二名。它就是一次都没赢过。
而我当时正准备拿这两个评委的判决,去量一个大约 1 个百分点的效应。
想直接拿判据的看第 2 章,那是一个除法;想知道我自己在这套方法上翻过什么车,看第 6 章。
1. 我在干什么,以及它为什么值得记一笔
我给自己的助理做一个「难度路由」:一句话进来,先判断它难不难,简单的甩给本地小模型,难的才送云端。要做这件事,我得先知道本地模型到底在哪些问题上会翻车。
于是有了这批数据:961 个真实的对话轮次,每一轮都有云端模型的答案和本地 35B 模型的答案。两个答案并排摆出来,交给评委,问同一道四选一——
都够用 / 只有 A 够用 / 只有 B 够用 / 都不行。
评委有两个。一个是云端的商用判别 API,一个是本地那台 35B 自己读 logit 出分(就是不让它写字,只看它给四个数字标签各打多少分,谁高算谁)。两边随机决定谁当 A 谁当 B,种子一样,961 条的 A/B 位置完全对齐。
理论上,两个评委应该指认出差不多同一批「本地模型答砸了」的题。
2. 噪声地板:一个除法
先看两个评委各自挑出多少:
| 判定本地模型失败 | 占比 | |
|---|---|---|
| 云端评委 | 102 条 | 10.6% |
| 本地 35B 评委 | 161 条 | 16.8% |
| 交集 | 47 条 | — |
| 并集 | 216 条 | — |
重合度 47 ÷ 216 = 21.8%。
这个数字高还是低?光看它没用,得有个「瞎挑能挑成什么样」的基线。基线是个除法:
随机重合期望 = a × b ÷ N
两个评委各挑 a 条和 b 条,总共 N 条,如果他们完全独立地瞎挑,期望重合就是这个数。代进去:
102 × 161 ÷ 961 ≈ 17.09 条
换算成重合度 ≈ 6.95%
实测 21.8%,是瞎挑的 2.75 倍。所以两个评委确实在看同一个东西,有信号,这点先说清楚,我不打算得出「模型评委没用」这种结论。
但有信号和能用是两回事。真正决定我能不能下结论的是另一个数:
噪声地板 = 分歧条数 ÷ 总条数 = 169 ÷ 961 = 17.6%
961 条里,两个评委有 169 条给出了相反的判决。这就是地板。我想量的那些维度——用户问题长不长、有没有上下文、是不是追问——实测出来的差异是 1 个百分点上下。
1pp 的效应,17.6% 的地板。这不是「结果不显著」,这是根本没开始测。
3. 一致率 82.4% 是怎么骗人的
961 减 169 等于 792,792 ÷ 961 = 82.4%。
两个评委一致率 82.4%。这数字要是写进报告里,没人会拦你。
它骗人的地方在于:两个评委大多数时候都说「没失败」。云端评委只挑出 10.6%,本地评委 16.8%。剩下八成多的题,两边都说没问题——这部分一致是白送的,两个瞎猜的评委也能拿到。
算一下白送多少:
瞎猜也能达到的一致率 pe = p₁ × p₂ + (1 - p₁) × (1 - p₂)
代进去:0.106 × 0.168 + 0.894 × 0.832 = 0.762。
也就是说,82.4% 里有 76.2% 是 base rate 送的,真正靠本事挣来的只有那 6 个点。扣掉之后的 kappa:
kappa = (0.824 − 0.762) ÷ (1 − 0.762) = 0.261
0.261。这个量级在标注一致性里通常被叫做「弱」。
这一段可以直接当武器用。 以后看到任何一份报告写「两个标注员一致率 90%」「模型和人类判断一致率 88%」,先问一句:那个类别的基础发生率是多少。如果被标注的东西只占 5%,那全答「没有」就能拿 95% 一致率。一致率这个指标在类别不平衡的时候几乎不含信息,要看 kappa,或者至少让他把混淆矩阵四个格子都写出来。
4. 全场最大的效应,是答案被贴在哪个槽里
这是我最没预料到的一段。
回到开头那个「一次都没选过」。本地 35B 评委的四个选项分布是这样的:
| 选项 | 本地 35B 评委 | 云端评委 |
|---|---|---|
| 都够用 | 623 | 672 |
| 只有 A 够用 | 326 | 192 |
| 只有 B 够用 | 0 | 88 |
| 都不行 | 12 | 9 |
它只要觉得有一个不行,挑的永远是 B。961 次,一次例外都没有。
A/B 位置是随机的,所以这直接污染了失败集。按位置拆开看:
| A 槽放本地答案时 | A 槽放云端答案时 | 差 | |
|---|---|---|---|
| 云端评委判本地失败 | 7.2% | 14.2% | 7.0pp |
| 本地 35B 评委判本地失败 | 1.4% | 33.2% | 31.8pp |
同一个模型、同一批答案,仅仅因为被粘贴到了第二个位置,失败率从 1.4% 跳到 33.2%。
我想测的那些维度,效应都是 1pp 量级。位置效应 31.8pp。这个实验里最大的信号,是槽位。
两个评委在不同的半场上重合度也完全不同:A 槽放本地答案时重合 1/42 = 2.4%,A 槽放云端答案时 46/174 = 26.4%。所谓 21.8% 的整体重合,基本全来自后一半。
顺带说一句,云端那个评委也有位置偏好(7.0pp),只是没到离谱的程度。它至少两个方向都选过:只有 A 挑了 192 次,只有 B 挑了 88 次。不平衡,但没塌成 0。
5. 那我到底需要多少样本
假设我把评委修好了,位置偏见也平衡掉了。要量一个维度上的差异,需要多少题?
两组比例之差的标准误 ≈ √(2p(1−p)/n)
能可靠看见的最小差异 ≈ 2 × 标准误
p 取云端评委那个 10.6% 的失败率:
| 每组样本 | 最小可分辨差异 |
|---|---|
| 100 | 8.7pp |
| 240 | 5.6pp |
| 480 | 4.0pp |
我手上全部 961 条对半分,也就是每组 480,能看见的最小差异是 4.0pp。而实测的维度差异:用户问题长短,云端评委 +1.0pp、本地评委 −0.8pp;有没有上下文,本地评委 −0.3pp。
全部在地板以下。这套装置看不见这些维度有没有效应,这跟「它们没有效应」是两个完全不同的结论。
6. 这个实验有哪些地方靠不住
写在前面:下面每一条都会削弱上面的结论,但不标出来的话,上面那些数字读者应该默认不信。
最大的一条:我没有人类标注。 这篇从头到尾在比两个模型评委,而「本地模型在这题上失败了」这个定义本身从没被人验证过。两个评委可能都在评判一个错的东西。真正的黄金标准得我自己手标,目前是 0 条。
没有上下文那一组只有 47 条。 第 5 章表里云端评委在这组上有 −11.2pp 的差异,看着最大,但 47 个样本的标准误接近 6pp,这个数我一个字都不打算当真。列出来只是因为它是我跑过的维度之一,藏起来不合适。
两个评委的读数机制根本不一样。 云端那个是完整 API,会真的推理再给结论;本地这个是单 token 读 logit,只让它吐一个数字。拿它们对账本来就掺了机制差异,不能干净地归因给「模型能力」。本地评委那个 0 次,也可能一部分来自单 token 这种读法本身。
只跑了一遍,一个提示词,一个随机种子。 位置偏见的正确做法是同一对答案正反各跑一次取平均,我没做。四选一的题面措辞也只试过一版,措辞本身可能就在诱导「只有 A」。
2.75 倍那个信号是真的。 别被前面几段带跑了——两个评委确实在相关地评判同一件事,不是纯噪声。只是这个相关度不足以支撑 1pp 级别的结论。
7. 下次遇到同类问题,照这个顺序走
- 先算随机重合基线
a × b ÷ N,再看你的实测重合度。没有基线的重合度是个没有单位的数。 - 算噪声地板
分歧数 ÷ 总数。把你想测的效应量跟它比一下,效应比地板小就别跑了,先修评委。 - 看到任何「一致率」先问基础发生率,然后算
pe = p₁p₂ + (1−p₁)(1−p₂),把白送的部分扣掉。 - 任何 A/B 并排的评判,先数一遍它选 A 和选 B 各多少次。塌成 0 就是坏了。
- 塌成 0 之后别急着改提示词,先去原始输出里确认那个选项真的被打过分——是没被选中,还是压根没进候选集。这两种情况修法完全不同。
- 要标注就标分歧的那些。我这里 792 条两边一致的题,标了等于白标,169 条分歧集才是信息全在的地方。
- 标之前用
2 × √(2p(1−p)/n)算一下这个样本量能看见多大的差异,再决定标多少条。
这批数据我花了一整晚跑,跑完最有用的产出是知道了它测不了我原本想测的东西。一晚上换一个「先别做」,比拿着 21.8% 的重合度往下修类别划分强。