技术博客

Adam 的 ε 与数值稳定性:一个小常数的大作用

第 128 / 147 篇 · 2026-09-06 · ai · 优化器Adam数值计算

Adam 的更新式分母里有个几乎没人调过的常数:

$$ \theta_{t+1} = \theta_t - \eta\,\frac{\hat m_t}{\sqrt{\hat v_t} + \varepsilon}, \qquad \varepsilon = 10^{-8}\ \text{(PyTorch 默认)}. $$

它通常被一句话带过——"防止除零"。防除零确实是它最显眼的功能,但只看这一层会错过它在另外三个场景里的结构性作用。

场景一:稀疏特征与除零

看一个 embedding 查表参数:某行 embedding 在本次 batch 里没被任何 token 命中,梯度就是零。动量和二阶矩照常更新:

$$ m_t = \beta_1 m_{t-1}, \qquad v_t = \beta_2 v_{t-1}. $$

只要这一行梯度有连续一段时间为零(稀疏特征、长尾 token 的典型处境),$v_t$ 会指数衰减到 $10^{-20}$ 量级以下,平方根后仍在 $10^{-10}$ 以下。没有 $\varepsilon$ 时,分子 $\hat m_t$ 和分母 $\sqrt{\hat v_t}$ 同量级相除,数值上不至于爆炸(两者同步衰减,比值仍约等于历史平均信噪比),但用 fp32 跑分母会一路跌向 denormal 区,运算变慢且精度损失;混合精度训练里分母一旦以 fp16/bf16 存,下溢直接变零或 inf。$\varepsilon$ 的实质作用是:当梯度统计量小到失去意义时,把更新式切换到一个安全退化模式——

$$ \frac{\hat m_t}{\sqrt{\hat v_t}+\varepsilon} \;\xrightarrow{v \to 0}\; \frac{\hat m_t}{\varepsilon} \quad (\text{若 } |\hat m_t| \ll \varepsilon \text{ 则进一步} \approx 0). $$

值得留意分子分母的不同待遇:分子 $\hat m_t$ 即使很小也保留符号信息,所以一个"很久以前动过、现在休眠"的参数仍会缓慢地被拉回,而 $\varepsilon$ 保证这个回拉的速度被钳制在 $\eta \cdot |\hat m_t|/\varepsilon$ 以内。

场景二:有效学习率的上限

Adam 的宣传口径是"自适应步长",但 $\varepsilon$ 给自适应设了一个天花板。单坐标的有效步长是

$$ \eta_{\text{eff}} = \eta \cdot \frac{1}{\sqrt{\hat v_t}+\varepsilon} \cdot |\hat m_t| \;\le\; \eta \cdot \frac{|\hat m_t|}{\varepsilon}. $$

在梯度幅值远小于 $\varepsilon$ 的区域(更新后期的微调、小学习率阶段),$\eta_{\text{eff}} \approx \eta |\hat m_t| / \varepsilon$,步长和梯度成正比、和 $\varepsilon$ 成反比——此时 Adam 的行为更接近裸 SGD 而不是符号下降。把 $\varepsilon$ 从 $10^{-8}$ 提到 $10^{-6}$(Adam 论文附录的建议值),相当于把这一线性区的斜率压低两个数量级。这个上限平时无关紧要(正常训练的 $\sqrt{\hat v}$ 在 $10^{-3}\sim10^{-1}$),但做极低学习率的微调(如 RLHF 里 $10^{-6}$ 级别的 lr)时,$\varepsilon$ 和 lr 的比值变得不可忽略,默认值就不再是安全选择了。

场景三:符号近似下的软化

把动量项也近似掉($\beta_1 \to 0$,$m \approx (1-\beta_1) g$),更新可以写成

$$ \Delta\theta \approx -\eta \cdot \frac{|g|}{\sqrt{\hat v}+\varepsilon}\cdot \mathrm{sign}(g). $$

$\varepsilon = 0$ 时分母 $\approx |g|$,严格的符号下降;$\varepsilon$ 给分母加了一个与 $g$ 无关的偏移,等效为给"步长恒定"的符号规则加了一个按梯度幅值加权的软过渡。可以把它理解成符号函数的光滑化参数:$\varepsilon$ 越大,小梯度坐标的步长被压得越多,坐标间越不均等;$\varepsilon \to 0$ 时所有活跃坐标严格等权。后面讲 Lion 的那篇会看到,Lion 走的正是 $\varepsilon=0$ 这条极限路线,并把这一选择解释成优点而非缺陷。

单坐标有效步长随梯度幅值的变化:ε 划出线性区与符号区的分界(示意) 梯度幅值 |g| ηeff |g| ≈ √v̂ + ε 线性区:Δθ ∝ g/ε 符号区:Δθ ≈ ±η 符号下降(ε→0)

该取多大:一个数量级的直觉

$\varepsilon$ 的正确量级由"你希望的步长地板"决定:当坐标梯度持续低于 $\varepsilon$ 量级时,这个坐标事实上被冻结(更新被压到噪声以下)。经验法则:

  • 常规预训练/微调,$\sqrt{\hat v}$ 典型值 $10^{-2}$ 上下:$\varepsilon=10^{-8}$ 完全够用,纯粹是防下溢保险丝。
  • 低学习率微调、参数本身已很小(RLHF、LoRA 的 B 矩阵):考虑 $10^{-6}$,避免 ε 相对 v̂ 过大造成小梯度坐标冻结。
  • 遇到 loss 长时间纹丝不动且排查不出原因时,值得看一眼各层 $\sqrt{\hat v}$ 的分布——如果中位数贴着 $10^{-7}$ 走,说明任务梯度天然极小,$\varepsilon$ 已在替你决定哪些参数活着。

PyTorch 的 AdamW 把 eps 暴露为构造参数,框架默认值 $10^{-8}$ 沿自原论文,而原论文的网格实验里表现最好的恰恰是更大的 $10^{-6}$——默认值是保守选择,不是最优选择。

小结

$\varepsilon$ 在 Adam 里有三层身份:数值保险丝(防 v̂ 下溢到 denormal)、有效学习率上限($|\Delta\theta| \le \eta|\hat m|/\varepsilon$)、符号规则的软化参数(决定坐标间均等程度)。它平时隐身,是因为正常训练的 $\sqrt{\hat v}$ 远高于它;一旦进入低梯度场景(稀疏特征、极低学习率、训练末期),$\varepsilon$ 就接管了更新行为。把它当可忽略的细节,等于把一部分优化器控制权交给了一个从没被扫过的超参。