开着梯度裁剪,为什么还会 loss spike?
本课一问:Pre-LN 用上了,warmup 做了,梯度裁剪也开着。为什么大模型训练到一半,loss 还会突然跳上去?
这一课先不碰:怎么把 logit 直接按住(第 4 课);低精度下的溢出(C9)。这一课只回答「spike 从哪来、该盯什么」。
从已有出发
C5 第 6 课的全局范数裁剪 g ← g·min(1, c/‖g‖):梯度太长就按比例缩短,方向不变。那一课纠正过一个误解——「开了裁剪就不会 spike」——并留下 PaLM 的例子。第 2 课结尾又留下一个现象:我们的 Pre-LN 模型不 warmup、学习率 1e-2 时没崩,最大注意力 logit 却从 0.64 涨到了 1289。这两条线索在这一课会合。例句这一课的用法:只看「给了」这一行注意力在两个候选之间的取舍——分差怎么来的不重要(下面是可调的教学参数),要看的是同样一步更新,在不同的 logit 尺度下会把这个取舍推到哪里。
先自己设计:spike 了就回滚,跳过那段数据
最直接的工程做法:盯着 loss,一旦 spike,就退回之前的 checkpoint,跳过出事的那几百个 batch 接着训。PaLM 就是这么做的:
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
| PaLM 540B §5.1 原文事实 | 数字 |
|---|---|
| 训练中出现 loss spike 的次数(梯度裁剪开着) | 约 20 次 |
| 发生时间 | 极不规则,有时在训练后期;小模型没出现 |
| 处理办法 | 从 spike 开始前约 100 步的 checkpoint 重启,跳过约 200–500 个 batch |
| 处理后 | 同一位置不再 spike |
| 对照实验 | spike 附近的那批数据,放到更早的 checkpoint 上训:不 spike |
| 原文结论 | spike 只在「特定数据 batch × 特定参数状态」的组合下出现 |
把「状态」拆成一个能算的量:这一行注意力 logit 的尺度 M。下面四块面板里,同一批数据推着参数走的是同样大小的一步(已被裁剪限制过),唯一的区别是模型走到这里时,logit 已经被养到多大。
公式现算:w = σ(M·t),ℓ = softplus(−M·t),∂ℓ/∂t = −M·(1 − w);悬崖宽度 = 权重从 12% 升到 88% 所需的 t 区间 = 2·ln(0.88/0.12)/M。四块面板共享同一坐标;loss 纵轴上限截到 12。
试三件事:① 先在表格里猜 M = 1,000 那一行,再点「揭晓」;② 把 t₀ 拖到 0.005、Δt 拖到 0.01:四块面板里分差都只被推过 0 一点点,M = 5.66 那块的权重只变了一两个百分点,M = 1,000 那块从 99% 以上翻到 1% 以下——悬崖宽度只有 0.004,任何跨过 0 的一小步都是整个翻转;③ 把 t₀ 拖到 0.08、Δt 放回 0.03:这回 M = 1,000 那块纹丝不动,M 小的几块反而在动。悬崖只在分差接近 0 的地方;logit 大不是处处危险,而是一旦走到边上就瞬间翻过去。裁剪决定的是 Δt 的上限,决定跳多高的是 M。
诊断一:裁剪管的是步长,不是 logit
把上面那块面板的公式逐项拆开:
这个斜率公式是直接求导的结果 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条w = σ(Mt),ℓ = −ln w = softplus(−Mt),dℓ/dt = −M·σ(−Mt) = −M(1 − w)。 出处待补 。还有一层:Adam 本来就把单步限制住了——C5 第 6 课算过,尖峰梯度进来时 Adam 每个参数最多走约 0.447η(β₂ = 0.95)。spike 不是「一步走太远」,是「走到了悬崖边」;跨过悬崖之后的那一步,梯度范数会变成 M 的量级,裁剪只能在它之后把它缩短。
诊断二:该盯的是哪些状态
2023 年 Wortsman 等人用小模型、高学习率复现了大模型的两类不稳定,并研究了能不能从激活与梯度范数随规模的变化趋势里提前预测它们 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条小模型代理实验;两类不稳定、两种缓解手段在大模型上都用过。 出处Wortsman et al. 2023 §3.1 ↗需联网 :
- 注意力 logit 增长:q·k 越来越大,注意力权重塌成 one-hot、熵塌缩(ViT-22B 在 8B 规模时撞上过,第 4 课);
- 输出 logit 与 log 概率发散:输出层 logits 整体漂走,log Z 离 0 越来越远(第 4 课的 z-loss)。
OLMo 2 从另一侧补了两条训练日志里的规律:梯度范数的 spike 常常先于 loss 的 spike;梯度范数缓慢上涨,与 spike 越来越频繁相关,最终会导致发散 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条来自 OLMo-0424 的训练日志与他们的对照实验;模型越大 spike 越频繁。 出处OLMo 2 §3 ↗需联网 。他们还找到了一种常见的导火索:长串重复的 n-gram(比如一整段 255, 255, 255……)。C5 第 6 课项目日志里的注入实验(inject_kind = repeat)用的正是「整批重复同一个 token」(那一课页内的浏览器实验是另一种注入:放大 embedding)——在我们的基线 checkpoint 上,这样一批数据的梯度范数约为正常 batch 的 160 倍(101 对 0.63,04-实践项目/experiments/EXPERIMENTS.md 的 C5 一节实测)。
读这张图要带条件:这是 400 步、3.7M 参数的小模型,没有一条曲线真的 spike。但它展示了 spike 的前提怎样一步步形成——学习率越大、不 warmup、不开 QK-Norm,最大注意力 logit 长得越高;QK-Norm 开着的几条始终贴在底部。
常见误解一:「spike 是坏数据造成的,把数据洗干净就好。」PaLM 的对照说明同一批数据在早一点的状态下不 spike。OLMo 2 也写明重复 n-gram 与 spike 的关系「不是确定性的」:同一段序列可能让大模型 spike、小模型不 spike;换个数据顺序也可能不 spike。洗数据能减少导火索,治不了状态。
常见误解二:「开了裁剪就不会 spike。」C5 第 6 课埋下的伏笔在这里兑现:裁剪只限制步长;logit 尺度 M 一大,限制过的步长照样跨得过悬崖。
常见误解三:「loss 恢复了就没事。」Stas Bekman 整理的真实训练图鉴里,有快速恢复的、慢恢复的,也有恢复不完全、最后发散的;OLMo 2 说 spike 对最终效果有害,梯度范数的缓慢上涨最终会让训练发散。
现代做法:给状态装仪表
| 仪表 | 看什么 | 出处 / 例子 |
|---|---|---|
| 裁剪前的梯度范数 | 突刺先于 loss spike;缓慢上涨预示 spike 越来越频繁 | OLMo 2 §3;我们项目的日志每 5 步记录均值与最大值 |
| 逐层最大注意力 logit | 一路长到上百、上千 | Wortsman 2023;Kimi K2 §2.1;项目探针 attn_logit_max |
| 输出 logit 最大值 / log Z | 整体漂移 | Wortsman 2023;PaLM 的 z-loss |
| spike score | 偏离近 1,000 步滚动均值 7 个标准差以上的点所占比例 | OLMo 2 §3.2 |
| 高学习率压力测试 | 把学习率放大几倍,数 spike | Google tuning playbook:在最佳学习率的 5–10 倍上看是否失稳;Qwen3.8-Flash-Next:学习率固定在最优的 4 倍,AdamW + Qwen3.5 结构每万步 183 次 spike,Muon + Gated Residual 0 次 |
有了仪表,大模型报告里才能写出「全程没有不可恢复的 spike、没有回滚」:DeepSeek-V3 这样写 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条原文:we did not experience any irrecoverable loss spikes or perform any rollbacks。自报。 出处DeepSeek-V3 技术报告摘要(本地 PDF) ↗ ,Kimi K2 写 15.5T token 全程 loss 平滑无 spike,Qwen3.8-Flash-Next 写正式训练没有一次 spike——都是自报,但每一家都在报告里专门写了自己按住了什么(第 4 课)。
证据三问
| 问 | 本课的回答 |
|---|---|
| ① 它解决什么问题? | 解释「开着裁剪仍 spike」:病根在参数状态(logit 尺度),不在单步步长;给出能提前看到它的仪表 |
| ② 数学上为什么可能有效? | ∂ℓ/∂t = −M(1 − w):同一步带来的 loss 变化随 M 线性放大,可证 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条sigmoid / softmax 直接求导。 出处待补 ;把两候选推广到整行 softmax,J = diag(w) − w·wᵀ 乘上 logit 尺度,结论相同 |
| ③ 实验上为什么这样判断? | PaLM 的换 checkpoint 对照;Wortsman 的小模型复现;OLMo 2 的训练日志与重复 n-gram 分析;我们项目里 logit 随学习率的增长 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条spike 的直接因果在大模型上很难做干净的消融,多数结论来自相关性与对照。 出处待补 |
一句话
先停在这里:记住「悬崖宽度 ∝ 1/M」和「盯梯度范数趋势、注意力 logit、log Z」。
再深一层:读 Wortsman 2023 的 §3,再翻 Stas Bekman 的图鉴,把每种 spike 形状对应到本课的仪表上。
下一个缺口
病根是 logit 被一步步养大:能不能直接把它按住? → 第 4 课:怎么按住 logit?
回扣:C5 第 7 课留下的「Kimi K2 原版 Muon 下 max logit 超过 1,000」,就是本课面板里 M = 1,000 那一块;下一课讲 K2 怎么把它按回 100。
你可能会问
- 「既然跨悬崖的是正常步,为什么不直接把学习率调小?」可以,但代价是全程都慢;Google tuning playbook 的说法是:不稳定只有在它逼你用更小的学习率时才是问题。按住 logit(第 4 课)就是为了在不降学习率的前提下去掉悬崖。
- 「梯度范数的 spike 为什么常常先于 loss 的 spike?」OLMo 2 只报告了现象;一个说得通的读法是:状态已经在悬崖边时,局部斜率先变陡(梯度大),下一两步才真正翻过去(loss 跳)。这是解读,不是论文的结论。
- 这一课还没有收到真实提问;你的提问会记到
05-问答记录/C8-L3.md。