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

2025-05-25 09:24:56

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!

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

使用异步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。
猜你喜欢