混合精度训练
深度神经网络(DNNs)在许多领域都取得了突破,包括图像处理和理解、语言建模、语言翻译、语音处理、游戏玩法等。随着DNN复杂性的提高,训练这些网络所需的计算资源也在增加。混合精度训练通过使用低精度算术来降低所需的资源,具有以下优点:
-
减少所需的内存量:半精度浮点格式(FP16)使用16位,与单精度(FP32)的32位相比,降低了所需的内存。这使得可以训练更大的模型或使用更大的小批量进行训练。
-
缩短训练或推理时间:执行时间可能对内存或算术带宽敏感。半精度将访问的字节数减半,从而减少了在内存受限层花费的时间。NVIDIA GPU在与单精度相比时,提供了高达8倍的半精度算术吞吐量,从而加速了数学受限的层。
混合精度训练使用单精度和半精度表示,以保持与单精度训练相同的网络精度。
混合精度训练的成功技巧
-
FP16乘积累积到FP32:NVIDIA Volta 架构引入了Tensor Core指令,这些指令可以乘以半精度矩阵,将结果累积到单精度或半精度输出中。我们发现,累积到单精度对于获得良好的训练结果至关重要。累积值在写入内存之前转换为半精度。
-
损失缩放:在训练DNNs时,会遇到四种类型的张量:激活,激活梯度,权重,和权重梯度。在我们的经验中,激活,权重,和权重梯度都落在半精度可以表示的范围内。然而,对于一些网络,小幅度的激活梯度会低于半精度的范围。为了确保梯度落入半精度可表示的范围,可以通过乘以比例因子S来乘以训练损失。这只添加了一个乘法,并通过链式规则确保所有的梯度都被放大(或向上移动)。
-
权重的FP32主副本:DNN训练的每次迭代都通过添加相应的权重梯度来更新网络权重。权重梯度的幅度通常比相应的权重小得多,特别是在乘以学习率(或像Adam或AdaGrad这样的优化器计算的自适应因子)之后。这种幅度差异可能导致如果其中一个加数太小而无法在半精度表示中产生差异(例如,由于指数差异大,较小的加数在对齐二进制点后变为零),则不会进行更新。
对于以这种方式丢失更新的网络,一个简单的解决办法是在单精度中维护和更新权重的主副本。在每次迭代中,都会制作主权重的半精度副本,并在前向和反向传播中使用,从而获得性能优势。在权重更新期间,将计算出的权重梯度转换为单精度,并用于更新主副本,然后在下一次迭代中重复这个过程。因此,我们在需要的地方混合使用了半精度存储和单精度存储。
混合精度训练迭代
以上介绍的三种技术可以组合成以下每次训练迭代的步骤序列。对传统迭代过程的新增部分以粗体表示。
- 制作权重的FP16副本
- 使用FP16权重和激活进行前向传播
- 将结果损失乘以比例因子S
- 使用FP16权重,激活及其梯度进行反向传播
- 将权重梯度乘以1/S
- 可选地处理权重梯度(梯度裁剪,权重衰减等)
- 在FP32中更新权重的主副本
我们在各种卷积、循环和生成DNN上使用了上述三种混合精度训练技术。应用任务包括图像分类、对象检测、图像生成、语言建模、语音处理和语言翻译。实验结果表明,虽然半精度范围比单精度范围窄,但对于训练各种应用任务的最先进的DNN来说,它是足够的,因为结果与纯单精度训练的结果相匹配。
参考资料
- P. Micikevicius, S. Narang, J. Alben, G. Diamos, E. Eelsen, B. Ginsburg, M. Houston, O. Kuchaiev, G. Venkatesh, H. Wu. Mixed Precision Training, 2017. 链接
- Training with Mixed-Precision User Guide, 2017. 链接
- B. Ginsburg, S. Nikolaev, P. Micikevicius. Training with Mixed Precision, GPU Technology Conference, 2017. 链接
混合精度训练是一种强大的工具,可以帮助我们更有效地训练深度神经网络。通过理解和应用这些技术,我们可以在保持模型精度的同时,提高训练速度和减少内存使用。
本文作者:Maeiee
本文链接:混合精度训练
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!