性能调优
性能分析工具PyTorch Profiling
pytorch profiling功能是继承自原生pytorch的功能,主要记录了pytorch框架层面的算子在多次分发中调用栈的耗时信息,而对于算子在CANN内的流程,只能作为一整块展示,无法详细展示内部流程。
-
使用torch.autograd.profiler打印或导出trace文件
-
trace文件导入chrome://tracing可视化
-
使用工具栏或快捷键(W/A/S/D)查看
-
将profiling与模型代码对应,识别性能瓶颈点。可同时跑出GPU与NPU的trace进行对比。
性能分析工具CANN Profiling
CANN Profiling则是仅针对CANN层内算子执行流程来记录性能信息,主要功能是分析算子在NPU设备上的执行性能,可以清晰看出算子在不同shape/format下耗时信息。
-
收集profiling数据,生成PROF_xxx目录

-
解析profiling数据

调优手段1:使用亲和的数据类型
- Cube计算单元支持Float16,算力高,使用AMP训练。
- AICore不支持torch.LongTensor类型,会自动切换AICPU,影响性能。

调优手段2:优化调度耗时(融合tensor)
梯度更新

梯度清零

调优手段2:优化调度耗时(融合算子)
自定义算子可能影响跨平台转模型推理,建议只在损失计算部分使用。
torch.nn.functional.one_hot()

torch.npu_one_hot()

torch.npu_confusion_transpose

调优手段3:非连续内存转连续内存
非连续转连续问题是所有芯片厂商都会遇到的问题,Cuda非element-wise类算子以及CuDNN类算子均需要连续Tensor输入。 而NPU芯片则问题更为突出,究其原因是NPU采用SMID指令架构,对访存有连续性要求。需要框架层将非连续的PyTorch Tensor通过统一接口format_contiguous()转为连续/匹配Tensor。

参考link1,link2,link3
调优手段4:使用自动调优工具AOE
对于NPU设备,算子输入参数的信息(shape/format等)会影响算子的性能,进而影响模型整体性能。为了使模型获得更良好的性能,可以将模型中所有的算子的输入参数信息获取至本地进行分析(dump),然后将每个算子在NPU上运行,调整算子运行时的策略,确定性能最佳的策略。以上这个过程称为调优,AOE工具则实现了这样的调优功能,可以用于提升模型的性能。
-
dump算子信息
-
执行调优
-
生成知识库,重新拉起自动使用
<aside> 💡 注意事项:
- 目前仅支持静态算子,动态算子暂不支持。
- dump算子信息时,目前无法对算子信息去重,且仅需执行一个step,否则会导致调优时间过长。
- 建议使用1P脚本进行dump图,多P会存在dump覆盖的问题。
- 使用前需关闭profiling工具,否则会影响模型性能。
</aside>
调优手段5:绑核,提升CPU性能
ARM服务器通常CPU核数更多,但单核性能弱于X86,因此更容易触发内核的负载均衡策略,启用进程迁移来降低繁忙的处理器压力。进程迁移时会导致进程上下文切换、降低Cache命中率,跨numa内存访问等。绑核可以减小此类现象对训练效率的影响。
为了提升host性能,解释一下原理 numa就是为了在cpu数量增加的背景下,避免不同区域之间的CPU和内存进行远程访问,而搞得一种机制,这种机制会使得虚拟机的CPU和内存都使用同一个node区域内的,避免的不同node之间的cpu和内存的跨区域访问。 虚拟机的线程在当前分配的CPU中按需分配CPU资源。此时虚拟机线程占用的CPU核是固定的,虚拟机的线程被固定分配到的CPU上进行调度,从而避免了线程在不同的CPU核进行切换的时间。 在NUMA架构下,整个内存空间在物理上是分布式的,所有这些内存的集合就是整个系统的全局内存。每个核访问内存的时间取决于内存相对于处理器的位置,访问本地内存(本节点内)会更快一些。 不同节点间相距的距离不同,距离越远,跨NUMA内存访问的延时越大。应用程序运行时应减少跨NUMA访问内存。


