diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/AMCT/README.md" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/AMCT/README.md" index 22246408995cea1589de5a7fdffb57333ccf5a5e..e5d9729450d87f7108fae1aa13213f9cc44dedb5 100644 --- "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/AMCT/README.md" +++ "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/AMCT/README.md" @@ -1,12 +1,19 @@ # 使用amct工具解决HRNet-OCR模型内存不足问题案例 -[TOC] +- [使用amct工具解决HRNet-OCR模型内存不足问题案例](#使用amct工具解决hrnet-ocr模型内存不足问题案例) + - [1 模型背景](#1-模型背景) + - [2 问题现象](#2-问题现象) + - [3 调试思路](#3-调试思路) + - [3.1 定位阶段](#31-定位阶段) + - [3.2 解决思路](#32-解决思路) + - [4 解决方案](#4-解决方案) + - [5 关于内存不足问题的总结](#5-关于内存不足问题的总结) -## 模型背景 +## 1 模型背景 HRnet是semantic-segmentation类网络,目前是该网络输入shape和权重太大,导致om离线推理报内存不足的错误。 -## 问题现象 +## 2 问题现象 HRNet-OCR模型已经完成了转om,但是使用benchmark或者msame工具进行om推理时报错,直接运行报错如下 ```shell [INFO][VisionPreProcess] Create stream SUCCESS @@ -52,9 +59,9 @@ HRNet-OCR模型已经完成了转om,但是使用benchmark或者msame工具进 [ERROR] GE(27294,benchmark.x86_64):2021-11-25-03:24:58.052.325 [model_manager.cc:1249]27294 LoadModelOffline: ErrorNo: 4294967295(failed) [LOAD][DEFAULT][Init][DavinciModel] failed, ret:245000. ``` -## 调试思路 +## 3 调试思路 -### 定位阶段 +### 3.1 定位阶段 从日志来看是申请5G的featuremap空间导致device内存不够用所以报错了 ```shell @@ -106,13 +113,13 @@ root@8c11674f3fef:# grep "\[IMAS\]InitFeatureMapAndP2PMem graph_" zl_debug.log - [ERROR] ASCENDCL(57775,benchmark):2021-12-01-02:07:54.023.946 [memory.cpp:62]57799 aclrtMalloc: alloc device memory failed, runtime result = 207001 ``` -### 解决思路 +### 3.2 解决思路 硬件只有这么多空间,然后该模型输入shape也比较大 `1*3*1024*2048`,所以权重也比较大,目前可以考虑的方式就是amct工具进行模型量化。 amct对原始onnx模型做量化,将fp32的权重量化成int8的权重,这样可以节约空间,同时可以保证atc得到的om体积和占用内存小。对应前面的分析就是解决 **om占用了5.8G** 的问题。 -## 解决方案 +## 4 解决方案 - AMCT工具下载与安装 > 请确保onnxruntime版本是1.5.2或者1.6.0,否则下面安装会报错 @@ -142,6 +149,6 @@ amct对原始onnx模型做量化,将fp32的权重量化成int8的权重,这 将amct_onnx得到的量化onnx进行om转换,精度和性能调测等。 -## 关于内存不足问题的总结 +## 5 关于内存不足问题的总结 内存不足的情况很少遇见,所以碰到了需要生成详细的debug日志和调测文件,然后仔细分析。确认硬件限制后再根据具体的业务场景给出解决方案,量化是常用的手段 diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/numpy_data_cmp/README.md" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/numpy_data_cmp/README.md" deleted file mode 100644 index 1d8223ff19f121c4dfd1b2827d73bbb69e159773..0000000000000000000000000000000000000000 --- "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/numpy_data_cmp/README.md" +++ /dev/null @@ -1,26 +0,0 @@ -# 功能 - -逐个对比两个numpy的每一个数据,输出每个数据的误差,和最后统计的最大误差以及误差比(误差比=有误差的数据个数/数据总个数)。 - -**要求:** 两个numpy的数据个数必须一致。 - -# 使用示例 - -## 对比npy类型数据 - -```shell -python numpy_data_cmp.py --type=npy --left_data_path=./left_data.npy --right_data_path=./right_data.npy -``` - -## 对比bin类型数据 - -```shell -python numpy_data_cmp.py --type=bin --left_data_path=./left_data.npy --left_data_type=np.float32 --right_data_path=./right_data.npy --right_data_type=np.float32 -``` - -## 查看帮助 - -```shell -python numpy_data_cmp.py -h -``` - diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/numpy_data_cmp/\345\267\245\345\205\267Gitee\350\216\267\345\217\226\345\234\260\345\235\200.txt" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/numpy_data_cmp/\345\267\245\345\205\267Gitee\350\216\267\345\217\226\345\234\260\345\235\200.txt" deleted file mode 100644 index f7df4387a9af22adbc00090fca6b8ff01497ee40..0000000000000000000000000000000000000000 --- "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/numpy_data_cmp/\345\267\245\345\205\267Gitee\350\216\267\345\217\226\345\234\260\345\235\200.txt" +++ /dev/null @@ -1 +0,0 @@ -https://gitee.com/zhang-dongyu/onnx_tools \ No newline at end of file diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.imgs/1622597724195.png" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.imgs/1622597724195.png" deleted file mode 100644 index bfd01ce0cf55fe5978eba323205e9f14decc3873..0000000000000000000000000000000000000000 Binary files "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.imgs/1622597724195.png" and /dev/null differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.imgs/1622712256468.png" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.imgs/1622712256468.png" deleted file mode 100644 index 372af554113c6c69b597e123492a3ad7f32aeec4..0000000000000000000000000000000000000000 Binary files "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.imgs/1622712256468.png" and /dev/null differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.md" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.md" deleted file mode 100644 index 88d659772247bec39b56683a727c06a82c078ebf..0000000000000000000000000000000000000000 --- "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/README.md" +++ /dev/null @@ -1,67 +0,0 @@ -# 简介 - -一步式精度比对工具。基于[《 CANN 5.0.1 开发辅助工具指南 (推理) 01.pdf》](https://cmc-szv.clouddragon.huawei.com/cmcversion/index/releaseView?deltaId=3696745162342656&isSelect=inner&url_data=CANN%E8%B5%84%E6%96%99%3E%E6%A0%87%E5%87%86%E6%80%81%3Ezh%3E%E6%8E%A8%E7%90%86)的 **《7 精度比对工具使用指南》** ,串起流程,只需一步操作即可生成中间dump数据、对比结果Excel文件。 - -# 准备工作 - -- 需要提前准备[msame](https://gitee.com/ascend/tools/tree/master/msame#https://gitee.com/ascend/tools.git)工具。本代码仓提供编译好的,在`msame`文件夹下,根据自己的系统获取对应版本。若无法使用,则需要用户自己重新编译。 - -# 如何使用? - -1、根据实际情况修改`config.yaml`文件,例如: - -```yaml -input_info: - - bin_path: ./input_data/0.bin - shape: (1, 3, 224, 224) - dtype: np.float32 - input_name: image -om_path: ./wide_resnet50_2_bs1.om -onnx_path: ./wide_resnet50_2.onnx -dump_save_path: ./dump_data -npu_device_id: 0 -msame_path: ./msame/x86/msame -msaccucmp_py_path: /usr/local/Ascend/ascend-toolkit/latest/x86_64-linux/toolkit/tools/operator_cmp/compare/msaccucmp.py -env: | - export install_path=/usr/local/Ascend/ascend-toolkit/latest - export PATH=/usr/local/python3.7.5/bin:${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATH - export PYTHONPATH=${install_path}/atc/python/site-packages:$PYTHONPATH - export LD_LIBRARY_PATH=${install_path}/atc/lib64:${install_path}/acllib/lib64:$LD_LIBRARY_PATH - export ASCEND_OPP_PATH=${install_path}/opp -``` - -**参数说明&注意事项:** - -- bin_path:模型的输入数据 -- shape:此输入数据的维度,写成python tuple格式 -- dtype:此输入数据的类型,numpy类型写法,写成np.float32,np.int32,...,不可写成numpy.float32,numpy.int32,... -- input_name:此输入数据对应的onnx模型的输入名字 -- 若模型有多个输入,input_info数组一定要按照onnx模型图中的输入顺序提供,不可颠倒顺序,否则dump出的om数据不可靠,甚至无法dump出om数据 -- npu_device_id:所用的npu设备id,**若运行出现卡死,说明npu设备正在被使用,尝试使用其它设备** -- 新版cann toolkit中的`msaccucmp.pyc`已改为`msaccucmp.py` -- env:cann toolkit环境变量 - -2、输入如下命令,开始生成dump数据并对比: - -```shell -python one_step_accuracy_cmp.py config.yaml -``` - -**dump生成的目录说明:** - -![1622597724195](README.imgs/1622597724195.png) - -- 20210601210956:om模型dump出的原始数据 -- 20210601210956_om:om模型dump出的原始数据转numpy后的数据 -- 20210601210956_onnx:onnx模型的dump数据 -- 20210601210956_cmp:比对报告CSV文件存放目录 - -# 特别说明(必看) - -若从对比excel文件,或者**20210601210956_om**目录中发现om的dump数据都为0,或者感觉om dump出的数据比较奇怪,感觉不正确,那么atc转om的时候加上`--buffer_optimize=off_optimize`关闭数据缓存优化,再运行一遍,看结果是否符合预期。 - -缓存优化默认是开启的,有些om在开启缓存优化后dump出的数据都是0,而有些om的某些节点dump出的数据是0,导致比对结果看起来不正常。 - -个人建议,先不关闭缓存优化,对比一遍,然后再关闭缓存优化对比一遍,比较两次得到的Excel文件。 - -![1622712256468](README.imgs/1622712256468.png) \ No newline at end of file diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/\345\267\245\345\205\267Gitee\350\216\267\345\217\226\345\234\260\345\235\200.txt" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/\345\267\245\345\205\267Gitee\350\216\267\345\217\226\345\234\260\345\235\200.txt" deleted file mode 100644 index f7df4387a9af22adbc00090fca6b8ff01497ee40..0000000000000000000000000000000000000000 --- "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\233\270\345\205\263\345\267\245\345\205\267/one_step_accuracy_cmp/\345\267\245\345\205\267Gitee\350\216\267\345\217\226\345\234\260\345\235\200.txt" +++ /dev/null @@ -1 +0,0 @@ -https://gitee.com/zhang-dongyu/onnx_tools \ No newline at end of file diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/1. \347\262\276\345\272\246\345\210\206\346\236\220\346\265\201\347\250\213.docx" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/1. \347\262\276\345\272\246\345\210\206\346\236\220\346\265\201\347\250\213.docx" deleted file mode 100644 index 296d7a99099694064e3435f9a286c7d98d79b224..0000000000000000000000000000000000000000 Binary files "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/1. \347\262\276\345\272\246\345\210\206\346\236\220\346\265\201\347\250\213.docx" and /dev/null differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/2. \344\270\200\346\255\245\345\274\217\347\262\276\345\272\246\346\257\224\345\257\271\345\267\245\345\205\267\344\275\277\347\224\250\346\225\231\347\250\213.docx" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/2. \344\270\200\346\255\245\345\274\217\347\262\276\345\272\246\346\257\224\345\257\271\345\267\245\345\205\267\344\275\277\347\224\250\346\225\231\347\250\213.docx" deleted file mode 100644 index 35c8ae47f4ebc7fb583062795f2b3029c428c5ef..0000000000000000000000000000000000000000 Binary files "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/2. \344\270\200\346\255\245\345\274\217\347\262\276\345\272\246\346\257\224\345\257\271\345\267\245\345\205\267\344\275\277\347\224\250\346\225\231\347\250\213.docx" and /dev/null differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/3. OXInterface\344\275\277\347\224\250\346\225\231\347\250\213\357\274\210\344\270\200\345\245\227\346\223\215\344\275\234\347\256\200\345\215\225\347\232\204ONNX\346\224\271\345\233\276\346\216\245\345\217\243\357\274\211.docx" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/3. OXInterface\344\275\277\347\224\250\346\225\231\347\250\213\357\274\210\344\270\200\345\245\227\346\223\215\344\275\234\347\256\200\345\215\225\347\232\204ONNX\346\224\271\345\233\276\346\216\245\345\217\243\357\274\211.docx" deleted file mode 100644 index 7871b376336f146a16c58334728134b20b49b5a4..0000000000000000000000000000000000000000 Binary files "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/3. OXInterface\344\275\277\347\224\250\346\225\231\347\250\213\357\274\210\344\270\200\345\245\227\346\223\215\344\275\234\347\256\200\345\215\225\347\232\204ONNX\346\224\271\345\233\276\346\216\245\345\217\243\357\274\211.docx" and /dev/null differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/README.md" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/README.md" new file mode 100644 index 0000000000000000000000000000000000000000..38c3aa051871c76a718bbcad36c10f0bc5a6222b --- /dev/null +++ "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/README.md" @@ -0,0 +1,216 @@ +# 精度调试工具及流程介绍 + +- [精度调试工具及流程介绍](#精度调试工具及流程介绍) + - [1 案例背景](#1-案例背景) + - [2 排除前后处理脚本引入的精度问题](#2-排除前后处理脚本引入的精度问题) + - [2.1 前处理脚本精度定位](#21-前处理脚本精度定位) + - [2.2 后处理脚本精度定位](#22-后处理脚本精度定位) + - [3 om引入的精度问题](#3-om引入的精度问题) + - [3.1 ATC转换的参数引入的误差](#31-atc转换的参数引入的误差) + - [3.2 使用msquickcmp工具进行快速定位](#32-使用msquickcmp工具进行快速定位) + - [3.3 单算子精度验证对比](#33-单算子精度验证对比) + - [3.4 针对有自定义算子的网络精度定位](#34-针对有自定义算子的网络精度定位) + +## 1 案例背景 + +om模型离线推理发现精度异常,不知道该如何定位精度 + +## 2 排除前后处理脚本引入的精度问题 + +### 2.1 前处理脚本精度定位 + +运行 `preprocess.py` 生成输入bin,然后用在线推理代码加载bin文件与dataloader输出tensor进行精度对比 +> 这里给出的数据比较方法是相对误差和绝对误差,还可以使用 `torch.nn.functional.cosine_similarity` 或者 `sklearn.metrics.pairwise.cosine_similarity` 余弦相似度进行评价比较。 + +```python +# 在线推理代码 +def eval(): + # 创建dataloader等相关代码 + data_loader = create_dataloader(args, **kwargs) + + # 初始化model并加载权重 + model = Model(args, **kwargs) + checkpoint = torch.load('/path/to/model.pth', map_location='cpu') + model.load_state_dict(checkpoint) + + for idx, data in enumerate(data_loader): + # 加载bin文件并转成torch.tensor + # WARNING:可能需要处理dtype和shape + preprocess = torch.from_numpy(np.fromfile(f'/path/to/preprocess/input_{idx}.bin')) + + # float32数据误差1e-6,fp16误差1e-3,int误差1【也可以使用余弦相似度】 + diff = (data - preprocess).abs() > 1e-6 + diff_ratio = diff.num() / data.numel() + if (diff.num() > 0) or (diff_ratio > 0): + print("预处理脚本可能存在问题,需要检查。", + "也可能是阈值设置不合理,需要确认。") + break + continue + + # 前处理精度不涉及在线推理,continue跳过 + output = model(data) + ... + + else: + print("数据集遍历完毕,预处理脚本没有精度问题") +``` + +### 2.2 后处理脚本精度定位 +将在线推理结果保存到bin文件与 `postprocess.py` 结果进行精度对比 + +- 将在线推理结果保存成bin文件 + + ```python + # 在线推理代码 + def eval(): + # 创建dataloader等相关代码 + data_loader = create_dataloader(args, **kwargs) + + # 初始化model并加载权重 + model = Model(args, **kwargs) + checkpoint = torch.load('/path/to/model.pth', map_location='cpu') + model.load_state_dict(checkpoint) + + for idx, data in enumerate(data_loader): + output = model(data) + output.numpy().tofile(f'/path/to/gt/output_{idx}.bin') + continue + + # 跳过在线推理中的后处理逻辑 + ... + ``` + +- 利用在线推理的结果验证后处理脚本 + + 假设精度评测指标是准确率,直接运行开源仓 `eval.py` 脚本得到的精度指标是 **acc@top1:84.16%**。 + + 运行如下命令后可以判断后处理脚本是否会引入精度问题: + ```shell + # 利用gt计算出精度评价指标 + python postprocess.py --input_bin_dir '/path/to/gt' + ``` + - `postprocess.py` 使用gt生成的bin处理得到的精度指标等于 `acc@top1:84.16%`,**后处理脚本正常** + - 否则,**后处理脚本异常** + +## 3 om引入的精度问题 + +### 3.1 ATC转换的参数引入的误差 + +> 这种情况很少见,部分网络在复用内存和数据优化中可能会引入精度问题 + +atc进行om模型转换时设置 [--buffer_optimize=off_optimize](https://support.huaweicloud.com/atctool-cann504alpha3infer/atlasatc_16_0083.html) 关闭数据缓存优化,然后进行om推理看看精度是否正常。 + + +### 3.2 使用[msquickcmp工具](https://gitee.com/ascend/tools/tree/master/msquickcmp)进行快速定位 + +- 准备工作 + + ```shell + # 下载工程 + git clone git@gitee.com:ascend/tools.git + cd tools/msquickcmp + + # 设置环境变量 + export install_path=/usr/local/Ascend/ascend-toolkit/latest + export DDK_PATH=${install_path} + export NPU_HOST_LIB=${install_path}/acllib/lib64/stub + export PATH=/usr/local/python3.7.5/bin:${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATH + export PYTHONPATH=${install_path}/atc/python/site-packages:$PYTHONPATH + export LD_LIBRARY_PATH=${install_path}/atc/lib64:${install_path}/acllib/lib64:$LD_LIBRARY_PATH + export ASCEND_OPP_PATH=${install_path}/opp + ``` + +- 程序执行 + + 推荐使用真实数据进行精度对比。 + ```shell + # 指定输入bin文件,一般是真实数据输入 + python3 main.py -m /path/to/src.onnx \ + -om /path/to/dst.om \ + -i /path/to/input.bin \ + -c ${install_path} \ + -o /path/to/result + + # 不指定模型输入,内部生成随机输入数据 + python3 main.py -m /path/to/src.onnx \ + -om /path/to/dst.om \ + -c ${install_path} \ + -o /path/to/result + ``` + +- 输出文件说明 + + 在 `-o /path/to/result` 所指定的输出目录下会生成一个 **result_xxx.csv** 文件,根据如下步骤快速定位精度异常算子: + + - 查找 **E列CosineSimilarity** 第一个余弦相似度值 **<0.99** 的算子(忽略NaN值),比如在第N行 + - 找到N行的 **B列LeftOp** 所对应的昇腾算子,即为精度异常算子 + > 特别说明: + > - transdata算子作用是将NCHW或者NCDHW格式的通用数据格式转换为NPU亲和的内部数据格式,可不必考虑精度问题 + > - name为ConvRelu这种算子表示ATC工具内部进行了算子融合,目的是提升性能,可不必考虑精度问题 + ![](img/precision_03.png) + +| 参数 | 说明 | +| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| LeftOp | om模型的算子名。 | +| RightOp | onnx模型的算子名。 | +| TensorIndex | om模型算子的input ID和output ID。 | +| CosineSimilarity | 进行余弦相似度算法比对出来的结果,范围是[-1,1],比对的结果如果越接近1,表示两者的值越相近,越接近-1意味着两者的值越相反。 | +| MaxAbsoluteError | 进行最大绝对误差算法比对出来的结果,值越接近于0,表明越相近,值越大,表明差距越大。 | +| AccumulatedRelativeError | 进行累积相对误差算法比对出来的结果,值越接近于0,表明越相近,值越大,表明差距越大。 | +| RelativeEuclideanDistance | 进行欧氏相对距离算法比对出来的结果,值越接近于0,表明越相近,值越大,表明差距越大。 | +| KullbackLeiblerDivergence | 进行KLD散度算法比对出来的结果,取值范围是0到无穷大。KL散度越小,真实分布与近似分布之间的匹配越好。 | +| StandardDeviation | 进行标准差算法比对出来的结果,取值范围:0到无穷大。标准差越小,离散度越小,表明越接近平均值。该列显示om和onnx两组数据的均值和标准差,第一组展示om模型dump数据的数值(均值;标准差),第二组展示onnx模型dump数据的数值(均值;标准差)。 | + +### 3.3 单算子精度验证对比 + +- 解析npu dump数据 + + > 这里默认msquickcmp使用真实数据进行精度对比 + ```shell + # 将dump的原始数据解析成npy文件并保存到/path/to/npy路径(需要自定义设置)下 + python /usr/local/Ascend/ascend-toolkit/latest/tools/operator_cmp/compare/msaccucmp.py convert -d /path/to/result/${timestamp}/dump_data/1/${model_name}/1/0/ -out /path/to/npy + ``` + +- 对比onnx与om输入输出数据的数值精度 + + 根据算子名字对比算子输出npy文件,其中onnx每个算子的输出npy在 `/path/to/result/${timestamp}/dump_data/onnx` 下,直接使用 `numpy.load` 加载即可,建议使用 `torch.nn.functional.cosine_similarity` 或者 `sklearn.metrics.pairwise.cosine_similarity` 余弦相似度进行比较,余弦相似度低于0.99的即可认为存在异常。 + +### 3.4 针对有自定义算子的网络精度定位 +- 使用 [msame工具](https://gitee.com/ascend/tools/tree/master/msame) dump数据 + + > - 因为自定义算子不能使用onnxruntime进行推理,所以无法使用 `msquickcmp` 工具进行精度对比快速定位异常算子。只能通过dump数据+二分法进行精度异常算子定位 + + ```shell + # dump数据 + ./msame --model "/path/to/model.om" --input "/path/to/actual_input.bin" --output "/path/to/result/" --outfmt BIN --device 1 --dump true + + # 解析数据 + python /usr/local/Ascend/ascend-toolkit/latest/tools/operator_cmp/compare/msaccucmp.py convert -d /path/to/result/${timestamp}/dump_data/1/${model_name}/1/0/ -out /path/to/npy + ``` + 然后om的每个算子输出会保存在 `/path/to/npy` 目录下 + - 因为msame默认只保存算子输出,如果想同时保存算子的输入输出可以[修改msame源码](https://gitee.com/ascend/tools/blob/master/msame/src/utils.cpp#L257)后编译 + ```c++ + ofstream outstr("acl.json", ios::out); + outstr << "{\n\"dump\": {\n \"dump_path\": \""; + outstr << out_dump_path << "\",\n "; + // outstr << "\"dump_mode\": \"output\",\n \"dump_list\": [{\n "; + // 修改点 + outstr << "\"dump_mode\": \"all\",\n \"dump_list\": [{\n "; + outstr << " \"model_name\": \"" << modelName << "\"\n }]\n"; + outstr << " }\n}"; + outstr.close(); + ``` +- 借助verbose信息对比pytorch在线推理和om算子结果进行对比 + + > onnx不能推理,所以om只能直接和pytorch源码进行精度对比 + 以自定义算子为anchor,在其附近寻找一个合适的算子进行om和pytorch算子精度对比,如果输出精度正常则二分往下找,否则二分往上找。 + +- 例子 + + ONNX模型中 `matmul+add+add` 融合成om中的 `BatchMatmulV2` 算子,以自定义算子col2im为anchor,发现 `BatchMatmulV2` 与ONNX中的第二个add输出等价,所以用这个算子输出进行比较。 + + + **通过verbose确定ONNX中的Add对应pytorch源码中哪行代码** + ![precision_02](./img/precision_02.png) + + 然后在python代码中通过pdb设置断点的方式获取pytorch算子输出,将该输出与om保存的npy输出进行对比查看精度(推荐使用余弦相似度比较) diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_01.png" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_01.png" new file mode 100644 index 0000000000000000000000000000000000000000..aad812951a9d21f2b52de0043325786f179f6b20 Binary files /dev/null and "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_01.png" differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_02.png" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_02.png" new file mode 100644 index 0000000000000000000000000000000000000000..0faab7d42742fb8467d771d41939a439b9639a16 Binary files /dev/null and "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_02.png" differ diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_03.png" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_03.png" new file mode 100644 index 0000000000000000000000000000000000000000..2d43523c95221c8a53b1f4601b69e0c7cba7e319 Binary files /dev/null and "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/\344\270\223\351\242\230\346\241\210\344\276\213/\347\262\276\345\272\246\350\260\203\350\257\225/img/precision_03.png" differ