人人都会AI编程

4.4 优化器与学习率策略:AdamW、余弦退火、热身(Warmup)机制

更新时间:2026-07-09

在 4.3 节中,我们讨论了交叉熵损失如何将“接龙预测”转化为可优化的数学目标。但仅仅算出梯度还不够——对于数百亿乃至万亿参数的 Transformer,选择什么样的优化器、以什么样的节奏更新学习率,直接决定了模型是收敛到一个可用的智能体,还是在训练初期就因震荡而崩盘。本节聚焦大模型预训练中最经典的“黄金配方”:AdamW 优化器 + Warmup 预热 + 余弦退火(Cosine Annealing)。这是当前工业界从头训练基座模型的默认范式,也是你阅读任何大模型技术报告时必然会遇到的三个关键词。


一、AdamW:为什么大模型训练几乎不用 SGD?

1.1 从 Adam 到 AdamW 的关键改进

标准的随机梯度下降(SGD)对所有参数使用同一学习率,且没有动量自适应。这在 CV 的 ResNet 时代运转良好,但面对 Transformer 时暴露出严重问题:不同层、不同参数的梯度尺度差异极大。例如,Embedding 层和深层 Attention 的梯度可能相差数个数量级,统一学习率会导致某些参数更新过快,另一些则几乎不动。

Adam(Adaptive Moment Estimation) 通过维护两个状态量来解决这一问题:

  • 一阶矩(m):梯度的指数移动平均,充当“动量”;
  • 二阶矩(v):梯度平方的指数移动平均,用于自适应地缩放每个参数的学习率。

参数更新时,Adam 将学习率除以 $\sqrt{v}$ 的修正值,使得梯度历史波动大的参数获得更保守的步长,波动小的参数获得更大步长。

但原始的 Adam 存在一个工程陷阱:它把权重衰减(Weight Decay)实现为与梯度耦合的 L2 正则化。在自适应学习率的分母 $\sqrt{v}$ 作用下,正则化效果被扭曲——梯度大的参数“感觉”到的正则化被稀释,梯度小的参数则被过度惩罚。

AdamW(Loshchilov & Hutter, 2017)的核心修正极其简洁却影响深远:将权重衰减与梯度更新解耦。Weight Decay 不再混在梯度里,而是直接在参数更新步骤中以固定系数衰减参数本身。这保证了正则化强度不受历史梯度尺度的干扰。

在大模型训练中,AdamW 几乎完全取代了 Adam。你今天看到的 Llama、GPT、Qwen、DeepSeek 等所有主流模型的预训练,默认优化器都是 AdamW。

1.2 大模型预训练中的典型超参

技术报告里通常不会详细展开,但它们的默认值高度趋同:

| 超参 | 典型设置 | 说明 |
|------|---------|------|
| $\beta_1$ | 0.9 | 一阶矩衰减系数,控制动量记忆长度 |
| $\beta_2$ | 0.95 或 0.999 | 近年趋势是降低(如 0.95),因为预训练步数极长,更希望重视近期梯度 |
| $\epsilon$ | $1\times10^{-8}$ 或 $1\times10^{-6}$ | 数值稳定性常数;大模型里倾向于设大一点,避免除零或过度放大噪声 |
| Weight Decay | 0.01 或 0.1 | 对 Embedding 和 LayerNorm 通常单独设为 0(不衰减) |

实用认知:AdamW 是显存杀手。每个参数除了自身和梯度外,还要存储一阶矩和二阶矩(均为 FP32)。在 FP16/BF16 混合精度训练中(4.5 节详述),还需维护一份 FP32 的 Master Weights。这意味着 AdamW 的优化器状态占用显存约为参数量的 8–12 倍——一个 7B 模型的参数本身约 14 GB(FP16),AdamW 状态再加 28 GB 以上。这也是 DeepSpeed ZeRO、FSDP 等分布式框架必须存在的根本原因。


