> temperature=0 不是确定性的——漂移和我要测的效应同阶,而没有一条误差棒含这一项

Research Tools Intermediate 2026-10-09 00:42 2026-10-09
#llm-evaluation #reproducibility #variance #test-retest #statistics #api

在一个 80 题的封闭集评测上,同一个商业模型、同样的 80 道题、同样的输入、 temperature=0,两次调用的准确率是:

结论先行

在一个 80 题的封闭集评测上,同一个商业模型、同样的 80 道题、同样的输入、 temperature=0,两次调用的准确率是:

第一次   60/80 = 75.0%
第二次   63/80 = 78.8%

另一对,相隔三小时的两次运行:56/80 = 70.0% 对 55/80 = 68.8%。

run-to-run 的漂移是 1–3 题。 而我当时想报告的效应,净差是 8 题。

噪声 1–3 题,信号 8 题,而论文里没有任何一条误差棒含有 run 级的方差分量。

所有的区间都是在"每个条件只跑一次"的数据上算的, 它们描述的是二项抽样的不确定性,不是重跑的不确定性。 后者在这里和前者同量级,却完全没有进入任何一个数。

为什么

temperature=0 承诺的是贪心解码,不是确定性服务。实际会动的东西包括: 批处理拼批方式的变化、浮点规约顺序、后端 GPU 型号或 kernel 版本的轮换、 供应商侧的静默模型更新。这些都不在你的控制里,也都不在 API 文档的保证里。

所以 temperature=0 真正的含义是"采样这一步不引入随机性", 而不是"同样的输入得到同样的输出"。

第二个独立的机制:选了个更宽松的区间方法

同一批数据上还有一件事值得记:百分位 bootstrap 的 CI 排除了零, 而同一组配对数据上的精确配对检验不显著。

这不矛盾——它们本来就不是同一个量。百分位 bootstrap 在小样本的配对二元数据上 比精确检验更宽松,所以"CI 不含零"在这里是方法选择的产物,不是证据的强度。

判断方法很简单:看 CI 下界离零有几个 item。 如果下界是 0.012 而 1 个 item = 1/80 = 0.0125, 那这个区间距离包含零只有一个样本。 这种时候报"显著",等于把结论押在一次抽样上。

怎么用

跑任何 LLM 评测,在报任何效应之前:

  1. 先测 test–retest。 同一个条件、同样的输入、不改任何参数,跑两到三次。 这是最便宜的实验,而且它定义了你后面所有数字的分辨率。
  2. 把 run 级方差写进误差棒,或者至少把它单独报出来: "同条件重跑的差异是 ±k 题"。读者需要这个数才能读懂你的主结果。
  3. 效应小于重跑噪声的 2–3 倍时,不要报它。 先扩样本或改设计。
  4. 固定并记录你能固定的:模型快照版本(不是 -latest)、 调用日期、region、batch 大小。记下来的目的不是消除漂移, 是让别人知道你的数字属于哪一次。
  5. 区间方法和检验要对齐。 配对设计就用配对检验; 用 bootstrap 就说明它的下界离零有几个 item。 两个方法给出相反结论时,报更保守的那个,并把分歧写出来。

一句可以直接抄进方法部分的话:

同条件重跑 N 次,准确率的极差为 k 题(k/n 个百分点)。 下文所有效应量均应对照这个分辨率阅读。

出处

2026-07,自己的一组 80 题闭集评测,在一个商业大模型 API 上以 temperature=0 重复调用。上面四个数字(60/80、63/80、56/80、55/80)来自同一批实验的 不同运行,两两之间除了调用时刻之外没有任何差别。 相关:只发边际计数等于结论不可判定——把它算成一个区间,而不是说「统计没做够」、事先声明的偏差是限制,事后发现的偏差是借口、 复现契约——一个分数如果答不出这五个问题,它就不是结果、吞吐上限要报在 spread 收敛的地方,不是报在还能跑通的地方。