跳到主要内容

训练跑久了会崩 — 该盯哪几个数才看得出要出事

这一章讲什么: 第 11 章那 50 步只是开头。跑到 400 步左右,分数会掉下来 —— 而且书开门就说:代码是对的也会不稳。 所以这一章教的不是一个新算法,是一门独立的手艺:训练跑起来之后,该盯哪几个数。 六个数,每一个都配了「它长什么样算正常、什么样算要出事」。

它在全书链条里的位置: 「动权重」这条路的诊断课。 第 13 章的三种补救,每一种都要靠这一章的数才判得出有没有用。

需要的基础: 第 11 章那套(优势、损失、以及那次「什么都没发生」的更新)。

顶层全景:一次 500 步的长跑,四个仪表上分别发生了什么

这一章的主走查是一次真实的长跑:原始算法、不加任何补救、跑 500 步。

步数 → 0 50 200 400 500
│ │ │ │ │
奖励 └─涨得快─┘── 收益递减 ────┼───────────────────┼─ **明显下滑** ─┘
准确率 15% ───→ 40% ─────────────┼── 停在 30%–40% ───┼─ **明显下滑**
熵 ── 低而平(行为偏确定) ──┼─ **明显上升** ────┴──────────────
优势标准差 ── 一直没有消失 ────────┴──────────────────────────────────

图说:四条线要一起读。约 200 步那次熵上升单独看像要塌,
但配上「奖励还在涨、优势标准差没消失」,书判成**还算健康的探索**。
而约 400 步那次下滑是真的出事了 —— 第 13 章去修它。

另外配两组小对照(它们是这一章所有数里最好记的):

奖励 [1, 1, 0, 0] → 优势 [0.8659, 0.8659, −0.8659, −0.8659] → 标准差 **0.9998**
奖励 [0, 0, 0, 0] → 优势 [0, 0, 0, 0] → 标准差 **0.0000**

1. 先接受一件事:代码是对的,它也会崩

这一章的定位很特别 —— 它是全书唯一一章以失败为主线的内容。

第 11 章的结论是「50 步,15.2% → 47.4%」。这一章开门就说另一半1:

这一章要讨论:除了奖励和准确率之外还该盯哪些数、怎么早点发现失效、 以及为什么训练在代码「正确」的情况下也会变得不稳。

书还给了两条免责声明,必须原样保留。

第一条,关于这一章所有实验的可信度2:

这些例子来自真实实验,但要谨慎解读 —— 要下强结论, 每个实验都得重复很多次再取平均,因为采样和优化里的随机性会让不同次运行差别明显。 不过这些例子足以说明主要的想法和相关的取舍。

——这条声明该被记住,它同样适用于第 08、09 章那两张表。

第二条,关于这一章能不能跳3:书自己说这一章可以跳过,第 8 章不依赖它。 (我们不建议跳。这一章是全书唯一给「失败现场」的地方,而失败现场在论文里几乎见不到。)

那次长跑的结论

书跑了一次 500 步、不加任何补救的训练,结论是4:

阶段发生了什么
前约 50 步涨得快 —— 和第 11 章一致
之后收益递减
约 400 步平均奖励和评测准确率明显下滑

书排除了一个看起来很自然的解释4:

有人会猜:是不是后面抽到的训练题更难? 但这解释不了评测准确率的下滑 —— 因为评测始终是在同一批 500 道题上算的。

——这个排除法本身值得学:变的那一侧不能解释不变的那一侧出的问题。 所以问题出在算法本身:原始的 GRPO 公式在长跑中不够稳。

2. 第一层:四个基础的数

先看训练时默认就会记下来的四个数,以及每一个该怎么读5:

该看什么
损失只当健全性检查 —— 书说和预训练比,这个值本身信息量不大;应当大致平稳,大的尖峰值得担心
平均奖励应当上升 —— 这是主表
平均回答长度初期应当变长,而且理想情况下伴随准确率提升
评测准确率最终目标,但默认不在训练中算

三处要展开说。