二、Warmup:为什么训练初期不能“猛踩油门”?

即使有了 AdamW,如果你直接将学习率拉到峰值(如 $3\times10^{-4}$),Transformer 在训练前几步几乎必定数值爆炸(Loss Spike)。Warmup 机制就是为此而生的。

2.1 原理与做法

Warmup 指在训练开始的若干步内,将学习率从一个极小值(或 0)线性或指数地提升到预设峰值。例如:

$$
lr_t = lr_{\text{peak}} \times \frac{t}{W}, \quad t \in [0, W)
$$

其中 $W$ 为 Warmup 步数。

2.2 为什么 Warmup 对 Transformer 不可或缺?

三个原因共同作用:

  1. Adam 的偏差校正初期不可靠:初始时 $m$ 和 $v$ 都被初始化为 0,需要经过数十到数千步才能积累出有代表性的统计量。Warmup 避免了在估计不稳定时迈出过大步子。
  2. 注意力层的 Softmax 饱和风险:训练初期,随机初始化的 Q/K 矩阵可能产生极大的内积值,导致 Attention Score 经过 Softmax 后进入饱和区(梯度极小)。温和的学习率让 Attention 机制有时间把数值尺度调整到合理区间。
  3. Embedding 层的稳定性:词嵌入向量在初始阶段需要缓慢脱离随机状态,过快更新会造成词汇表级的分布震荡。

2.3 工程经验:Warmup 步数怎么定?

  • 预训练:通常取总步数的 0.5%–2%。例如总训练 10000 步,Warmup 设 2000 步(2%)。对于极长训练(如 1T Token,百万级步数),绝对步数可能只有 2000–4000 步,比例会更低。
  • 监督微调(SFT):因为基座模型已经稳定,Warmup 步数可大幅减少(如 100–500 步),甚至线性预热到 5% 即可。
  • 铁律:预训练大模型时,宁长勿短。省几百步 Warmup 导致 Loss 在初期发散,后续可能需要几万步才能拉回,得不偿失。

三、余弦退火(Cosine Annealing):峰值之后的“优雅减速”

当学习率到达峰值后,如果直接保持恒定,Loss 通常会在后期剧烈震荡,难以收敛到平坦的极小值。如果采用阶梯式衰减(Step Decay),学习率的骤降又会让优化轨迹“急刹车”,损伤已学到的泛化特征。

余弦退火提供了一条平滑下降曲线:

$$
lr_t = lr_{\min} + \frac{1}{2}(lr_{\text{peak}} - lr_{\min})\left(1 + \cos\left(\frac{T_{\text{cur}}}{T_{\max}}\pi\right)\right)
$$

其中 $T_{\text{cur}}$ 是当前已进行衰减的步数,$T_{\max}$ 是衰减周期总步数(通常等于总训练步数)。

3.1 为什么大模型偏爱余弦退火?

  • 前期慢降:在训练中期,学习率仍保持较高水平,允许模型跨越浅层局部最优,充分探索参数空间;
  • 后期快降:接近收敛时快速进入精细调整阶段,稳定在最优邻域;
  • 无需人工设置衰减节点:阶梯式衰减需要调“第几步降到多少”,而余弦退火只需设定峰值、谷值和总步数,自动化程度更高。

3.2 峰值、谷值与周期设置

  • 峰值学习率($lr_{\text{peak}}$):基座预训练通常在 $1\times10^{-4}$ 到 $3\times10^{-4}$ 之间。模型越大,绝对值往往倾向越小(如 GPT-3 175B 用 $6\times10^{-4}$ 配合大 Batch,而 7B 小模型可能用到 $3\times10^{-4}$ 甚至更高)。
  • 最小学习率($lr_{\min}$):通常设为峰值的 10%(如峰值为 $3\times10^{-4}$,则谷值为 $3\times10^{-5}$),或一个绝对小值。也有实践在最后 10% 步数保持恒定最小值,避免过度衰减导致更新停滞。
  • 周期对齐:余弦衰减的 $T_{\max}$ 必须与实际总训练步数严格对齐。如果计划训练 300B Token,但调度器周期只设到 100B Token,后续 200B Token 将在极低学习率下“爬行”,造成严重的欠拟合(Underfitting)。

