diff --git "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/PyTorch\347\246\273\347\272\277\346\216\250\347\220\206-FAQ.md" "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/PyTorch\347\246\273\347\272\277\346\216\250\347\220\206-FAQ.md"
index 521f3738395ea2d29253b369473bf771d80930b8..5a2f61dfae701307c5a24df34a5a1b92b8a35049 100644
--- "a/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/PyTorch\347\246\273\347\272\277\346\216\250\347\220\206-FAQ.md"
+++ "b/Ascend-PyTorch\347\246\273\347\272\277\346\216\250\347\220\206\346\214\207\345\257\274/PyTorch\347\246\273\347\272\277\346\216\250\347\220\206-FAQ.md"
@@ -5,21 +5,24 @@
- [2.1 如何查看 `ONNX/om/pbtxt` 模型](#21-如何查看-onnxompbtxt-模型)
- [2.2 `Exporting the operator {opname} to ONNX opset version {version} is not supported.`](#22-exporting-the-operator-opname-to-onnx-opset-version-version-is-not-supported)
- [2.3 resize不支持5d输入的解决方案](#23-resize不支持5d输入的解决方案)
+ - [2.4 循环(LOOP)结构](#24-循环(LOOP)结构)
- [3 OM离线推理失败问题汇总](#3-om离线推理失败问题汇总)
- [3.1 找不到atc命令或找不到ascend动态库](#31-找不到atc命令或找不到ascend动态库)
- [3.2 模型推理工具常见的错误&&解决方案](#32-模型推理工具常见的错误解决方案)
- [3.3 msame和benchmark在多batch下推理区别](#33-msame和benchmark在多batch下推理区别)
- [3.4 msame/benchmark推理提示实际输入和om输入size不一致](#34-msamebenchmark推理提示实际输入和om输入size不一致)
- [3.5 benchmark工具报错`ERROR Check free memory less 0.256 rate now wait!`](#35-benchmark工具报错error-check-free-memory-less-0256-rate-now-wait)
-- [4 精度调试常见问题](#4-精度调试常见问题)
-- [5 性能优化常见问题](#5-性能优化常见问题)
+- [4 精度相关问题](#4-精度相关问题)
+- [5 性能相关问题](#5-性能相关问题)
- [5.1 如何使用AIPP进行性能提升](#51-如何使用aipp进行性能提升)
-- [5.2 GPU推理(trtexec)报错](#52-gpu推理trtexec报错)
+ - [5.2 GPU推理(trtexec)报错](#52-gpu推理trtexec报错)
- [5.3 提升transpose的性能](#53-提升transpose的性能)
+ - [5.4 AICPU算子问题](#54-AICPU算子问题)
# 1 介绍
本文目标读者为Ascend PyTorch模型离线推理开发者,用于指导开发者在昇腾服务器的CANN软件环境中,实现模型离线推理精度性能达标。这里仅列举模型离线推理中遇到的常见问题与解决方法,持续更新。
**FAQ上传格式**
尽量以文本方式呈现,方便索引查找
+
- 标题
- 错误现象
- 原因分析
@@ -70,11 +73,11 @@
- 解决方案
使用 [MagicONNX工具](https://gitee.com/Ronnie_zheng/MagicONNX/tree/master) 进行改图,这里给出该问题的改图代码,更多功能详见[使用教程](https://gitee.com/Ronnie_zheng/MagicONNX/blob/master/docs/tutorials.md)和[API说明](https://gitee.com/Ronnie_zheng/MagicONNX/blob/master/docs/operations.md)
+
```python
import numpy as np
from magiconnx import OnnxGraph
-
-
+
def modify(path):
graph = OnnxGraph(path)
resizes = graph.get_nodes("Resize")
@@ -86,7 +89,7 @@
graph.add_initializer(f'shape_{node.name}', np.array(shapes[idx][0]))
reshape1.inputs = [node.inputs[0], f'shape_{node.name}']
reshape1.outputs = [f'Reshape_{node.name}']
-
+
graph[node.inputs[-1]].value = np.array(shapes[idx][1])
out_name = node.outputs[0]
node.set_input(0, f'Reshape_{node.name}')
@@ -108,12 +111,56 @@
reshape3.outputs = [out_name]
graph.save('modify.onnx')
-
+
if __name__ == "__main__":
modify('src.onnx')
```
+## 2.4 循环(LOOP)结构
+
++ 问题现象
+
+ 原始模型存在循环的Loop结构,导致静态模型节点不断堆叠,节点过多,onnx模型过大,无法打开。
+
++ 原因分析
+
+ 动态模型推理时,因为模型为动态编译,且Loop结构中,通常为重复调用相同的操作,不会涉及内存资源的累计。如下面的采样结构:
+
+ ```python
+ def farthest_point_sample(xyz, npoint):
+ """
+ Input:
+ xyz: pointcloud data, [B, N, 3]
+ npoint: number of samples
+ Return:
+ centroids: sampled pointcloud index, [B, npoint]
+ """
+ device = xyz.device
+ B, N, C = xyz.shape
+ centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
+ distance = torch.ones(B, N).to(device) * 1e10
+ farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
+ batch_indices = torch.arange(B, dtype=torch.long).to(device)
+ # 采样过程
+ for i in range(npoint):
+ centroids[:, i] = farthest
+ centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
+ dist = torch.sum((xyz - centroid) ** 2, -1)
+ mask = dist < distance
+ distance[mask] = dist[mask]
+ farthest = torch.max(distance, -1)[1]
+ return centroids
+ ```
+
++ 处理方案
+
+ 可采用两种方案:
+
+ + 修改loop代码,一些简单的loop结构可以通过基本算子进行替换:如一些取值或则拼接操作可以通过indext/concat操作替换
+ + 分离模型结构,遇到无法替换的loop结构,可以剥离loop结构到数据前处理或者后处理中,可参考案例:[PointNet++循环采样结构解决案例](https://gitee.com/wangjiangben_hw/ascend-pytorch-crowdintelligence-doc/blob/master/Ascend-PyTorch%E7%A6%BB%E7%BA%BF%E6%8E%A8%E7%90%86%E6%8C%87%E5%AF%BC/%E4%B8%93%E9%A2%98%E6%A1%88%E4%BE%8B/%E5%8A%9F%E8%83%BD%E6%89%93%E9%80%9A/PoinetNet++%E5%BE%AA%E7%8E%AF%E9%87%87%E6%A0%B7%E7%BB%93%E6%9E%84%E8%A7%A3%E5%86%B3%E6%A1%88%E4%BE%8B.md)
+
# 3 OM离线推理失败问题汇总
+
## 3.1 找不到atc命令或找不到ascend动态库
- 现象描述
```shell
@@ -222,9 +269,9 @@
bash build_local.sh
```
-# 4 精度调试常见问题
+# 4 精度相关问题
-# 5 性能优化常见问题
+# 5 性能相关问题
## 5.1 如何使用AIPP进行性能提升
原理介绍可以参考[使能AIPP](https://support.huaweicloud.com/atctool-cann503alpha2infer/atlasatc_16_0016.html)
- 使用方法
@@ -245,7 +292,7 @@
- 增加atc参数
在原有atc命令基础上增加 [--enable_small_channel=1](https://support.huaweicloud.com/atctool-cann503alpha2infer/atlasatc_16_0077.html) 和 [--insert_op_conf=path/to/insert_op.cfg](https://support.huaweicloud.com/atctool-cann503alpha2infer/atlasatc_16_0068.html#ZH-CN_TOPIC_0000001152734182)
-# 5.2 GPU推理(trtexec)报错
+## 5.2 GPU推理(trtexec)报错
+ 错误现象
@@ -276,8 +323,8 @@
对于算子支持问题,默认采用以下两种解决方案:
1. 采用更高版本的trt版本(默认为trt7.xxx),如trt8
- 2. 基于onnxruntime进行onnx的离线推理得到性能
- 3. 基于2.方案仍然不生效,则基于在线推理得到性能
+ 2. 基于onnxruntime进行onnx的离线推理得到性能
+ 3. 基于2.方案仍然不生效,则基于在线推理得到性能
2. 内存限制
@@ -300,22 +347,22 @@
```python
import torch
from torch import nn
-
+
class SrcCode(nn.Module):
def forward(self,x):
y = x.expand(1024, 1024, 3).transpose(0, 1)
return y
-
+
class Optimizer(nn.Module):
def forward(self,x):
t = x.reshape(1024,1,3).repeat((1,1024,1))
return t
-
+
src = SrcCode()
opt = Optimizer()
src.eval()
opt.eval()
-
+
input1 = torch.randn(1024,3)
out = src(input1)
out2 = opt(input1)
@@ -330,3 +377,68 @@
性能提升结果:整网性能提升270%,性能达标。


+
+## 5.4 AICPU算子问题
+
++ 问题现象
+
+ + 算子不支持直接,转换模型错误:
+
+
+
+ + 性能问题:
+
+ 
+
++ 原因分析
+
+ 相关算子如果不支持某一格式时,算子将不再再AIcore侧进行调用,而是直接走AICPU,会造成一定性能损失,甚至模型转换的时候直接报错,常见如:INT64格式(AICORE默认不支持INT64格式)
+
++ 处理方案
+
+ 可以通过改图规避,这里提供通用的转换INT64数据节点为INT32的方案,其他格式转换原理类似:
+
+ ```python
+ import numpy as np
+ from magiconnx import OnnxGraph
+
+ def value_to_int32(node):
+ node_value = node.value.copy()
+ if (node_value > MAXINT32).any():
+ node_value[node_value>MAXINT32] = MAXINT32
+ if (node_value < MININT32).any():
+ node_value[node_value