第一,为什么损失在这里不重要? 第 11 章第 5 节已经讲过一半: reward_avg=0 的步骤损失接近零,只是因为这一组回答分数相同。 书在这里把话说得更死:和预训练相比,这个损失值本身信息量小,主要就是个健全性检查。

第二,平均奖励升到 1.00 反而是坏消息。 这条最反直觉,书写得很清楚6:

原则上,平均奖励等于 1.00 意味着采出来的回答全都对了,这是我们想要的; 但它同时意味着训练信号消失了。 到那个时候,继续训下去多半没用,早点停下来能省时间和资源。

为什么会这样,第 11 章第 1 节已经给了机制: 全对 ⟹ 优势全为零 ⟹ 权重一动不动。 ——所以「奖励刷满」和「模型学废了」在数据上长得一模一样:都是零梯度。

第三,评测准确率为什么默认不算? 因为在训练中途算它会大幅拖慢训练; 书给的做法是训练之后单独跑一遍第 05 章那个评测脚本7

3. 第二层之一:优势的均值和标准差

这一节把第 11 章那条性质,做成一个能长期盯着的仪表。

先说均值。它没有信息,但它有用8:

按 GRPO 的算法,优势的均值恒等于零。 所以这个数主要是一个健全性检查 —— 它要是漂离了零,说明实现有 bug。

——这是一条可以直接抄走的工程习惯:找一个「理论上必然等于某个值」的量,专门盯着它。 它平时毫无信息,出问题时第一个报警。

真正有信息的是标准差。 所谓标准差,就是一组数彼此差得有多开: 全都一样时是 0,差得越开越大。

书给的四档读法9:

标准差含义
接近 1信号缩放得好,更新通常稳定
很小学习信号在消失 —— 常见于奖励塌缩的时候
很大更新过于尖锐,可能把训练搞崩
等于 0极端情形:所有奖励相同 ⟹ 优势全同 ⟹ 权重完全不更新

两组实测把这张表钉死了10:

奖励 [1, 1, 0, 0]
→ 优势 [0.8659, 0.8659, −0.8659, −0.8659]
→ 均值 0.0000,标准差 **0.9998** ← 接近 1,健康

奖励 [0, 0, 0, 0] (全 1 也一样)
→ 优势 [0, 0, 0, 0]
→ 均值 0.0000,标准差 **0.0000** ← 这一步白跑了

第 11 章第 4 节那次「什么都没发生」的更新,在这张仪表上就是右边这一行。 ——那时我们只看到了一次;现在有了一个能一直盯着的数。

4. 第二层之二:熵 —— 模型挑下一个词时有多不确定

这是这一章唯一一个全新的概念,值得单开一节。

书就地下的定义11:

熵衡量的是:模型在生成下一个词时有多不确定。

熵的高低意味着什么
可能性摊在很多个词上 —— 倾向探索
可能性集中在一个词上 —— 模型越来越确定;也可能是训练塌缩的信号(它不再探索,反复吐同样的东西)

怎么算?书给的做法一句话12: 把每个词的可能性乘上它的对数概率,全部加起来,再取负。

——注意这里又用到了第 09 章那套对数概率。它在这本书里出现了第三次。

一个 7 个词的玩具例子,把它算到底

书用一个只有 7 个词的假词表演示,每一步的数都印出来了13:

原始分数 logits = [0.6667, −2.0000, 1.3333, −0.0000, −0.6667, 2.0000, −1.3333]
│ 换算成可能性(第 07 章那道 softmax)
▼ [0.1295, 0.0090, 0.2522, 0.0665, 0.0341, 0.4912, 0.0175]
│ ↑ 第 6 个最大(0.4912),但它没有独占 —— 第 3 个还有 0.2522
│ 每个可能性 × 它的对数概率,求和,取负
▼ 熵 = **1.3700**

这个 1.3700 该怎么读?书给了一把刻度尺14:

含义
约 0–0.5一个词独占,模型高度自信、近乎确定性
约 1–2可能性分摊在一小撮词上 —— 稳定训练时的典型状态
远大于 2摊得很开,模型高度不确定、接近随机

