混合精度调优经验分享(四)

算子溢出定位

由于昇腾上部分算子不支持fp32(如 Conv,Pooling),或部分算子虽然支持fp32但性能极差,不得不切换成fp16(如MatMul),或者用户脚本中设置了混合精度,这些原因导致其必须走fp16格式,这增大了训练过程中算子溢出的风险,影响网络最终收敛的精度,这里给出算子溢出分析方法。

开启溢出检测

cke_5645.png

在MindSpore官网如上所示搜索 dump ,找到 异步dump 指导。

对于溢出检测,需要注意以下配置:

dump_mode:设置为0,检测到所有算子

path:推荐设置到/home/ma-user/modelarts/outputs/output_url_0/ 目录下,DI训练时该目录会自动回传数据到obs,方便后续进行溢出检测分析

iteration:设置为all,检测所有迭代

op_debug_mode:设置为3,开启全部溢出检测

一个典型的溢出检测 data_dump.json 配置为:

{

"common_dump_settings": {

"dump_mode": 0,

"path": "/home/ma-user/modelarts/outputs/output_url_0/bev/dump/",

"net_name": "bevnet",

"iteration": "all",

"saved_data": "tensor",

"input_output": 0,

"kernels": [],

"support_device": [0,1,2,3,4,5,6,7],

"op_debug_mode": 3,

"file_format": "npy"

}复制

查看溢出算子

在日志中搜索关键字 overflow infos,如果有算子溢出,则日志中会提示算子所在的代码行:

cke_115301.png

如上图所示,溢出的算子为 Cast-op41878 该算子为 Cast 算子,scope 名为 Gradients/Default/network-MultiTaskTrainOneStepCell/network-ModuleWrapper/detection3d_head-DetHead/det_head-CenterPointHead/head-CenterHead/task_heads-CellList/0-SeparateHead/reg-SequentialCell/1-_OutputTo32/_op-Conv2d/gradConv2D/Cast-op41878(如果scope的名字以Gradients 开头,说明该算子是反向产生的算子)。根据 The function call stack: 提示,找到该算子对应的代码(反向算子需要先找到对应的正向算子)。

分析溢出产生原因

在上一步骤中,我们可以找到具体溢出的算子和所在代码,这一步我们需要分析溢出产生的原因。首先需要找出溢出算子所在的rank,下载该rank 下的dump数据,一个标准的dump数据结构如下所示:

rank_xx

|-- bevnet           # 根目录,根据 data_dump.json 配置生成

|   |-- 0            # 每个step产生的dump文件,序号代表step数

|   |-- 1

|   |-- 17

|   |-- 2

|   `-- constants     # 网络中的常量,数据不随step数改变

|-- execution_order   # 网络中算子的执行顺序(如果有多个图,则产生多个文件)

|   |-- ms_execution_order_graph_0.csv

|   |-- ms_execution_order_graph_1.csv

|   |-- ms_execution_order_graph_17.csv

|   |-- ms_execution_order_graph_18.csv

|   |-- ms_execution_order_graph_19.csv

|   |-- ms_execution_order_graph_2.csv

|   `-- ms_global_execution_order_graph_17.csv

`-- graphs           # 网络中算子的图结构(如果有多个图,则产生多个文件)

|-- ms_output_trace_code_graph_0.ir

|-- ms_output_trace_code_graph_0.pb

|-- ms_output_trace_code_graph_1.ir

|-- ms_output_trace_code_graph_1.pb

|-- ms_output_trace_code_graph_17.ir

|-- ms_output_trace_code_graph_17.pb

|-- ms_output_trace_code_graph_18.ir

|-- ms_output_trace_code_graph_18.pb

|-- ms_output_trace_code_graph_19.ir

|-- ms_output_trace_code_graph_19.pb

|-- ms_output_trace_code_graph_2.ir

`-- ms_output_trace_code_graph_2.pb

8 directories, 21 files复制

一般我们只关注 rank_xx/xxx/x/ 下的数据,假设该目录下数据如下所示:

cke_130747.png

可以看到,Cast-op41878 的溢出数据被dump了出来,读取其中的数据,可以发现该算子的输入 104856.29 在cast之后变成了 65500.0 ,算子发生了溢出。(因为FP16格式下最大能表达的值为65504)

cke_138539.png

这里的溢出是正常的,原因详细参考下一章节

判断溢出是否合理

如果出现了溢出,第一件事就是需要判断该溢出是否合理,一般合理的溢出无需关注,溢出出现的step会被忽略,然后网络会调整LossScale 的值,后续训练仍会正常更新。如果溢出不合理,则需要定位原因,不合理的溢出可能一直影响网络训练,导致最终精度无法收敛的合理的值。

首先需要判断溢出算子出现在正向还是反向,判断的根据是scope名字,如果算子的scope名字以 "Default/xx" 开头,则该算子出现在正向;如果算子的scope名字以 "Gradient" 开头,则算子出现在反向。

步骤1:判断算子是否确实存在计算溢出

仅分析该算子的输入输出,此时输入输出是否真的达到了触发溢出的条件,触发条件一般为:输入/输出的绝对值大于 65504、输入输出数据中存在nan或inf、算子存在除0的操作、算子存在对负数开偶数次方等;

如果以上情况不存在,该溢出不合理;

步骤2:判断溢出场景的存在是否合理

如果是网络迁移场景,请和原脚本相同位置的值进行比较,同样的输入和网络,该溢出位置的输入输出是否和原脚本一致;如果是新开发脚本,请认真检查该值出现的合理性;

如果该溢出场景实际并不合理,则该算子的溢出也不合理;

步骤3:判断反向算子的LossScale 是否过大

对于溢出算子是反向算子,除了按照步骤1和步骤2的判断外,还需要考虑混合精度场景下LossScale的影响。在混合精度场景中,反向算子的值都会被扩大LossScale倍,此时很容易发生溢出,此时可以将算子的输入梯度除以LossScale,再观察是否会触发溢出;

如果该溢出是由于LossScale的值过大导致,则该算子的溢出是合理的,如果不是LossScale的值过大引起,则连续发生溢出,则该算子的溢出不合理;

溢出问题解决方法

  1. 算子计算不涉及溢出

如果算子计算不存在溢出,则算子存在误溢出;误溢出一般是算子本身的bug导致,可能是算子内部实现时脏数据的处理误触发了溢出,此时直接联系相关支撑人员解决;

  1. 溢出场景不存在

如果溢出的场景本身不应该存在,此时应进行逐层与原迁移脚本的比对或检查,很可能是网络脚本写错而引入了溢出场景;

如果网络脚本排查后没有问题,也可能是网络代码中存在框架bug或算子bug,导致运行到该处发生了溢出;如果迁移前后的脚本是数学上等价,但计算结果不同,此时需要联系相关支撑人员解决;

  1. 反向梯度过大导致溢出

在上一节判断溢出是否合理的第三步中, 我们首先需要判断梯度溢出是否由于LossScale过大引起,如果是,则无需关注,随着训练中每个step的溢出,LossScale会逐渐调整合适的值,直到不再溢出;

注意,LossScale的最小值默认为1,当LossScale 的值降低为1仍持续发生溢出,此时表明网络中是存在问题的。

这时存在问题的原因有两个:

一是由于网络设计的原因,在迭代前期需要的梯度特别大,导致不使用LossScale缩放时的实际梯度值都要大于FP16的表达范围,因此,当LossScale降低为1时,仍会发生溢出。针对该问题,建议重新设计网络,或者将网络的Loss值乘以一个小于1的数进行缩小,从而缩小梯度保证正常的更新;

二是反向存在框架或算在bug,此时可以与对标脚本或框架比对结果,如果无法定位或确实发现有框架/算子的问题,可以在MindSpore论坛进行提问会有专人帮忙支撑处理:https://www.hiascend.com/forum/forum-0106101385921175002-1.html

混合精度调优经验分享(一):https://www.hiascend.com/forum/thread-0236124525404545023-1-1.html

混合精度调优经验分享(二):https://www.hiascend.com/forum/thread-0239124525600150026-1-1.html

混合精度调优经验分享(三):https://www.hiascend.com/forum/thread-0216124525871858017-1-1.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值