1 系统环境
硬件环境(Ascend/GPU/CPU): Ascend
MindSpore版本: mindspore=2.6.0
执行模式(PyNative/ Graph): 不限
Python版本: Python=3.9
操作系统平台: Linux
2 报错信息
2.1 问题描述
onnx模型转换为.mindir格式后,查看profiling数据,其中transdata算子耗时占了总耗时的23.6%,这种情况下一般是什么原因?
按照如下试了下,[acl_build_options]里的input_format=“ND”,[ge_session_options]里的ge.exec.formatMode=1都配置上,结果还是一样,这种情况是否可以说明和配置无关,就是部分算子不支持ND格式导致?
主要算子消耗是BatchMatmul、SelectV2、SoftmaxV2、LogSoftmaxV2、LayerNorm, 此时如何判断是哪些算子不支持ND格式?
试着看了下dump出来的ge图,softmax,batchMatmul,select等很多算子之前看起来都有transdata,是否正常?
尝试着又配置了下plugin_custom_ops=BatchMatmulToMatmul,想看看是否BMM和MM会不同,结果执行benchmark时加载模型报错:CreateDataBuffer] Malloc device buffer failed.
3 根因分析
TransData较多,主要是因为CANN算子中format的变化导致的,NZ和ND的format的变化,主要是Conv算子以及部分Norm类算子导致的,比较好的优化手段为融合算子,减少format的转换;当前默认是ND的格式,部分算子不支持ND,只能NZ,所以必然会有TransData;
4 解决方案
atchMatmul、SelectV2、SoftmaxV2、LogSoftmaxV2、LayerNorm
这些算子都是NZ的格式的,所以都会有transData,这个目前没法避免,只能尽可能的使用融合算子做等价替换,提升性能;
当前这些算子里面:
BatchMatmul建议替换成等价的MatmaulV2/V3;
SoftmaxV2确认一下是否可以融合成Attention(PFA或者IFA),这个得看看是否可以以及seq大小,seq len太小,没有什么收益;
LayerNorm可以考虑替换成LayerNormV3(性能应该是存在点收益的)