上限是多少?书也给了:对词表里的词数取一次对数。 这个玩具例子里词表只有 7 个词, 所以上限是 log(7) = 1.9459 —— 而算出来的 1.3700 已经相当接近上限了。

——注意这条:熵的绝对值只有配上「词表里有多少个词」才有意义。 真实模型的词表有 15 万个词,上限会大得多。

书顺带教了一个小换算15:取对数的逆运算能把对数概率变回可能性。 所以手上只有对数概率时,不必重新算一遍,直接换算回去就行。

5. 落点:每个指标只讲故事的一部分

这一节是这一章存在的理由,而且它是通过一次真实的判断示范出来的。

那次 500 步长跑里,熵的走势是这样的16:

早期:熵低而平 ⟹ 模型行为偏确定性
约 200 步之后:**熵明显上升** ⟹ 下一个词的可能性摊开了,模型行为更随机

单看这一条,该报警吗? 熵上升可以是「开始探索」,也可以是「开始跑飞」。 书没有单看,它把三个数放在一起判17:

一起看的三件事当时的状态
在涨
平均奖励也在涨
优势的标准差没有消失

⟹ 书的判断:这更像还算健康的探索,而不是塌缩。

而且它还找了第四个旁证17:这与评测准确率停在 30%–40% 是一致的 —— 「不算好,但也没接近零」。

——这就是这一章的手艺:任何单一指标都可以被两种相反的故事解释, 只有几个指标互相印证,才能定性。

书自己的总结句值得原样记住18:

每个指标只讲了故事的一部分,它们必须放在一起、放在上下文里看,才有用。

顺带一条口径,书在练习答案里给了19:回答长度这个指标本身也要看清是在哪儿量的。 同一个 base 模型,在 10 道题的小子集上平均 97.30 个小块,在全部 500 道题上是 96.74; 而官方推理版在小子集上是 891.80,在全部 500 道题上是 1361.21 —— 小子集上的数和全量上的数差得很远,尤其对推理模型。

作者的判断与证据

说法性质
那次 500 步长跑的四条曲线真实实验,但只跑了一次 —— 书自己在开头声明了这一点
两组优势与标准差(0.9998 / 0.0000)书里印出来的实测
7 个词那个熵的例子(1.3700)书里印出来的实测
「约 400 步下滑是算法不稳造成的」作者的推断,措辞是「一个可能的原因」;但他排除了「后面的题更难」这个解释,理由很硬
损失在这里信息量不大作者的判断,并给了对照:预训练时它更有用
「奖励升到 1.00 意味着信号消失」从机制推出来的,不是观察
优势均值恒为零算法的性质,不是观察
标准差那四档读法作者给的经验刻度,没有列出处
熵那三档刻度作者给的经验刻度,同样没有出处
「200 步后熵上升是健康探索」作者的综合判断,他明说了是把三个指标放在一起看才这么判的
表 B.1 那四个长度书在练习答案里给的实测

判断(我们的,不是书里的): 这一章教的其实是一种通用的调试姿势,和推理模型没什么关系: 先找一个「理论上必然等于某个值」的量当哨兵(这里是优势的均值), 再找一个「有信息但会两义」的量当主表(标准差、熵), 最后用互相印证来定性。 这套姿势在任何训练、任何系统监控上都成立。 如果错,会错在: 我们没有从书里找到「按这套读法提前发现了某次故障」的正面案例 —— 书是在事后解释曲线,不是在事前预警。 一套诊断法有没有预测力,和它能不能解释历史,是两件事。

边界与局限

  1. 每个实验只跑了一次。 书自己在开头就声明了:要下强结论必须重复多次取平均。
  2. 那些刻度(标准差接近 1、熵在 1–2)是经验值。 书没有给出处,也没有说在多少个模型上验证过。
  3. 熵的绝对值取决于词表里有多少个词。 玩具例子的上限是 log(7);真实模型完全不是一个量级 —— 书没有给真实模型上的熵取值范围。
  4. 评测准确率默认不在训练中算。 所以那条曲线是每 50 步才有一个点,不是连续的。
  5. 这一章只诊断,不治疗。 三种补救在第 13 章 —— 其中一种(限制单次更新的幅度)真的把这次下跌治住了,另外两种各自以自己的方式失手。
  6. 书说这一章可以跳过。 我们不同意,但读者应当知道作者本人的态度。

