更新时间:2024-04-30 GMT+08:00
分享

性能调优五板斧

性能调优相对来说门槛较高,对PyTorch以及昇腾AI处理器的理解越深刻,越能发挥昇腾AI处理器的计算能力,从而提高训练性能。一般情况下,通过对PyTorch代码做profiling,从而基于数据分析,调整代码,尽可能发挥硬件能力,但在做profiling数据分析前,通常可简单地基于性能优化五板斧先尝试做性能调优:

NPU融合算子API和亲和优化器

可对训练代码中的部分API替换成NPU融合算子API和亲和优化器,从而提升训练性能。但需要注意的是,在一些场景下,替换后的算子可能会对模型精度有影响,所以适配后,需要验证精度,如果确认有影响,需要在精度和性能之间做取舍。

  • NPU融合算子API

    识别融合算子和亲和优化器请参考工具使用,当前支持识别的融合算子API和亲和优化器请参考昇腾迁移融合算子API替换样例

  • NPU亲和优化器替换

    PyTorch原生优化器在训练过程中,一般需要下发多个NPU算子完成梯度和参数的更新计算,过多的算子下发,可能造成NPU空等。可将PyTorch优化器替换成NPU亲和优化器提高训练性能,详情请见此处

算子二进制调优

PyTorch Adaptor框架提供与算子编译相关的二进制配置参数,可设置模型编译时是否优先在线编译,以此优化模型训练性能。在main函数训练逻辑开始前通过以下函数设置(True为启动优先在线编译、False为取消优先在线编译)。

torch_npu.npu.set_compile_mode(jit_compile=False)

对于固定shape场景和动态shape场景,是否优先在线编译对训练性能带来不同的效果:

  • 固定shape场景:固定shape是指在模型计算过程中,模型的输入和输出的shape是固定的。如果优先在线编译,可根据当前获得的算子信息,进行融合和优化,在线编译出运行性能更优的算子。反之,则编译优化少,性能降低。
  • 动态shape场景:动态shape是指在模型计算过程中,模型的输入和输出存在多种shape。如果对动态shape的算子优先编译,会导致编译时间长训练性能差。如果取消优先编译,会优先查找当前编译好的算子二进制配置文件,如果存在则不在线编译算子;如果不存在,再进行在线编译。此时虽然编译优化少,但是没有编译时间,模型训练性能大概率比配置为优先编译高。

总结:

  • 如果模型中无动态shape,启动优先在线编译,可提高训练性能。
  • 如果模型中只有动态shape(该情况较少),关闭优先在线编译,模型训练性能大概率会更高。
  • 既有动态shape也有固定shape,启动优先在线编译对训练性能是否提升无法确定,因此可以在调整训练代码后,分别尝试开关优先在线编译后根据训练性能的优劣再设置。
    • Snt9B芯片默认关闭了优先在线编译,可通过以下命令获取当前模式。如果返回为False,代表已启动优先在线编译。
      print(torch_npu.npu.is_jit_compile_false())
    • 算子会根据该开关走不同的代码逻辑,如出现jit_compile切换后,代码运行失败的情况,需要联系昇腾技术支持获取帮助。

AOE自动性能调优

AOE(Ascend Optimization Engine)是一款自动调优工具,当训练模型全部为固定shape时,可选择AOE调优,具体操作参见此处。该优化会进行算子融合,将融合得到的图进行算子粒度切分,针对每一个融合算子子图生成不同的算子调优策略,从而实现最优的算子性能,并将得到的最优策略保存在算子知识库。性能调优期间只要做了代码修改后,可尝试运行AOE自动性能调优。

多进程绑核

相比于x86服务器,ARM服务器通常CPU核数更多,但单核性能更弱,因此更容易触发内核的负载均衡策略,该策略是通过启用进程迁移来降低繁忙的处理器压力。进程迁移会导致进程上下文切换、降低Cache命中率和跨numa内存访问等,从而影响训练性能。

如果使用docker容器作为训练环境,启动容器的时候,通过cpuset-cpus参数指定当前容器绑定的cpu核(如绑定16个cpu核60~75,命令示例为“docker run -d --cpuset-cpus=60-75 myimage bash”),这样容器中的进程只能在指定的CPU核上运行,达到绑核的效果。

优化数据处理

训练性能依赖训练数据是否及时准备好让NPU进行计算,因此需要尽量减少NPU等待数据准备的概率,主要优化方法包括:使用高性能图像预处理工具如opencv加速数据下沉到NPU设备数据预取与数据计算并行减少NPU与CPU数据交互等。

分享:

    相关文档

    相关产品