从0训练LLM · 现代大模型体系 实验 实验 ≈ 30 分钟 页内实验 ×3
C14 评测与训练仪表:分数能信吗 实验课

我们项目跑过的几十个 run,仪表上哪些「正常」、哪些「要出事」?

实验课:给全课的 run 做一次体检
本章第三层交互:把 C1 到 C11 各章在我们项目里跑过的全部 run 放进一张体检表——开局 − ln V、梯度范数峰值、最大注意力 logit、是否发散——自己定三条报警规则,再和「最终 val 比参照差多少」对照:报警的 run 里有多少真的变坏,没报警的里漏掉了什么。最后用 5 次同配置重跑定下项目的噪声底线。
🧪

这一课不讲新概念。第 1 课的四块仪表、第 3 课的噪声底线,放到我们项目的全部 run 上核对一遍。所有数字直接读实验导出的 c14-eval.json(2026-09-26 生成,共 127 个 run,来自 基线、C11、C14、C1、C2、C3、C4、C5、C6、D/C6、C8、C9、D、参照);没有探针的 run,logit 一栏写「无探针」。

为什么这里不用例句:我们的模型在《三國志演義》上训练,体检看的是每个 run 在整段验证集上的读数,不是某一句话。

先写预测

在打开下面的表之前,先在纸上写三件事:

  1. 你觉得哪几类改动会让仪表报警?(提示:学习率、warmup、归一化位置、初始化、残差、掩码……)
  2. 你觉得有没有「最后结果变差了,但一路上仪表都很安静」的 run?会是哪一类改动?
  3. 同一个配置重跑,最终 val loss 会差多少?0.001、0.01,还是 0.1?

第一步:体检表与报警规则

每一行是一个 run,参照是基线配置 ref_baseline。上面四个输入框是报警规则,默认值是一种写法,不是标准答案:

「结果」一列拿最终 val loss 和参照比:比参照差超过阈值记为「坏」,比参照好得离谱也记为异常。词表、训练长度、步数不同的 run,val loss 没法直接比,记为「不可比」。

项目真实日志 · 全部 run 的体检表(点一行看曲线)
全部 run 的体检表项目真实日志 · 3.7M 参数 · 《三國志演義》

🎯

试三件事(以 2026-09-26 导出的数据为准):① 读最上面的四个计数,再在表里找出「没报警结果却坏」的那几行——它们改的是宽度、去掉 FFN、去掉残差、Post-LN,或者开着 QK-Norm 用大学习率:容量不够、结构卡住、被 QK-Norm 按住了 logit 的 run,仪表都很安静;② 找到 c3_no_mask(去掉因果掩码):最终 val loss 只有 0.0246,参照是 4.6405——它不是训得好,是在训练和验证时都能看到答案(C0 第 5 课:低得离谱时先怀疑评估);③ 把规则 ② 从 3 倍改成 10 倍,再改成 2 倍,看「报警但结果正常」和「没报警结果却坏」两个计数怎么此消彼长——阈值要拿自己的 run 校准。

⚠

常见误解:「仪表报警 = 这个 run 一定坏;仪表安静 = 没问题。」这张表里两种错都有。仪表查的是不稳定(logit 失控、梯度尖峰、开局不对),不是所有的「变差」:模型太窄、结构不对,训练照样平稳,只是学不到;反过来,某些改动让梯度范数峰值很高,最终 loss 却没变差。

第二步:代表性 run 的完整曲线

c14-eval.json 按固定规则挑了几条代表性 run 导出完整曲线:参照、梯度范数峰值最大的未发散 run、最大注意力 logit 峰值最大的 run、初始化标准差 1.0 的 run;第 1 课用过的 C8 各 run 也在。挑一条和参照并排回放:

项目真实日志 · 仪表回放
四块仪表同屏回放(与参照 run 并排)项目真实日志 · 3.7M 参数 · 《三國志演義》

🎯

