使能自动混合精度
混合精度训练方法是通过混合使用单精度和半精度数据格式来加速深度神经网络训练的过程,同时保持了单精度训练所能达到的网络精度。混合精度训练能够加速计算过程,同时减少内存使用和存取,并使得在特定的硬件上可以训练更大的模型或。
对于FP16的算子,若给定的数据类型是FP32,MindSpore框架的后端会进行降精度处理。用户可以开启INFO日志,并通过搜索关键字“reduce precision”查看降精度处理的算子。
MindSpore混合精度典型的计算流程如下图所示:
参数以FP32存储;
正向计算过程中,遇到FP16算子,需要把算子输入和参数从FP32 cast成FP16进行计算;
反向计算过程中,首先乘以Loss Scale值,避免反向梯度过小而产生下溢;
除以Loss scale值,还原被放大的梯度;
判断梯度是否存在溢出,如果溢出则跳过更新,否则优化器以FP32对原始参数进行更新。
本文通过自动混合精度和手动混合精度的样例来讲解计算流程。
使用自动混合精度,需要调用相应的接口,将待训练网络和优化器作为输入传进去;该接口会将整张网络的算子转换成FP16算子(除BatchNorm
算子和Loss涉及到的算子外)。可以使用amp
接口和Model
接口两种方式实现混合精度。
使用amp
接口具体的实现步骤为:
引入MindSpore的混合精度的接口
amp
;定义网络:该步骤和普通的网络定义没有区别(无需手动配置某个算子的精度);
代码样例如下:
引入MindSpore的模型训练接口
Model
;定义网络:该步骤和普通的网络定义没有区别(无需手动配置某个算子的精度);
创建数据集。该步骤可参考 https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/quick_start/quick_start.html;
使用
Model
接口封装网络模型、优化器和损失函数,设置amp_level
参数,参考。在该步骤中,MindSpore会将有需要的算子自动进行类型转换。
代码样例如下:
MindSpore还支持手动混合精度。假定在网络中只有一个Dense Layer要用FP32计算,其他Layer都用FP16计算。混合精度配置以Cell为粒度,Cell默认是FP32类型。
以下是一个手动混合精度的实现步骤:
定义网络: 该步骤与自动混合精度中的步骤2类似;
配置混合精度: 通过
net.to_float(mstype.float16)
,把该Cell及其子Cell中所有的算子都配置成FP16;然后,将模型中的dense算子手动配置成FP32;
代码样例如下: