从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 35 分钟 页内实验 ×3
C8 稳定性:放大后为什么会炸 第 3 课

开着梯度裁剪,为什么还会 loss spike?

loss spike:裁剪管不住的那一跳
PaLM 540B 开着梯度裁剪仍出现约 20 次 spike,回滚跳数据能躲过,可同一批数据换一个更早的 checkpoint 就不 spike:病根是数据 × 参数状态。裁剪只限制每一步走多远,管不住 logit 被养到多大;logit 尺度为 M 时,同一步让分差变化 M 倍,M 到了上千,一步普通的更新就能让 softmax 翻转。该盯的是状态:梯度范数趋势、注意力 logit、log Z。
❓

本课一问:Pre-LN 用上了,warmup 做了,梯度裁剪也开着。为什么大模型训练到一半,loss 还会突然跳上去?

这一课先不碰:怎么把 logit 直接按住(第 4 课);低精度下的溢出(C9)。这一课只回答「spike 从哪来、该盯什么」。

从已有出发

从已有出发 · 训练的一步(点任一环节看它在 Qwen/Qwen3.8-27B 上有多大) 本课本章后面的课
从已有出发 · 累计数据流 点已学环节看形状与参数
解码层

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 就是这么做的:

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案只靠梯度裁剪;spike 了就回滚、跳过那段数据
PaLM 540B §5.1 原文事实数字
训练中出现 loss spike 的次数(梯度裁剪开着)约 20 次
发生时间极不规则,有时在训练后期;小模型没出现
处理办法从 spike 开始前约 100 步的 checkpoint 重启,跳过约 200–500 个 batch
处理后同一位置不再 spike
对照实验spike 附近的那批数据,放到更早的 checkpoint 上训:不 spike
原文结论spike 只在「特定数据 batch × 特定参数状态」的组合下出现
🎯

试三件事:① 先在表格里猜 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

把上面那块面板的公式逐项拆开:

两候选之间的注意力:loss 对「分差比例」的梯度
= − ·
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
步长有上限——SGD 下来自裁剪(‖Δθ‖ ≤ η·c),Adam 下来自它自己的归一化(C5 第 6 课:β₂ = 0.95 时每个参数约 0.447η);无论哪种,Δt 都有上限,但都管不到 M。M 大时悬崖宽度只有 3.98/M:M = 1,000 时是 0.004,任何一步普通的更新都跨得过去。

这个斜率公式是直接求导的结果 。还有一层:Adam 本来就把单步限制住了——C5 第 6 课算过,尖峰梯度进来时 Adam 每个参数最多走约 0.447η(β₂ = 0.95)。spike 不是「一步走太远」,是「走到了悬崖边」;跨过悬崖之后的那一步,梯度范数会变成 M 的量级,裁剪只能在它之后把它缩短。

诊断二:该盯的是哪些状态

2023 年 Wortsman 等人用小模型、高学习率复现了大模型的两类不稳定,并研究了能不能从激活与梯度范数随规模的变化趋势里提前预测它们 :

OLMo 2 从另一侧补了两条训练日志里的规律:梯度范数的 spike 常常先于 loss 的 spike;梯度范数缓慢上涨,与 spike 越来越频繁相关,最终会导致发散 。他们还找到了一种常见的导火索:长串重复的 n-gram(比如一整段 255, 255, 255……)。C5 第 6 课项目日志里的注入实验(inject_kind = repeat)用的正是「整批重复同一个 token」(那一课页内的浏览器实验是另一种注入:放大 embedding)——在我们的基线 checkpoint 上,这样一批数据的梯度范数约为正常 batch 的 160 倍(101 对 0.63,04-实践项目/experiments/EXPERIMENTS.md 的 C5 一节实测)。

真训练日志 · 我们的模型里,最大注意力 logit 是怎么长上去的
项目实测 · 最大注意力 logit 随训练怎么长

读这张图要带条件:这是 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
高学习率压力测试把学习率放大几倍,数 spikeGoogle tuning playbook:在最佳学习率的 5–10 倍上看是否失稳;Qwen3.8-Flash-Next:学习率固定在最优的 4 倍,AdamW + Qwen3.5 结构每万步 183 次 spike,Muon + Gated Residual 0 次

有了仪表,大模型报告里才能写出「全程没有不可恢复的 spike、没有回滚」:DeepSeek-V3 这样写 ,Kimi K2 写 15.5T token 全程 loss 平滑无 spike,Qwen3.8-Flash-Next 写正式训练没有一次 spike——都是自报,但每一家都在报告里专门写了自己按住了什么(第 4 课)。

证据三问

问本课的回答
① 它解决什么问题?解释「开着裁剪仍 spike」:病根在参数状态(logit 尺度),不在单步步长;给出能提前看到它的仪表
② 数学上为什么可能有效?∂ℓ/∂t = −M(1 − w):同一步带来的 loss 变化随 M 线性放大,可证 ;把两候选推广到整行 softmax,J = diag(w) − w·wᵀ 乘上 logit 尺度,结论相同
③ 实验上为什么这样判断?PaLM 的换 checkpoint 对照;Wortsman 的小模型复现;OLMo 2 的训练日志与重复 n-gram 分析;我们项目里 logit 随学习率的增长

一句话

📌
裁剪只限制每一步走多远,管不住走到了哪:logit 被一步步养大之后,一步普通大小的更新就能让 softmax 翻转——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。

你可能会问