华为Ascend众智计划项目--3DMPPE_ROOTNET--Pytorch模型迁移至NPU(四)

系列文章目录

项目信息、本地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. 使用FusedSGD/FusedAdam, 参考链接, 使用combine_grad, 例如model, optimizer = amp.initialize(model, optimizer, opt_level=‘O2’, loss_scale=32.0, combine_grad=True)
  2. 使用taskset绑核起任务, 参考链接
  3. 同比例增大BS和LR, 充分利用NPU资源
  4. 使用NPU 亲和库函数替代原生函数,提升模型性能,参考链接
  5. AutoTune,详见性能调优工具说明
  • 笔者尝试了方法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)

精度优化首先请参考华为官方文档

  1. 在NPU单P可以跑通后,对模型进行训练,得到的模型精度如下表,左边的序号代表对应epoch结束后保存的model。
    在这里插入图片描述

  2. 可以看到第8个epoch结束后精度接近了论文精度,于是笔者在第7个第8个epoch保存的model的基础上继续训练,但精度一直维持在0.22~0.28,无法继续提升。

  3. 之后笔者尝试更改了amp中的loss_scale,由原来的none改为128.0,最终精度仍然维持在0.22~0.26左右,笔者又尝试注释掉了test.py中的cam_param.to(torch.int32),精度只有极小的提升。

  4. 之后笔者又注释掉了train.py中的.to(torch.int32)相关语句,并且将amp中的opt_level设置为了"O1",原先为"O2",loss_scale保持128.0不变,精度有所提升,但最高没有超过0.29。amp中opt_level改变的是性能,O2的性能相对来说高于O1,但笔者推测性能的提升会随之带来一些精度的下降。

  5. 因为原先作者的代码中设置了一个int型参数,在设置的这个epoch之后,将学习率变为原来的十分之一,从而进一步提高精度,尽可能达到最优,笔者也尝试对学习率和这一参数进行调整,也没有达到论文的精度。

  6. 最后,笔者去掉了之前添加的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的性能调优和精度调优。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值