> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/llm_internals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/llm_internals/di-er-bu-fen-xun-lian-pian/06_training_techniques/6.2_lr_schedule.md).

# 6.2 学习率调度：为什么需要先预热再衰减

学习率可能是 Transformer 训练中最关键的超参数。6.1 节的每一条更新公式里，$\eta$ 都只是写在最前面的一个常数——Adam 自适应的是各参数之间的相对步长，这个全局尺度并不在它的调节范围内。6.1.3 已经给出它的物理含义：Adam 下单步更新的幅度上界约为 $\eta$，所以“调学习率”调的是每个参数每步能挪多远。本节先写清原始论文那条“先预热再衰减”的曲线，再说明预热与衰减各自在防什么，最后换成当代模型实际在用的三种调度，并给出峰值学习率怎样随模型规模改变。

## 6.2.1 原始调度公式

Transformer 的学习率调度公式为：

$$\text{lr} = d\_{\text{model}}^{-0.5} \cdot \min(\text{step}^{-0.5}, \text{step} \cdot \text{warmup\_steps}^{-1.5})$$

这个公式通过 min 函数的“切换”实现两个阶段的平稳过渡。在 step = warmup\_steps 时，两项相等：

$$\text{warmup\_steps}^{-0.5} = \text{warmup\_steps} \cdot \text{warmup\_steps}^{-1.5}$$

因此：

* **预热阶段**（step < warmup\_steps）：$\text{step} \cdot \text{warmup\_steps}^{-1.5}$ 较小，学习率按此项线性增长：$\text{lr} \propto \text{step}$
* **衰减阶段**（step ≥ warmup\_steps）：$\text{step}^{-0.5}$ 较小，学习率按此项逐渐衰减：$\text{lr} \propto \text{step}^{-0.5}$

原始论文使用 warmup\_steps = 4000。峰值出现在 step = warmup\_steps，此时学习率为 $d\_{\text{model}}^{-0.5} \cdot \text{warmup\_steps}^{-0.5}$；对于 d\_model = 512、warmup\_steps = 4000，峰值约为 $512^{-0.5} \cdot 4000^{-0.5} \approx 6.99 \times 10^{-4}$。$512^{-0.5} \approx 0.0442$ 只是模型维度缩放因子，不是最终峰值学习率。

代进几个步数，这条曲线的形状就具体了：

| step |                   1 |                 100 |               1,000 |               4,000 |               8,000 |              16,000 |             100,000 |
| ---- | ------------------: | ------------------: | ------------------: | ------------------: | ------------------: | ------------------: | ------------------: |
| lr   | $1.75\times10^{-7}$ | $1.75\times10^{-5}$ | $1.75\times10^{-4}$ | $6.99\times10^{-4}$ | $4.94\times10^{-4}$ | $3.49\times10^{-4}$ | $1.40\times10^{-4}$ |

表 6-5：$d\_{\text{model}} = 512$、warmup\_steps = 4000 时原始调度的学习率，由上面的公式逐点代入算出。左半段严格线性：step 从 100 到 1,000 涨 10 倍，学习率也涨 10 倍。右半段衰减极慢：从峰值起步数涨 25 倍，学习率才降到峰值的五分之一。这条尾巴太平，是它后来被余弦与 WSD 取代的直接原因。

$d\_{\text{model}}^{-0.5}$ 这个因子里藏着一条经验：模型越宽，同一个全局学习率就该越小。6.2.4 的 μP 与它方向一致但指数不同——μP 在 Adam 下按 $1/\text{fan\_in}$ 缩小隐藏层与输出层的学习率，而不是 $1/\sqrt{d\_{\text{model}}}$，且按层的类型分开处方。

## 6.2.2 为什么需要预热

预热要防的不是一件事，而是两件，它们的前提并不相同。

