使用异步dump解决A910静态图模式下的error!

2025-04-05 17:33:17

1、问题观察观察报错前的几个epoch输出的loss,有明显下降的趋势,因此代码逻辑应该没有问题。通过对报错信息的分析,并没有提及具体的逻辑运算错误,因此可以初步判断是数据问题。

2、个人排查由于同样逻辑的代码在GPU设备上并不会报错,并且能够完整训练完成,测试结果也较为正常,故可以从昇腾A910设备的特性开始着手。我尝试过将反向传播(求梯度更新参数的部分)去除,也就是去掉nn.TrainOneStep或者nn.TrainOneStepWithLossScaleCell去掉,直接输出模型的loss不进行更新。在此设置下可以稳定运行不报错(同时因为参数不更新,loss也不会变小)。由此确定模型前向传播的逻辑和算子暂无问题。至此,结合报错信息unsortedsegmentsum算子属于gather算子反向传播时经历的算子,可以确定是反向传播时算子报的数据错误。

3、使用异步dump调试由于报错的位置不确定,因此需要在静态图模式下使用dump调试功能确定报错位置和数据。在进行dump调试之前,应固定模型的随机性,使其训练时报错在一个固定的step里。榄蝈蒈缩根据我的经验,需要确定以下几点:① 数据集构建时应设置shuffle=False;② 在需要进行随机采样或者设置随机数的文件最前面加上set_seed()和np.random.seed(),固定随机种子;③ 使用numpy脚本生成npy文件固定模型参数的初始值,如果模型中有dropout等也应去掉。具体可参考官网固定随机性经过随机性固定,模型可以稳定在第5个epoch第50个step报错(可能是由于机器的原因,会有个别偶然的情况不是在此步报错)。使用异步dump参考官网给定的异步dump的方法流程异步dump配置dump.json

使用异步dump解决A910静态图模式下的error!

4、PS:net_name需要自己指定,dump成功之后会在rank_0文件夹下生成以此命名的数据文件磲稷怡棍夹;iteration在model.train模型下可以叠加计算,比如一个epoch有100个step,报错在第3个epoch的第50个step,那么就可以计算iteration为100×2+50;op_debug_mode设置为3可以dump有问题算子的脏数据,如果最初出现脏数据的地方不明显,可以先设置为3,然后在上述net_name文件夹下查看哪个op以确定最初出现脏数据的地方,后续再设置为0从而dump全量数据;配置环境变量设置dump环境变量export MINDSPORE_DUMP_CONFIG={dump.json的绝对路径}完成上述步骤后即可进行dump数据。配置mindinsight进行离线调试参考官方教程离线调试器启动mindinsight:mindinsight start --port {PORT} --summary-base-dir {SUMMARY_BASE_DIR}注意此处的SUMMARY_BASE_DIR应该是dump.json中path的上一级目录,端口设置尽量设置成不常用的。本地命令行建立连接:ssh root@{remote ip} -f -N -L localhost:{port}:localhost:{port}本地执行上述命令无误后即可打开localhost:{port}看到mindinsight界面离线调试查看数据打开界面后点击离线调试器进入离线调试界面根据报错信息,最开始在op223处报了一个overflow的warning,设置当前轮次为727并搜索op223,可以查看此op的输入输出数据。点击查看后,可以观察到op223的输出有-INF的脏数据。

使用异步dump解决A910静态图模式下的error!

5、在查看页面的下方可以顺着数据流检查数据的传导。经过检查,最终报错的算子op252处于op223的下游,因此可以确定op252的错误是op223产生的脏数据级联传播造成的。

使用异步dump解决A910静态图模式下的error!

6、经过dump全量数据之后,进一步观察op223的输入,发现其中有几个0数据,通过查看堆栈信息,此处为求范数。

使用异步dump解决A910静态图模式下的error!

7、对应的前向中出现sqrt求根操作,因此对应反向会将输入x置于分母上,当输入数据产生0,就会产生除0操作从而生成脏数据。由于昇腾机器上部分算子为fp16精度,个人猜测是由于fp32的数据强制转换为fp16时进行了截断,导致一些很小的数截断后直接变成了0。按照严谨解决此类问题的思路,应当是顺着数据流和算子,找到需要降精度的算子,强制让其不转换精度。我这里的解决方法是直接重写nn.Norm,在求根操作时加上一个极小的偏置值,使其不会出现除0操作产生脏数据:x = self.sqrt(self.reduce_sum(F.square(x), self.axis)+1e-6)

8、修正后训练测试在加上偏置值进行修正Norm算子之后,模型可以完整地训练给定的迭代次数:

使用异步dump解决A910静态图模式下的error!

9、注意事项不同的模型应该就具体情况而论,出现问题的算子也不一定就都是norm算子,最好的解决方案还是找到降低精度的算子进行修正,当前的修正方案尚在评估精度和效率影响;dump全量数据可能会占用大量的磁盘空间(我dump全量的数据占用了90G磁盘空间),需要保证有充足的磁盘空间。

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