系列文章目录
项目信息、本地GPU单卡复现:
华为Ascend众智计划项目–3DMPPE_ROOTNET–Pytorch模型迁移至NPU(一)
模型迁移——本地代码添加:
华为Ascend众智计划项目–3DMPPE_ROOTNET–Pytorch模型迁移至NPU(二)
模型迁移——服务器GPU-2P调试和NPU单卡调试:
华为Ascend众智计划项目–3DMPPE_ROOTNET–Pytorch模型迁移至NPU(三)
模型迁移——NPU单P性能和精度调优:
华为Ascend众智计划项目–3DMPPE_ROOTNET–Pytorch模型迁移至NPU(四)
模型迁移——NPU-8P调试:
华为Ascend众智计划项目–3DMPPE_ROOTNET–Pytorch模型迁移至NPU(五)
前言
本系列文章记录笔者在完成华为昇腾众智项目的主要过程、遇到的问题及解决方案等。Ascend 众智计划是华为围绕 Ascend 基础软件平台推出的一项生态合作计划,旨在汇聚高校、科研院所、企业等组织和机构的开发团队,通过项目合作方式,基于 Ascend 基础软硬件平台开发算子、网络模型及行业参考设计,不断丰富 Ascend 计算产业生态,为加速千行百业智能化升级贡献智慧与力量。笔者负责的是姿态识别模型3DMPPE_ROOTNET的训练任务,该模型是基于Pytorch框架实现的。
一、性能调优
- 性能优化首先请参考华为官方文档。
- 刚开始在NPU上单卡带prof运行时,1个epoch需要接近7个小时,即使不带prof也需要6个小时左右。所以笔者对比了GPU单P和NPU单P的prof文件。
上面两张图中,第一张为GPU的prof文件,第二张为NPU的prof文件,可以看出NPU的prof文件中几乎没有NPU的使用时间,经过对代码的排查,发现是:
with torch.autograd.profiler.profile(use_cuda=True) as prof:
应该改为:
with torch.autograd.profiler.profile(use_npu=True) as prof:
更改之后NPU的prof文件如下图,可以看出NPU和GPU上都有了时间:
- 进行上述更改后发现在不带prof的情况下,一个epoch仍然需要6个小时左右,所以笔者尝试将batch_size从32调为64,时间缩短为4~5h,但和添加了apex的GPU单卡(1个epoch需要2h左右)相比仍然有较大差距。所以笔者将batch_size改回32,开始尝试文档中性能优化的方法。
性能优化五板斧:
- 笔者尝试了方法1中的更改优化函数和
combine_grad=True
,对代码进行了这两处修改后,性能有了明显提升,1个epoch只需要1h左右,达到了GPU单P的2倍。更改优化函数的代码如下:
from apex.optimizers import NpuFusedSGD
...
#optimizer = torch.optim.Adam(model.parameters(), lr=cfg.lr)
optimizer = NpuFusedAdam(model.parameters(), lr=cfg.lr)
二、精度调优(论文精度为0.31)
精度优化首先请参考华为官方文档。
-
在NPU单P可以跑通后,对模型进行训练,得到的模型精度如下表,左边的序号代表对应epoch结束后保存的model。
-
可以看到第8个epoch结束后精度接近了论文精度,于是笔者在第7个第8个epoch保存的model的基础上继续训练,但精度一直维持在0.22~0.28,无法继续提升。
-
之后笔者尝试更改了amp中的loss_scale,由原来的none改为128.0,最终精度仍然维持在0.22~0.26左右,笔者又尝试注释掉了test.py中的
cam_param.to(torch.int32)
,精度只有极小的提升。 -
之后笔者又注释掉了train.py中的
.to(torch.int32)
相关语句,并且将amp中的opt_level设置为了"O1",原先为"O2",loss_scale保持128.0不变,精度有所提升,但最高没有超过0.29。amp中opt_level改变的是性能,O2的性能相对来说高于O1,但笔者推测性能的提升会随之带来一些精度的下降。 -
因为原先作者的代码中设置了一个int型参数,在设置的这个epoch之后,将学习率变为原来的十分之一,从而进一步提高精度,尽可能达到最优,笔者也尝试对学习率和这一参数进行调整,也没有达到论文的精度。
-
最后,笔者去掉了之前添加的
combine_grad=True
,也就是将其设置为False,并且将loss_scale设置为了-1,也就是动态变化的。此时训练1个epoch需要1.6h左右,可见之前性能提升的主要作用者是更换了优化函数,combine_grad=True
只对性能提升起了较少的作用。此时的精度如下所示。可见精度已经达到甚至超过了论文的精度(第15个epoch,0.35)。
7.之后笔者又尝试在第15个epoch得到的model上继续进行训练,希望得到更多的精度,但之后的精度一直在0.30~0.34左右,没有再得到更高的精度,调整学习率后也是如此。但总之已经成功达到了论文的精度。
总结
本文介绍了模型迁移过程中NPU单P的性能调优和精度调优。