**其一，Post-LN 结构在初始化时靠近输出层的梯度偏大。** 原始 Transformer 把层归一化放在残差相加之后（Post-LN）。[一项用平均场理论做的分析](https://arxiv.org/abs/2002.04745)证明：在这种结构下，初始化时输出层附近参数的期望梯度很大，对这些梯度直接用大学习率会让优化不稳定，预热正是绕开这一段的办法。同一篇工作还给出了对偶的结论——把归一化搬进残差分支内部（Pre-LN，见 [3.6 节](/llm_internals/di-yi-bu-fen-ji-chu-pian/03_components/3.6_layer_norm.md)）后初始化时的梯度表现良好，因此**预热阶段可以安全去掉**，并在 IWSLT14、WMT14 与 BERT 预训练上验证了这一点。

这意味着“预热必不可少”是一句有前提的话。当代 LLM 几乎全是 Pre-LN，却仍然保留预热，理由要到第二条上去找。

**其二，Adam 的二阶矩在开头几步估不准。** 由 6.1.3 的手算可知，第一步的 $\hat m\_1/\sqrt{\hat v\_1}$ 精确等于 1——此时 $v$ 只见过一个样本，这个比值里不含任何统计信息。$\beta\_2 = 0.95$ 要约 20 步、$\beta\_2 = 0.999$ 要约 1000 步才积累起一个像样的二阶矩估计。在此之前，自适应学习率的方差很大，而它乘的又是全局 $\eta$，于是几个参数可能一步就被推到很远的地方。预热用小学习率把这段窗口“走过去”。

这两条机制解释不了预热长度的具体取值。DeepSeek-V3 用 2,000 步预热，而它的 $\beta\_2 = 0.95$ 只对应 20 步的窗口；Llama 3 405B 用 8,000 步。实践中预热长度更像是按总步数的一个小比例来定的，Megatron-LM 因此同时提供 `--lr-warmup-iters` 与 `--lr-warmup-fraction` 两种写法。

**预热常与批量预热同时发生。** 大规模训练常在开头同时做两件事：学习率从 0 升起，全局批量也从小往大升（6.4.1）。GPT-3 的描述是“在最初的 40 亿到 120 亿词元内，批量从 3.2 万词元线性增到全量”，与 3.75 亿词元的学习率预热重叠。两者防的是同一件事的两个侧面：初期梯度方向不可靠，既不宜迈大步，也不宜用过大的批量去平滑一个本来就没稳定的方向。

## 6.2.3 为什么需要衰减

在训练后期，模型已经接近了损失函数的局部最优区域。此时如果继续使用较大的学习率，模型会在最优点附近**反复震荡**而无法收敛。逐步降低学习率让模型的更新步长越来越精细，最终“平稳着陆”到一个好的解。

这个说法可以被一条经验结果钉死。[MiniCPM 的一组扫描实验](https://arxiv.org/abs/2404.06395)在 0.036B 模型上把余弦调度的周期 $T$ 与实际总步数 $S$ 拆开：在 $S = 20N, 40N, 60N, 80N$ 四种设定下，最低损失**总是出现在 $T = S$**，$T < S$ 与 $T > S$ 都更差。$T > S$ 差，是因为训练结束时学习率还没降下来，衰减没做完；$T < S$ 差，是因为高学习率的探索期被砍短了。式中 $N$ 为该模型的非嵌入参数量，四档设定对应词元数与参数量之比从 20 到 80。MiniCPM 还引述 Chinchilla 的同一观察：$T > S$ 会掉点，$T = S$ 则提高训练效率。结论是，衰减不是可有可无的收尾，它要落在正确的位置上。

衰减还有一个常被忽略的连带效应。6.1.4 已经指出，AdamW 的实际衰减量是 $\eta\lambda\theta$，学习率下降时权重衰减同步变弱。所以“降学习率”降的不只是步长，也在放松正则；Llama 3 在 scaling-law 实验里把权重衰减直接定义成“当步学习率的 0.1 倍”，就是把这层耦合写进了配置。

## 6.2.4 现代调度策略

除了原始的逆平方根衰减，现代大模型训练常用的是下面三条曲线。记预热结束步为 $T\_w$、总步数为 $T$、峰值与终值为 $\eta\_{\max}$、$\eta\_{\min}$。

**余弦退火**（Cosine Annealing）：

$$\eta(t) = \eta\_{\min} + \tfrac{1}{2}(\eta\_{\max}-\eta\_{\min})\left(1 + \cos\frac{\pi(t-T\_w)}{T-T\_w}\right)$$

它在中期保持较高学习率，末期下降很快。这里的 $\eta\_{\min}$ 通常**不是 0**：GPT-3 的原话是“把学习率按余弦衰减到初值的 10%，跨 2,600 亿词元；之后继续以原学习率的 10% 训练”；Llama 3 的 scaling-law 实验同样写明“余弦衰减到峰值的 0.1 倍”。降到 0 与降到 10% 的差别在于末段还留不留一点更新能力——留着，训练可以从终点继续；降到 0，则这条曲线只对一个事先定死的总步数有效。

**线性衰减**（Linear Decay）：$\eta(t) = \eta\_{\max} - (\eta\_{\max}-\eta\_{\min})\frac{t-T\_w}{T-T\_w}$。简单直接，效果通常不亚于余弦退火。

**预热-稳定-衰减**（Warmup-Stable-Decay，WSD）：名称与系统研究出自 MiniCPM，写成三段：

$$
\eta(s) =
\begin{cases}
\dfrac{s}{W},\eta, & s < W \\\[4pt]
\eta, & W \le s < T \\\[4pt]
f(s-T),\eta, & T \le s < S
\end{cases}
$$

其中 $f$ 是一个从 1 递减的函数，$W$ 是预热结束步，$T$ 是稳定段结束步。MiniCPM 的实验结论是**衰减段占总词元的 10% 就够**：2.5% 不足，10% 已能取得最好结果。

**WSD 换来了什么。** 余弦调度必须事先定死总步数——由 6.2.3 可知 $T \ne S$ 两侧都掉点，而训练要跑多久往往在开跑时并不确定。WSD 把这个约束解开：稳定段的**任何一个检查点**都可以接一段短衰减，得到一个可用的模型；不满意就回到稳定段继续训，再衰减一次。MiniCPM 正是用这一点把 scaling-law 实验的代价从“模型轴与数据轴上都要平方级的工作量”降到“数据轴上几乎没有额外代价”。

**它的代价是一个极易踩中的比较陷阱。** MiniCPM 观察到，进入衰减段后损失会**急剧下降**，迅速追平甚至低于同点的余弦调度。反过来说，在衰减段开始之前，WSD 的损失曲线看上去一直比余弦高。于是：**中途截取两条曲线比损失，得到的结论毫无意义**——比的不是调度的好坏，而是“谁已经衰减完了”。

[Kimi K3 的技术报告](https://arxiv.org/abs/2607.24653)给出了同一类陷阱的另一个版本，值得记住的是它的方法论。他们的 scaling-law 研究一致偏好余弦退火而非 WSD，但给出的理由不是“余弦更好”，而是先说明为什么此前的对比可能不可信。即使在相同模型规模与相同训练词元预算下，两种调度的最优峰值学习率与最优批大小也显著不同。用同一组超参去比较两种调度，可能仅仅因为那组超参更贴合其中一方，就不公平地偏向它。该结论属该团队在自己的模型族与数据上的观察，不是普适定论。他们的做法是对每种调度各自独立做一次 scaling-law 搜索，让两者都跑在自己的最优超参上再比较最终损失；在这个前提下余弦退火才稳定更优。这条经验的适用面远超学习率调度本身：**只要两个方案各自有一组需要调的超参，“固定超参、只换方案”的对比就是有偏的**——优化器、归一化位置、注意力变体的比较都吃这个坑。

**真实配置。** 表 6-6 把三个公开模型的调度放在一起，数值均取自各自论文的训练配方段落。

| 模型           |                 峰值 | 预热            | 衰减形状                 |                        终值 | 总长        |
| ------------ | -----------------: | ------------- | -------------------- | ------------------------: | --------- |
| GPT-3 175B   | $0.6\times10^{-4}$ | 前 3.75 亿词元线性升 | 余弦，跨 2,600 亿词元       |                   峰值的 10% | 3,000 亿词元 |
| Llama 3 405B |   $8\times10^{-5}$ | 8,000 步线性升    | 余弦                   |          $8\times10^{-7}$ | 120 万步    |
| DeepSeek-V3  | $2.2\times10^{-4}$ | 2,000 步线性升    | 恒定到 10T 词元，再余弦跨 4.3T | $2.2\times10^{-5}$，末段两级常数 | 14.8T 词元  |

表 6-6：三个公开模型的学习率调度。DeepSeek-V3 的末段是“最后 5,000 亿词元里先用 $2.2\times10^{-5}$ 训 3,330 亿，再用 $7.3\times10^{-6}$ 训 1,670 亿”，是一个带两级常数尾巴的多段式，不是单纯的“最后快速衰减”；它的衰减段占 `4.3 / 14.8 = 29%` 的词元，恒定段占 68%。

把公式代进去可以复核：GPT-3 175B 的满批量是 320 万词元/步，3.75 亿词元的预热折合 `3.75e8 / 3.2e6 = 117` 步，2,600 亿词元的余弦段折合 81,250 步，3,000 亿词元的总长减去这一段还剩 12,500 步，维持在 $6\times10^{-6}$。开头批量还在从 3.2 万词元往上爬，所以“117 步”是下界，实际预热步数更多。Llama 3 405B 按余弦公式代入，第 4,000 步（预热过半）是 $4.0\times10^{-5}$，第 30 万步是 $6.88\times10^{-5}$，中点第 60.4 万步是 $4.04\times10^{-5}$，第 90 万步已降到 $1.25\times10^{-5}$。

**峰值学习率怎样随规模变。** GPT-3 的表 2.1 把八个规模的峰值学习率一并给出，取其中三行：

| 配置     |  GPT-3 Small（125M） |         GPT-3 6.7B |         GPT-3 175B |
| ------ | -----------------: | -----------------: | -----------------: |
| 峰值学习率  | $6.0\times10^{-4}$ | $1.2\times10^{-4}$ | $0.6\times10^{-4}$ |
| 批量（词元） |               0.5M |                 2M |               3.2M |

表 6-7：GPT-3 三个规模的峰值学习率与批量，取自该论文表 2.1。参数量涨 1,400 倍，峰值学习率降到十分之一，批量涨 6.4 倍。

这条“模型越大学习率越小”的经验背后有结构性原因。标准参数化（SP）下，宽度增加时各层更新对激活的影响并不等价：一步更新之后，logits 与 attention logits 的量级会随宽度一起涨，必须靠调小全局学习率去压住，而这又让另一些参数（如词嵌入）几乎学不动。**μP**（Maximal Update Parametrization，最大更新参数化）就是为消掉这种宽度依赖而设计的一组缩放规则。用 Adam 时，[它的处方](https://arxiv.org/abs/2203.03466)按层的类型分三类：

* 输入层权重与所有偏置：初始化方差 $1/\text{fan\_in}$，学习率不随宽度变；
* 输出层权重：初始化方差 $1/\text{fan\_in}^2$，学习率按 $1/\text{fan\_in}$ 缩小；
* 隐藏层权重：初始化方差 $1/\text{fan\_in}$，学习率按 $1/\text{fan\_in}$ 缩小。

Transformer 还要多改一处：attention logits 除以每头宽度 $d\_h$ 而不是 $\sqrt{d\_h}$。做完这些之后，最优学习率在不同宽度上基本重合，于是可以在小模型上调好超参、零样本迁移到大模型。论文把这套流程叫 **μTransfer**，并报告从 4,000 万参数的代理模型迁移出的超参，在 6.7B 的 GPT-3 规模上超过了原论文公布的结果，调参代价只占总预训练算力的 7%。它的适用边界有两条。一是迁移的对象是同一族模型在**不同宽度**上的超参，换数据或换任务不在保证范围内。二是不能只改学习率一项，上面三类参数的初始化与学习率要同时改对。

**框架里的名字。** Hugging Face 的 `transformers.optimization` 直接提供 `get_cosine_schedule_with_warmup`、`get_linear_schedule_with_warmup`、`get_inverse_sqrt_schedule`、`get_cosine_with_min_lr_schedule_with_warmup` 与 `get_wsd_schedule`，通过 `lr_scheduler_type` 选择，WSD 对应的枚举值是 `SchedulerType.WARMUP_STABLE_DECAY`。Megatron-LM 的 `--lr-decay-style` 可取 `constant`、`linear`、`cosine`、`inverse-square-root`、`WSD`，配 `--min-lr` 指定终值、`--lr-warmup-iters` 或 `--lr-warmup-fraction` 指定预热长度；选 WSD 时还有 `--lr-wsd-decay-style`（`exponential`、`linear`、`cosine`、`minus_sqrt`）与 `--lr-wsd-decay-iters` 单独控制衰减段。本节三条曲线与这两处的参数名可以逐条对上。

**续训与重新预热。** 从一个已训练好的检查点继续训（继续预训练、长上下文扩展、退火阶段）时，优化器状态若一并恢复，$m$ 与 $v$ 都是热的，不需要重新走一遍预热；若只恢复权重而丢掉优化器状态，6.2.2 的第二条机制重新生效，就要补一段短预热。DeepSeek-V3 的长上下文扩展两阶段直接沿用预训练末尾的 $7.3\times10^{-6}$，没有重新升回峰值，是前一种情形的例子。

## 6.2.5 学习率调度可视化

不同的调度策略在训练过程中的学习率走势差异显著。把三种主流策略——原始逆平方根、余弦退火、WSD 三阶段——画在同一张图上，行为差异一目了然。

![不同学习率调度策略的变化曲线对比](https://2725837439-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbgsjZZ97DMbz2xYCVMN1%2Fuploads%2Fgit-blob-6edce479be80faab3f86c29ea83c135290b2ce40%2Flr_schedule_comparison.png?alt=media)

图 6-1：三种学习率调度策略的曲线对比（[生成脚本](https://github.com/yeasy/llm_internals/blob/main/tools/figures/lr_schedule_comparison.py)）。纵轴统一归一化为“占峰值学习率的比例”，以便三条曲线并排；横轴的 2 万步与 2 千步预热是示意值，真实配置见表 6-6。余弦与 WSD 都降到峰值的 10%，WSD 的衰减段取总步数的 10%，与 MiniCPM 的结论一致。

三条曲线的形状差异可以直接读出：**逆平方根**衰减最平缓，两万步后仍停在峰值的三成；**余弦退火**在中期保持较高学习率，末期快速下沉；**WSD** 在九成的训练时间里维持峰值，只在最后 10% 掉下来。图上没有画的是损失曲线，而那正是比较时最容易出错的地方——WSD 的损失在衰减段之前一直偏高，要等这段陡坡走完才追上余弦。