实用认知:近年有些长周期训练(如持续预训练)会采用 Cosine with Restarts(余弦重启),即衰减到谷底后迅速拉回峰值再降。但在从头预训练千亿级基座模型时,单次余弦仍是主流——重启带来的冲击对超大规模参数稳定性过于危险。


四、完整学习率曲线的工程全貌

把三者拼起来,一次标准大模型预训练的学习率曲线如下:

学习率
  ↑
lr_peak |       ╭──────╮
        |      /        \
        |     /          \
        |    /            \
        |   /              \
lr_min  |──/                ═════════
        |
        +────────────────────────────→ 训练步数
        ↑      ↑                  ↑
       Warmup  峰值              结束
       (线性)   (余弦衰减)        (常数尾部/结束)

在工程配置文件中(如 Megatron-LM 或 Hugging Face Trainer),你通常会看到类似这样的参数块:

optimizer: adamw
lr: 3.0e-4
min_lr: 3.0e-5
weight_decay: 0.1
warmup_steps: 2000
lr_decay_style: cosine
lr_decay_iters: 600000  # 总训练步数

五、与分布式训练和混合精度的耦合

5.1 学习率与 Batch Size 的缩放

当使用数据并行并将全局 Batch Size 从 512 扩大到 4096 时,梯度估计的噪声降低,理论上可以使用更大的学习率。大模型社区通常遵循 Linear Scaling 经验:Batch Size 扩大 $k$ 倍,初始学习率也近似扩大 $k$ 倍(在一定范围内)。但这并非绝对真理——当 Batch Size 已经极大(如 4M Token)时,过犹不及。

5.2 混合精度下的 AdamW(衔接 4.5 节)

在 FP16/BF16 混合精度训练中,AdamW 的更新计算实际在 FP32 Master Weights 上完成。这意味着:

  • Weight Decay 施加在 FP32 主参数上,精度更高;
  • 一阶矩和二阶矩通常也保持 FP32,避免低精度下的状态抖动。

这为 4.5 节的主题埋下伏笔:混合精度不只是“用 FP16 省显存”这么简单,它与优化器状态的管理、梯度缩放(Gradient Scaling)、数值稳定性共同构成了一套系统工程。


六、小结

AdamW、Warmup 和余弦退火构成了现代大模型预训练的“优化铁三角”

  • AdamW:用自适应学习率+解耦权重衰减,驯服 Transformer 各层参数量级差异巨大的梯度;
  • Warmup:在训练初期为 Adam 的偏差校正和 Attention 数值稳定性争取时间,避免 Loss 爆炸;
  • 余弦退火:以平滑、可预测的节奏降低学习率,兼顾中期的充分探索与后期的精细收敛。

关键 takeaway:

  1. AdamW 状态是显存大头:优化器状态占显存通常超过参数本身,这是你做显存预算时不可忽视的项;
  2. Warmup 是保险丝:预训练时不要轻易缩减 Warmup 步数,它是整个训练曲线平稳启动的开关;
  3. 余弦周期必须与总步数锁死:衰减周期错配是长周期训练中常见的隐性灾难;
  4. 学习率是最值得仔细调的超参之一:在算力允许范围内,用小规模实验(如 1/100 数据量)快速扫描峰值学习率,能极大降低正式训练的风险。

在 4.5 节中,我们将继续深入训练稳定性主题,讨论梯度爆炸与消失、混合精度训练、梯度裁剪与检查点策略——这些机制与 AdamW 和余弦退火共同守护着千亿参数在数月训练中的数值安全。