试三件事:① 默认 c4_nores_12L(12 层、去掉残差):梯度范数在第 5–10 步就是参照的上百倍,loss 很快停在 6.63 附近再也不动——和只按词频猜的 unigram 基线(约 6.62,C0 第 5 课)几乎一样,这是 C4 第 2 课「去掉残差」的实验;② 换成 c8_init1:四块仪表都在第 20 步之前报警(梯度范数第 5 步就报了),它的开局 loss 已经是 ln V 的 7 倍多;③ 换成 c8_qknorm_lr3e-3(开 QK-Norm、基线学习率):它最后比参照还好,可 loss 那一行在第 60 步「报警」了——前期学得慢的 run 会被「比参照高 3σ」这条规则误报。

第三步:定下项目的噪声底线

项目真实日志 · 同配置重跑
同一个配置重跑几次,最终 val loss 差多少项目真实日志 · 3.7M 参数 · 《三國志演義》

同一个配置、同一个种子、同一台机器,5 次重跑的最终 val loss 均值 4.6293、标准差 0.0066、极差 0.0162 。README 里「重跑差约 0.003」的说法只来自两次运行;这张图才是项目今后判断「差异是否超出噪声」的依据。

把结论写进项目

🧭

三条写进 04-实践项目 的规则(对应章首页的项目决策):

  1. 开局自检:每个新 run 的第 0 步 val loss 与 ln 2,048 = 7.6246 的差不超过你在表里定的阈值,否则先查初始化与评估,不往下训。
  2. 报警规则:三条仪表规则的阈值写进 README,附上它们在本表上的「报警且坏 / 报警但正常 / 没报警却坏」三个计数——规则的误报与漏报要公开。
  3. 比较规则:两个配置差距小于 3 × 0.0066(同配置重跑的 3σ)时不下结论;差距与种子标准差同量级时,每边至少 3 个种子(第 3 课的表会告诉你要几个)。

在演进地图上的位置

评测的演进:每一代都被上一代的某个真数字逼出来(点名字去那一课;完整版在章首页)
  1. 只看 loss(和 PPL)
  2. 仪表:开局对 ln V、梯度范数、最大 logit、spike score
  3. 公开 benchmark
  4. n-gram 去污染 + 干净子集
  5. 换一套没见过的题 / 按时间切分
  6. 交换性置换检验(可证检测)
  7. 非公开题 + 第三方预先定好的评测集
  8. 三层可信度 + 口径核对
  9. 多种子、信噪比
  10. 平滑指标 + 两步预测
训练中仪表:开局对 ln V、梯度范数、最大 logit、spike scoreKarpathy 2019;Wortsman 2023;OLMo 2(2024)你在这里
解决了在 loss 变坏之前报警:OLMo 2 观察到剧烈的梯度范数尖峰常先于 loss 尖峰;改初始化后梯度范数的 spike score 从 0.40 降到 0.03。
卡在训练完了,仪表回答不了「模型会不会做题」——要拿题来考。
数字口径:第一格由构建时读取项目真实日志 c08-stability.json 现算(runs 为 c6_lrw_d256_lr0.03 与 ref_baseline);其余出自原文——GPT-3 §4 与附录 C(本地 PDF)、HF《What's going on with the Open LLM Leaderboard?》(2023)、GSM1k 附录 F、Oren 2023 表 1、NIST CAISI 页面(2026-05-01)、DataDecide 摘要、Schaeffer 2023 §1、Hu 2024 摘要、OLMo 2 §3。

一句话

📌

仪表的阈值要拿自己的 run 校准:报警的 run 里有多少真的变坏,没报警的里有没有漏网;差距小于噪声底线,就不下结论。

下一站

这一章的三件工具——训练仪表、分数与污染、信噪比——到这里都用过了。下一章去读别人的前沿技术报告:C15 前沿解剖。

🔍 为什么不把「最终 loss 变差」本身当报警?

因为它来得太晚:最终 loss 要训完才有,而且只能和参照比。仪表的价值在于训练中途就能看、并且带自己的刻度(ln V、logit 的量级)。这张表把最终结果拿来做的,是反过来检验仪表:哪些规则能提前抓住后来变坏的 run。大模型训练里,这一步对应的是用许多小规模、短步数的 run 校准监控阈值,再把阈值用到正式训练上(OLMo 2 的 spike score 就是这样用的)。