深度学习中的自适应优化算法之AdaFactor算法原理与参数缩放机制
题目描述
AdaFactor是一种自适应优化算法,专门设计用于降低内存占用,尤其适合训练大规模语言模型(如Transformer-based模型)。它基于Adam算法的自适应动量估计思想,但通过因子分解(factorization)技术减少存储二阶矩(second moment)估计所需的内存。AdaFactor的核心目标是在保持模型训练效果的同时,显著降低优化器内存开销,从而支持更大规模的模型训练。本题目将详细解释AdaFactor的原理、因子分解机制、自适应参数缩放、以及其相对于Adam的改进之处。
解题过程
1. 背景与问题动机
在深度学习优化中,Adam及其变体广泛使用。Adam为每个参数维护两个状态:一阶矩(动量)和二阶矩(自适应学习率项)。对于包含数十亿参数的大模型,二阶矩估计(每个参数一个标量)会占用巨大内存。例如,10亿参数的模型,Adam二阶矩存储需约4GB内存(float32精度)。
AdaFactor的关键创新:将二阶矩估计矩阵分解为两个低秩矩阵的乘积,大幅减少内存使用,同时保留自适应学习率特性。
2. AdaFactor 算法核心思想
原始Adam的更新规则回顾:
- 一阶矩:\(m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t\)
- 二阶矩:\(v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2\)
- 更新:\(\theta_t = \theta_{t-1} - \alpha \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}\)
AdaFactor的改进思路:
- 将二阶矩估计 \(v_t\) 分解为两个低秩向量(或矩阵)的乘积,避免存储完整矩阵。
- 引入参数缩放(parameter scaling),替代权重衰减(weight decay)。
3. 二阶矩的因子分解
假设模型参数 \(\theta \in \mathbb{R}^{m \times n}\) 是一个矩阵(例如,Transformer中的权重矩阵)。在Adam中,二阶矩 \(v \in \mathbb{R}^{m \times n}\) 存储每个参数的平方梯度。
AdaFactor将 \(v_t\) 分解为:
\[v_t = R_t \cdot C_t^\top \]
其中:
- \(R_t \in \mathbb{R}^{m \times k}\)
- \(C_t \in \mathbb{R}^{n \times k}\)
- \(k \ll \min(m, n)\) 是低秩维度(通常设为1)。
物理意义:
- \(R_t\) 表示行方向的梯度统计。
- \(C_t\) 表示列方向的梯度统计。
- 通过外积近似恢复完整二阶矩:\(v_t \approx R_t C_t^\top\)。
内存节省:原始需存储 \(m \times n\) 个元素,现只需存储 \((m + n) \times k\) 个元素。当 \(k=1\) 时,内存减少为原来的 \(\frac{m+n}{m \times n} \approx \frac{1}{\min(m, n)}\)。
4. 因子分解的更新规则
AdaFactor维护两个低秩矩阵 \(R_t\) 和 \(C_t\),分别用指数移动平均更新:
- 计算当前梯度矩阵 \(g_t \in \mathbb{R}^{m \times n}\)。
- 更新行统计:\(R_t = \beta_2 R_{t-1} + (1 - \beta_2) \sum_{j} (g_t^2)_{ij} / n\) (对每行求平均)
- 更新列统计:\(C_t = \beta_2 C_{t-1} + (1 - \beta_2) \sum_{i} (g_t^2)_{ij} / m\) (对每列求平均)
近似二阶矩:
\[\hat{v}_t = R_t \cdot C_t^\top / \left( \frac{1}{mn} \sum_{i,j} (g_t^2)_{ij} \right) \]
这里的分母是为了数值稳定性,确保估计尺度合理。
5. 参数缩放与学习率调整
AdaFactor用参数缩放替代权重衰减。更新公式为:
\[\theta_t = \theta_{t-1} - \alpha_t \cdot g_t / \sqrt{\hat{v}_t + \epsilon} \]
其中:
- \(\alpha_t\) 是学习率,可包含预热(warmup)和衰减(decay)。
- 参数缩放通过自适应学习率隐式控制参数范数,避免显式权重衰减项。
相对更新量裁剪:为防止更新步长过大,AdaFactor会限制更新量的相对幅度:
\[\Delta_t = \text{clip}\left( \frac{g_t}{\sqrt{\hat{v}_t}}, \text{threshold} \right) \]
阈值通常设为1.0。
6. 算法步骤总结
-
初始化:
- 初始化参数 \(\theta_0\)。
- 初始化行统计 \(R_0\) 和列统计 \(C_0\) 为零矩阵。
- 设置超参数: \(\beta_1, \beta_2\)(动量衰减率)、\(k\)(低秩维度)、学习率 \(\alpha_t\)、阈值 \(\text{clip\_threshold}\)。
-
迭代更新(对每个训练步 \(t\)):
- 计算梯度 \(g_t\)。
- 更新一阶矩(可选):\(m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t\)。
- 更新行统计 \(R_t\) 和列统计 \(C_t\) 如上所述。
- 计算近似二阶矩 \(\hat{v}_t = R_t C_t^\top / \text{mean}(g_t^2)\)。
- 计算自适应步长:\(\Delta_t = g_t / \sqrt{\hat{v}_t + \epsilon}\)。
- 裁剪更新:\(\Delta_t = \text{clip}( \Delta_t, \text{threshold} )\)。
- 参数更新:\(\theta_t = \theta_{t-1} - \alpha_t \cdot \Delta_t\)。
7. 与Adam的对比优势
- 内存效率:二阶矩存储从 \(O(mn)\) 降至 \(O(m + n)\),适合大参数矩阵。
- 数值稳定性:因子分解减少极端值对二阶矩估计的影响。
- 训练效果:在语言模型任务中,AdaFactor常达到与Adam相当或更好的效果,尤其在超大模型上。
8. 实际应用与注意事项
- 适用场景:主要针对矩阵参数(如全连接层、注意力层的权重),对向量参数(如偏置)可退化为普通二阶矩。
- 超参数设置:通常 \(\beta_2\) 较高(如0.999),\(k=1\) 已足够。学习率调度需配合预热。
- 实现细节:需处理低秩矩阵的初始化、数值下溢问题(添加小常数 \(\epsilon\))。
小结
AdaFactor通过因子分解二阶矩估计,大幅降低优化器内存占用,同时保持自适应学习率的优点。其参数缩放机制避免了显式权重衰减,简化了超参数调节。在训练Transformer等大型模型时,AdaFactor成为内存敏感场景下的重要优化器选择,体现了深度学习优化在效率与效果之间的平衡设计。