可带走的

  1. 代码写对了,训练照样会崩。 这不是安慰话,是这一章的前提。
  2. 不要只看一个数。 任何单一指标都能被两种相反的故事解释。
  3. 损失在这类训练里只当健全性检查 —— 它应当大致平稳,大的尖峰值得担心, 但它的绝对数值不值得深究。
  4. 平均奖励是主表,但它升到 1.00 反而是坏消息 —— 全对意味着学习信号消失了, 该早停省钱。
  5. 找一个「理论上必然等于某个值」的量当哨兵。 这里是优势的均值(恒为零)—— 它平时毫无信息,一漂就说明代码有 bug。
  6. 真正有信息的是优势的标准差: 接近 1 说明信号缩放得好;很小说明学习信号在消失; 很大说明更新太尖锐;等于 0 说明这一步完全白跑。
  7. 熵量的是「模型挑下一个词时有多不确定」。 算法:每个可能性乘它的对数概率,求和取负。
  8. 熵的刻度:约 0–0.5 是近乎确定;约 1–2 是稳定训练的典型状态;远大于 2 接近随机。 上限是「对词表里的词数取一次对数」—— 所以脱离词表谈熵的绝对值没有意义。
  9. 熵走低不一定是好事 —— 它可能意味着模型不再探索、开始复读。熵走高也不一定是坏事。 判断哪一种,要看奖励和优势标准差有没有跟着动。
  10. 排除法要用对:变的那一侧解释不了不变的那一侧出的问题。 评测题始终是同一批 500 道,所以准确率下滑不可能是「后面的题更难」。
  11. 报回答长度时要说清是在多少道题上量的 —— 小子集和全量能差出好几百个小块。

原文地图

主题原书章原文位置
这一章要讲什么 · 代码对了也会不稳7 Improving GRPO for reinforcement learningtext/59-ch07-7-improving-grpo-for-reinforcement-learning.txt:42(搜「even when the code is "correct."」)
实验要重复多次才能下强结论7.1 Improving GRPOtext/60-ch07-01-7-1-improving-grpo.txt:20(搜「repeated multiple times and the results averaged」)
这一章可以跳过同上text/60-ch07-01-7-1-improving-grpo.txt:33(搜「the next chapter does not depend on it」)
四个基础指标与损失怎么读7.2 Tracking GRPO performance metricstext/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:325(搜「The four metrics tracked」) · :331(搜「the loss value itself is less informative」)
奖励升到 1.00 反而是坏消息同上text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:337(搜「the training signal has disappeared」)
那次长跑的结论与排除法同上text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:349(搜「diminishing returns after approximately fifty steps」)
评测准确率默认不算同上text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:368(搜「significantly slows down training」)
优势的均值恒为零7.3 Tracking more advanced GRPO performance metricstext/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:110(搜「their mean is always zero」)
标准差的四档读法同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:116(搜「Values close to 1 indicate a well-scaled gradient signal」)
两组实测同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:104(搜「std = 0.9998」) · :145(搜「std = 0.0000」)
熵的定义同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:175(搜「how uncertain the model is when generating the next token」)
熵怎么算同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:250(搜「multiplying each probability by its log-probability」) · :298(搜「entropy = torch.sum」)
7 个词的玩具例子同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:201(搜「logits = torch.tensor」) · :315(搜「0.1295」) · :316(搜「Entropy: tensor(1.3700)」)
熵的三档刻度与上限同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:275(搜「behaves almost deterministically」) · :281(搜「log(7) = 1.9459」)
对数的逆运算同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:328(搜「is the inverse of torch.log()」)
长跑里熵的走势与综合判断同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:521(搜「the entropy is relatively low and fairly flat」) · :527(搜「still somewhat healthy exploration rather than collapse」)
总结句同上text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:533(搜「each metric tells a slightly different part of the story」)
表 B.1 平均回答长度Appendix B. Exercise solutionstext/80-apx-b-appendix-b-exercise-solutions.txt:452(搜「Average number of tokens on MATH-500」) · :477(搜「97.30」) · :510(搜「1361.21」)

