图 1:本文封面,loss 突刺的三条成因线与恢复流程。
先说明属性:这是一篇经典题解析,题目出自本地历史面试资料整理,与任何公司的当前招聘无关。loss 突刺(loss spike)指的是训练过程中 loss 曲线在平稳下降时突然向上冲出一根尖峰。这道题考的从来不是名词解释,而是你把一次训练事故当成系统工程问题来处理的能力:成因分几层、先查什么、怎么恢复。
一句话结论:突刺是数值稳定性事故,成因集中在数据、学习率、梯度数值三条线;处理原则是先回滚到突刺前的 checkpoint 稳住现场,再分头排查。
突刺为什么值得单独当回事?
它不只是曲线上难看。轻的时候,模型要花大量训练步才能爬回突刺前的水平,等于白烧一段算力;重的时候 loss 再也降不下来,整个训练跑废。这不是理论担忧:2022 年发布的 GLM-130B 技术报告(arXiv:2210.02414)把 loss 突刺与发散列为训练百亿规模模型时最突出的工程挑战,并提到同期的 OPT-175B 靠人工跳过数据段、调整超参数硬扛,BLOOM-176B 用了 embedding norm 技术压住不稳定。也就是说,一线大模型团队都在和同一根刺搏斗。
成因分三层,排查也按这三层走。
数据层:某个 batch 混入脏样本——乱码、超长文本、标注错误——瞬时算出一个离谱的损失和梯度。特征是突刺往往单步出现、随后自己回落。优化层:学习率峰值过高或 warmup 太短,模型在损失曲面的陡峭区域迈出过大的一步,轻则震荡重则弹飞。数值层:梯度爆炸或混合精度上溢。GLM-130B 的报告里有一个很值的记住的观察:训练崩溃之前,梯度范数(grad norm)往往提前几步就飙出尖峰,而且异常梯度经常来自嵌入层——他们最终用嵌入层梯度收缩(系数取 0.1)抹掉了绝大多数突刺。这给了排查一个关键抓手:grad norm 是比 loss 更早的报警器。
为什么模型越大越容易中招?小规模训练里梯度噪声会被平均掉,而出问题的条件——超大 batch 下梯度估计趋于平稳、部分参数长期得不到有效更新、混合精度数值范围紧张——在百亿规模上会同时出现,任何一层数值失控都会被后续的连乘放大成整根尖刺。GLM-130B 的最终训练跑也只靠继续收缩嵌入层梯度就压住了后期三次发散,说明这类事故大多数时候可恢复,前提是你有高频 checkpoint 和正确的排查顺序。
用最小实验看懂「谁先有信号」。
一段玩具代码(Node.js 22.15.0,node spike.js):让参数沿梯度稳定下降,第 6 步注入一个 50 倍梯度的脏 batch,对比不做梯度裁剪和把梯度范数裁到 1 的两种跑法:
let w = 1.0, lr = 0.1;
const target = () => 0.5 * w * w; // 玩具损失,最优点在 w=0
function run(clip) {
w = 1.0;
const log = [];
for (let step = 1; step <= 12; step++) {
const dirty = step === 6; // 第 6 步混入异常 batch
const g = w * (dirty ? 50 : 1);
const gn = Math.abs(g);
const gg = clip && gn > 1 ? g / gn : g; // 梯度范数裁剪到 1
w -= lr * gg;
if (step >= 5 && step <= 8)
log.push(`步${step} loss=${target().toFixed(3)} |g|=${gn.toFixed(1)}`);
}
return log.join(' ');
}
console.log('不裁剪:', run(false));
console.log('裁剪 :', run(true));
实测输出:
不裁剪: 步5 loss=0.174 |g|=0.7 步6 loss=2.789 |g|=29.5 步7 loss=2.259 |g|=2.4 步8 loss=1.830 |g|=2.1
裁剪 : 步5 loss=0.174 |g|=0.7 步6 loss=0.120 |g|=29.5 步7 loss=0.097 |g|=0.5 步8 loss=0.079 |g|=0.4
不裁剪时第 6 步 loss 从 0.174 冲到 2.789——一根教科书式的刺;裁剪后同一根 29.5 的梯度尖峰被压平,loss 继续平滑下降。注意两种跑法第 6 步的 |g| 都是 29.5:监控 grad norm 能提前看到事故,裁剪则让事故不演变成灾难。
图 2:三层成因、定位三问与四步恢复流程。
面试现场的答题结构。
先给定义和危害,再把成因拆成数据、学习率、梯度数值三层各举一例,然后讲定位三问:突刺是单步还是持续、对应 batch 数据是否异常、同一时刻 grad norm 是否飙升——三问分别指向三条成因线。最后给恢复流程:回滚到突刺前的 checkpoint,跳过可疑数据段,以更小学习率重启并观察曲线确认收敛;长期手段是梯度裁剪、合理 warmup、数据清洗,混合精度场景还要检查数值范围。如果追问「怎么提前防」,就落到 GLM-130B 那条经验上:盯 grad norm 这个先行指标。你在训练里遇到过 loss 突刺吗?最后定位到的是数据问题还是数值问题?欢迎聊聊。