1 两种模式的区别
饱和模式(不开infnan模式):检查训练中间比较、计算操作的溢出情况,只要中间结果有溢出,就会丢弃当前step,重新开始训练。
非饱和模式(infnan模式):只检查梯度数据是否存在INF/NAN,不检查中间结果。中间结果溢出,只要梯度正常,整网依然不会溢出,可以正常训练。
2 开启INFNAN模式后的溢出问题
开启infnan模式之后网络可能出现持续溢出,可以尝试关闭matmul算子的fixpipe融合,方法如下:
以CANN 7.0为例,修改
/usr/local/Ascend/CANN-7.0/opp/built-in/fusion_pass/config/fusion_config.json
"UBFusion":{
"TbeMatmulFixPipeFus ionPass":"on",
"TbeConvDequantSigmoidMulAddFus ionPass": "off",
"Conv2dTransDataFusionPass" : "off",
"AutoSingleNormFusionPass": "off",
"AutoSingleReduceFusionPass": "off"
}
其中TbeMatmulFixPipeFus ionPass这个值改成off。
3 开启INFNAN输出为Nan,关闭INFNAN输出正常
现象:INFNAN模式下训练loss为nan,910 loss 正常,经过dump比对发现在attention中query和key进行矩阵乘获取score时,计算结果超出了fp16的表示范围,在INFNAN模式下依然为inf, 然而在910上会将超出fp16表示范围的置为65504。
目前可以使用以下几种方法:
1,全局使用fp32训练
2,溢出部分手动改成fp32计算,
3,全局修改成bf16训练。