性能调优
性能分析工具PyTorch Profiling
pytorch profiling功能是继承自原生pytorch的功能,主要记录了pytorch框架层面的算子在多次分发中调用栈的耗时信息,而对于算子在CANN内的流程,只能作为一整块展示,无法详细展示内部流程。
使用torch.autograd.profiler打印或导出trace文件
trace文件导入chrome://tracing可视化
使用工具栏或快捷键(W/A/S/D)查看
将profiling与模型代码对应,识别性能瓶颈点。可同时跑出GPU与NPU的trace进行对比。
性能分析工具CANN Profiling
CANN Profiling则是仅针对CANN层内算子执行流程来记录性能信息,主要功能是分析算子在NPU设备上的执行性能,可以清晰看出算子在不同shape/format下耗时信息。
收集profiling数据,生成PROF_xxx目录
with torch.npu.profile('./cann_prof'): # 一般只需要执行1个step即可 out = model(input_tensor) loss=loss_func(out,target) loss.backward() optimizer.zero_grad() optimizer.step()解析profiling数据
调优手段1:使用亲和的数据类型
import torch import torch_npu x = torch.rand(100, 100).npu() x1 = torch.rand(100, 100).npu().long() with torch.npu.profile('./result'): x + x x1 + x1调优手段2:优化调度耗时(融合tensor)
梯度更新
梯度清零
调优手段2:优化调度耗时(融合算子)
自定义算子可能影响跨平台转模型推理,建议只在损失计算部分使用。
torch.nn.functional.one_hot()
torch.npu_one_hot()
torch.npu_confusion_transpose
调优手段3:非连续内存转连续内存
非连续转连续问题是所有芯片厂商都会遇到的问题,Cuda非element-wise类算子以及CuDNN类算子均需要连续Tensor输入。 而NPU芯片则问题更为突出,究其原因是NPU采用SMID指令架构,对访存有连续性要求。需要框架层将非连续的PyTorch Tensor通过统一接口format_contiguous()转为连续/匹配Tensor。
参考link1,link2,link3
调优手段4:使用自动调优工具AOE
对于NPU设备,算子输入参数的信息(shape/format等)会影响算子的性能,进而影响模型整体性能。为了使模型获得更良好的性能,可以将模型中所有的算子的输入参数信息获取至本地进行分析(dump),然后将每个算子在NPU上运行,调整算子运行时的策略,确定性能最佳的策略。以上这个过程称为调优,AOE工具则实现了这样的调优功能,可以用于提升模型的性能。
dump算子信息
执行调优
生成知识库,重新拉起自动使用
<aside> 💡 注意事项:
</aside>
调优手段5:绑核,提升CPU性能
ARM服务器通常CPU核数更多,但单核性能弱于X86,因此更容易触发内核的负载均衡策略,启用进程迁移来降低繁忙的处理器压力。进程迁移时会导致进程上下文切换、降低Cache命中率,跨numa内存访问等。绑核可以减小此类现象对训练效率的影响。
为了提升host性能,解释一下原理 numa就是为了在cpu数量增加的背景下,避免不同区域之间的CPU和内存进行远程访问,而搞得一种机制,这种机制会使得虚拟机的CPU和内存都使用同一个node区域内的,避免的不同node之间的cpu和内存的跨区域访问。 虚拟机的线程在当前分配的CPU中按需分配CPU资源。此时虚拟机线程占用的CPU核是固定的,虚拟机的线程被固定分配到的CPU上进行调度,从而避免了线程在不同的CPU核进行切换的时间。 在NUMA架构下,整个内存空间在物理上是分布式的,所有这些内存的集合就是整个系统的全局内存。每个核访问内存的时间取决于内存相对于处理器的位置,访问本地内存(本节点内)会更快一些。 不同节点间相距的距离不同,距离越远,跨NUMA内存访问的延时越大。应用程序运行时应减少跨NUMA访问内存。