Footnotes

  1. 出处:「7 Improving GRPO for reinforcement learning」第 42 段(text/59-ch07-7-improving-grpo-for-reinforcement-learning.txt:42,搜「even when the code is "correct."」)。

  2. 出处:「7.1 Improving GRPO」第 20 段(text/60-ch07-01-7-1-improving-grpo.txt:20,搜「repeated multiple times and the results averaged」)。

  3. 出处:「7.1 Improving GRPO」第 33 段(text/60-ch07-01-7-1-improving-grpo.txt:33,搜「the next chapter does not depend on it」)。

  4. 出处:「7.2 Tracking GRPO performance metrics」第 349 段(text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:349,搜「diminishing returns after approximately fifty steps」)。那句排除法的原话是:「后面的训练题更难」这个解释说明不了评测准确率的下滑,因为评测是在同一批 500 道 MATH-500 题上算的 2

  5. 出处:「7.2 Tracking GRPO performance metrics」第 325 段(text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:325,搜「The four metrics tracked」)是图 7.4 的说明(那张图上还画了一条移动平均线,用来在噪声很大的曲线里看趋势);第 331 段(text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:331,搜「the loss value itself is less informative」)是对损失和回答长度的解读,里面也提到了那次约 400 步之前的下滑,以及「训练中段那几个较大的尖峰有点让人担心」。

  6. 出处:「7.2 Tracking GRPO performance metrics」第 337 段(text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:337,搜「the training signal has disappeared」)。

  7. 出处:「7.2 Tracking GRPO performance metrics」第 368 段(text/61-ch07-02-7-2-tracking-grpo-performance-metrics.txt:368,搜「significantly slows down training」)。

  8. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 110 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:110,搜「their mean is always zero」)。原文明说:因为 GRPO 算优势的方式,它的均值总是零,所以这个量主要是个健全性检查。

  9. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 116 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:116,搜「Values close to 1 indicate a well-scaled gradient signal」)。

  10. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 103–104 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:104,搜「std = 0.9998」)与第 144–145 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:145,搜「std = 0.0000」)。书说明了奖励全为 1 时结果也一样。

  11. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 175 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:175,搜「how uncertain the model is when generating the next token」)。

  12. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 250 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:250,搜「multiplying each probability by its log-probability」);代码那一行在第 298 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:298,搜「entropy = torch.sum」)。

  13. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 201 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:201,搜「logits = torch.tensor」)是那七个原始分;换算出来的可能性与熵在第 315 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:315,搜「0.1295」)与第 316 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:316,搜「Entropy: tensor(1.3700)」)。

  14. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 275 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:275,搜「behaves almost deterministically」)到第 281 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:281,搜「log(7) = 1.9459」)。

  15. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 328 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:328,搜「is the inverse of torch.log()」)。

  16. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 521 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:521,搜「the entropy is relatively low and fairly flat」)。同一段还提醒:调高采样温度会让采出来的回答更多样,但那并不改变模型本身的熵

  17. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 527 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:527,搜「still somewhat healthy exploration rather than collapse」)。那句「不算好,但也没接近零」也在这一段。 2

  18. 出处:「7.3 Tracking more advanced GRPO performance metrics」第 533 段(text/62-ch07-03-7-3-tracking-more-advanced-grpo-performance-metr.txt:533,搜「each metric tells a slightly different part of the story」)。

  19. 出处:表 B.1,「Appendix B. Exercise solutions」第 452 段(text/80-apx-b-appendix-b-exercise-solutions.txt:452,搜「Average number of tokens on MATH-500」),四个数分别在第 477 段(text/80-apx-b-appendix-b-exercise-solutions.txt:477,搜「97.30」)与第 510 段(text/80-apx-b-appendix-b-exercise-solutions.txt:510,搜「1361.21」)附近。注意这几个数和第 11 章表 6.1 里的 78.85 / 1369.79 不完全一致 —— 它们来自不同的运行与设备,不要混着比。