Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve amp training and fix nan error #8305

Merged
merged 1 commit into from
Jun 5, 2023

Conversation

zhangting2020
Copy link
Contributor

背景:ppyoloe、ppyolo、ppyolov2、picodet、mask_rcnn、tinypose在Paddle2.4版本上amp-o2会训练nan,或者精度无法对齐。本PR修复这几个模型,并且已经自测了当前修复后的精度,可以达到和fp32训练对齐的效果。主要修复的问题如下:

(1)一些模型特定的模块计算结果上溢出,不适合fp16

  • ppyoloe、ppyolo、ppyolov2、picodet、mask_rcnn这些模型中发现,IoU计算、DropBlock、YoLoLoss、PicoHeadV2等多个部分计算结果已经远超fp16上限,因此导致模型运行nan。
  • 在旧版本上,amp-o2采用的是almost fp16,即只要算子支持fp16就使用fp16计算,较为激进。而Paddle2.5版本和当前的develop分支上,除了conv等白名单算子会默认采用fp16计算加速,其他算子当输入全是fp16类型才会使用fp16计算。因此能够避免一些模块出现上溢出,例如mask rcnn模型原始需要对IoU部分关掉amp,但在Paddle2.5上由于该模块算子输入存在fp32类型,则自动选择fp32计算,无需修改模型。

(2)一些模型需要手动将部分算子输入提升到fp32类型:如PR中修改,某些模块依然会在Paddle2.5上出现溢出,但基于升级后的O2,我们只需要将算子输入手动cast到fp32就能保证算子使用fp32计算了。而在过去需要手动cast+auto_cast(enable=False)2步修改。

(3)一些模型梯度过小导致训练指标无法对齐:tinypose模型梯度非常小,套件采用了1024的初始loss scale,会导致梯度大部分在fp16表示下为0,参数得不到更新,表现在训练开始后loss没有下降也没有nan。另外在反向传播过程中权重梯度尽管可以通过调大的loss scale被放大,但在参数更新前需要unscale权重的梯度,此时权重梯度在fp16表示下依然会变为0,导致梯度更新受影响。因此我们新增了master_grad的功能解决此问题:当启用该功能后,每一个迭代,在反向传播结束,权重梯度会被cast到fp32,并且用这份fp32梯度替换原始的fp16梯度,以此来保证后续通过param.grad拿到的是fp32梯度,避免unscale后数值下溢出为0

(4)一些模型梯度过大导致训练nan:ppyolo、ppyolov2权重梯度较大,在grad_clip阶段,会导致在fp16计算下出现inf。该问题也可以通过启用master_grad去解决。

(5)EAM在amp-o2模式下,需要使用fp32存储权重,并且使用fp32计算更新权重:原始的实现EMA部分在O2模式下采用的fp16的权重存储和计算,随着迭代误差积累会发现训练loss正常下降,但是eval时指标接近于0。

@paddle-bot
Copy link

paddle-bot bot commented May 31, 2023

Thanks for your contribution!

@LokeZhou LokeZhou merged commit 2277804 into PaddlePaddle:develop Jun 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants