我们项目跑过的几十个 run,仪表上哪些「正常」、哪些「要出事」?
这一课不讲新概念。第 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 在整段验证集上的读数,不是某一句话。
先写预测
在打开下面的表之前,先在纸上写三件事:
- 你觉得哪几类改动会让仪表报警?(提示:学习率、warmup、归一化位置、初始化、残差、掩码……)
- 你觉得有没有「最后结果变差了,但一路上仪表都很安静」的 run?会是哪一类改动?
- 同一个配置重跑,最终 val loss 会差多少?0.001、0.01,还是 0.1?
第一步:体检表与报警规则
每一行是一个 run,参照是基线配置 ref_baseline。上面四个输入框是报警规则,默认值是一种写法,不是标准答案:
- 规则 ① 开局自检:|第 0 步 val loss − ln V| 大于阈值;
- 规则 ② 梯度范数:全程峰值 ≥ 参照峰值的几倍;
- 规则 ③ 最大注意力 logit:全程峰值 ≥ 阈值(K2 的 QK-Clip 用 τ = 100,C8 第 4 课);
- 发散:训练中 loss 变成 NaN / inf。
「结果」一列拿最终 val loss 和参照比:比参照差超过阈值记为「坏」,比参照好得离谱也记为异常。词表、训练长度、步数不同的 run,val loss 没法直接比,记为「不可比」。
试三件事(以 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 也在。挑一条和参照并排回放:
试三件事:① 默认 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σ」这条规则误报。
第三步:定下项目的噪声底线
同一个配置、同一个种子、同一台机器,5 次重跑的最终 val loss 均值 4.6293、标准差 0.0066、极差 0.0162 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条MPS 上部分算子不保证逐位确定,400 步训练把微小差异放大;换种子的波动更大(C2 的三种子实验,种子标准差多在 0.01–0.04,sinusoidal 外推到 512 时达 0.14)。 出处本章第 3 课 ↗ 。README 里「重跑差约 0.003」的说法只来自两次运行;这张图才是项目今后判断「差异是否超出噪声」的依据。
把结论写进项目
三条写进 04-实践项目 的规则(对应章首页的项目决策):
- 开局自检:每个新 run 的第 0 步 val loss 与 ln 2,048 = 7.6246 的差不超过你在表里定的阈值,否则先查初始化与评估,不往下训。
- 报警规则:三条仪表规则的阈值写进 README,附上它们在本表上的「报警且坏 / 报警但正常 / 没报警却坏」三个计数——规则的误报与漏报要公开。
- 比较规则:两个配置差距小于 3 × 0.0066(同配置重跑的 3σ)时不下结论;差距与种子标准差同量级时,每边至少 3 个种子(第 3 课的表会告诉你要几个)。
在演进地图上的位置
- 只看 loss(和 PPL)
- 仪表:开局对 ln V、梯度范数、最大 logit、spike score
- 公开 benchmark
- n-gram 去污染 + 干净子集
- 换一套没见过的题 / 按时间切分
- 交换性置换检验(可证检测)
- 非公开题 + 第三方预先定好的评测集
- 三层可信度 + 口径核对
- 多种子、信噪比
- 平滑指标 + 两步预测
一句话
仪表的阈值要拿自己的 run 校准:报警的 run 里有多少真的变坏,没报警的里有没有漏网;差距小于噪声底线,就不下结论。
下一站
这一章的三件工具——训练仪表、分数与污染、信噪比——到这里都用过了。下一章去读别人的前沿技术报告:C15 前沿解剖。
🔍 为什么不把「最终 loss 变差」本身当报警?
因为它来得太晚:最终 loss 要训完才有,而且只能和参照比。仪表的价值在于训练中途就能看、并且带自己的刻度(ln V、logit 的量级)。这张表把最终结果拿来做的,是反过来检验仪表:哪些规则能提前抓住后来变坏的 run。大模型训练里,这一步对应的是用许多小规模、短步数的 run 校准监控阈值,再把阈值用到正式训练上(OLMo 2 的 spike score 就是这样用的)。