使用Dump功能比对Ascend310和Ascend910推理过程中相同算子的输入和输出数据
本文主要分享在Ascend310和Ascend910的推理过程使用Dump功能比对相同算子的输入和输出数据,帮助定位问题算子。
一、使用该方法的前提条件和建议:
1.训练好的模型在Ascend910上推理精度已达到预期要求;
2.确保Ascend310上预处理图片结果是与Ascend910上处理结果是一致的;
3.当满足上述两点时,开发Ascend310推理过程中若遇到Ascend310上的推理精度与Ascend910上的推理精度有较大偏差时可以尝试用该方法定位问题算子;
4.建议使用一张相同的输入图片进行数据Dump。
二、Ascend910上Dump图和数据:
官网已给出训练过程中Dump功能操作流程:https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.3/dump_in_graph_mode.html?
推理过程使用Dump功能大同小异,下面对操作步骤进行总结:
1.使用静态图模式;
2.使用同步dump时json文件设置方式,需要将trans_flag设置为false;
{
"common_dump_settings": {
"dump_mode": 0,
"path": "/absolute_path",
"net_name": "ResNet50",
"iteration": 0,
"input_output": 0,
"kernels": ["Default/Conv-op12"],
"support_device": [0,1,2,3,4,5,6,7]
},
"e2e_dump_settings": {
"enable": true,
"trans_flag": false
}
}
3.配置环境变量:
export MINDSPORE_DUMP_CONFIG=/path/to/data_dump.json
4.随后运行推理脚本即可,Dump的数据和图会被保存在json文件设置的路径当中。
Dump生成的数据文件是后缀名为.bin的文件,可以使用numpy.fromfile命令查看具体数据,需要注意的是要根据文件名指定输出数据类型和shape。
np.fromfile('Default--decode-DetectionDecode--gather_topk-GatherTopK--Mod-op1608_input_0_shape_1_80_100_Int32_DefaultFormat.bin', dtype=np.int32).reshape((1, 80, 100))
对于图的两个文件,后缀名分别是.pb和.ir文件,.pb文件可以使用MindInsight查看,.ir可以使用vi命令查看。
三、Ascend310上Dump图和数据:
dump的图和数据可在全部配置完成后再运行推理脚本一起生成。
Dump图:
1.设置以下环境变量后重新运行推理脚本即可,需要将之前编译的c++文件删除,此外商用版本不具备此功能:
export DUMP_GE_GRAPH=2
2.运行推理脚本后,Dump下来的图会被保存在运行路径中,后缀名为.pbtxt文件,可安装netron包后使用如下命令查看,通常查看'ge_onnx_00000070_graph_0_Build.pbtxt'文件即可:
netron.start('ge_onnx_00000070_graph_0_Build.pbtxt')
Dump数据:
1.获取Mindir文件的图名,获取方式如下:
from mindspore.train._utils import read_proto
model = read_proto("mindir_path")
with open('mindir.log', 'w+') as f:
f.write(str(model))
生成mindir.log文件后使用如下命令:
grep -rn "name:" mindir.log |grep ": name"
输出类似图名:"4855_2425_1_construct_wrapper.101"
图名一定要正确,否则无法成功dump数据。
2.设置如下acl.json文件,注意json文件中的模型名需要在最后增加.0:
{
"dump":{
"dump_list":[
{
"model_name":"4855_2425_1_construct_wrapper.101.0"
}
],
"dump_path":"/absolute_path",
"dump_mode":"all"
}
}
3.修改main.cc文件:
#include "acl/acl.h"
aclInit("acl.json的绝对地址"); //加在main函数中
如输入数据类型为fp32还需要在main.cc文件添加以下语句:
ascend310->SetBufferOptimizeMode("off_optimize");
ascend310->SetPrecisionMode("allow_fp32_to_fp16");
ascend310->SetOpSelectImplMode("high_precision");
4.在CMakeList.txt文件添加如下语句:
include_directories(/usr/local/Ascend/fwkacllib/include/
../inc)
target_link_libraries(main ${MS_LIB} ${MD_LIB} ascendcl acl_dvpp acl_cblas gflags)
5.运行推理脚本前,需要提前创建好json文件中设置的保存dump数据的文件夹。
6.运行推理脚本后需要对dump下来的数据进行解析:
首先需要找到run包中提供的msaccucmp.py文件,在根目录下使用如下命令:
find ${run_path} -name "msaccucmp.py"
找到后使用如下命令进行解析:
python ${The absolute path of msaccucmp.py} convert -d {file path of dump} -out {file path of output}
解析的文件保存格式为.npy文件,可以使用numpy.load命令直接查看,不需要像910中设置数据类型和shape。
该过程在https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.3/dump_in_graph_mode.html?中的异步Dump数据分析样例中有详细描述。
四、Dump数据比对技巧:
1.根据生成的图找到对应算子所dump下来的输入和输出数据;
2.由于网络模型通常会比较大,可以采用区间查看的方法,找到Ascend310和Ascend910中第一次出现算子输入相同输出不同的算子。
五、其他注意事项:
1.310中conv2d算子不支持fp16,所以如果输入数据类型为fp32会前插cast将数据转为fp16,运算结束后再转回fp32;
2.Exp算子的输出范围为fp16,所以nn.Sigmoid算子输出张量会出现大量相同输出数据,不会影响推理结果;
3.目前ops.Mod算子在输入数据相同的情况下,在310和910上输出数据会有偏差,可用ops.FloorMod算子替代。