Toybrick

关于 pytorch 的 ZeroPad2d, 通过onnx 转rknn结果不一致

kkkaaa

中级会员

积分
203
楼主
发表于 2020-4-24 11:05:30    查看: 29596|回复: 10 | [复制链接]    打印 | 只看该作者
本帖最后由 kkkaaa 于 2020-4-24 11:12 编辑

模型的卷积用到 nn.ZeroPad2d, 似乎有问题,就单独拎出来测试转换。
torch -> onnx -> rknn (无量化): 可以转换成功,但是torch 和 rknn inference 结果不同,代码和结果都附在最后(虽然结果不一致,但是似乎有某种规律)
torch -> rknn(无量化):失败,
E Catch exception when loading pytorch model: little_model_zeropad.pt!
E Traceback (most recent call last):
E   File "rknn/api/rknn_base.py", line 611, in rknn.api.rknn_base.RKNNBase.load_pytorch
E   File "rknn/base/RKNNlib/app/importer/import_pytorch.py", line 97, in rknn.base.RKNNlib.app.importer.import_pytorch.ImportPytorch.run
E   File "rknn/base/RKNNlib/converter/convert_pytorch.py", line 573, in rknn.base.RKNNlib.converter.convert_pytorch.convert_pytorch.__init__
E   File "rknn/base/RKNNlib/converter/convert_pytorch.py", line 657, in rknn.base.RKNNlib.converter.convert_pytorch.convert_pytorch.model_simplify
E   File "rknn/base/RKNNlib/converter/convert_pytorch.py", line 113, in rknn.base.RKNNlib.converter.convert_pytorch.torch_inference_engine.shape_pick
E   File "rknn/base/RKNNlib/converter/convert_pytorch.py", line 148, in rknn.base.RKNNlib.converter.convert_pytorch.torch_inference_engine.__ir_shape_inference
E KeyError: 'aten::constant_pad_nd'



torch -> onnx -> rknn 的代码和输出结果
  1. class ZeroPadModel(nn.Module):
  2.     def __init__(self):
  3.         super(ZeroPadModel, self).__init__()
  4.         self.static_padding = nn.ZeroPad2d((0,1,0,1))

  5.     def forward(self, x):
  6.         x = self.static_padding(x)
  7.         return x


  8. # === torch 模型初始化 ===
  9. # net = Conv2dStaticSamePaddingModel(image_size)
  10. net = ZeroPadModel()
  11. print("==== network ====")
  12. print(net)
  13. net.eval()

  14. # === 转化1: torch2onnx ===
  15. print("--> torch model inference result")
  16. input_tensor = torch.rand(1,3, image_size, image_size)
  17. torch_out = torch.onnx._export(net, input_tensor, ONNX_MODEL, export_params=True)

  18. # === 转化2: onnx2rknn ===
  19. from rknn.api import RKNN
  20. rknn = RKNN()

  21. print('--> Loading model')
  22. ret = rknn.load_onnx(model=ONNX_MODEL)
  23. if ret != 0:
  24.     print('Load resnet50v2 failed!')
  25.     exit(ret)
  26. print('done')

  27. # Build model
  28. print('--> Building model')
  29. ret = rknn.build(do_quantization=False, dataset='./dataset.txt')
  30. if ret != 0:
  31.     print('Build resnet50 failed!')
  32.     exit(ret)
  33. print('done')

  34. # Export rknn model
  35. print('--> Export RKNN model')
  36. ret = rknn.export_rknn(RKNN_MODEL)
  37. if ret != 0:
  38.     print('Export resnet50v2.rknn failed!')
  39.     exit(ret)
  40. print('done')

  41. # === rknn inference ===
  42. # init runtime environment
  43. print("--> Init runtime environment")
  44. ret = rknn.init_runtime()
  45. if ret != 0:
  46.     print("Init runtime environment failed")
  47.     exit(ret)
  48. print('done')

  49. # inference
  50. print("--> Running rknn model")
  51. rknn_input = input_tensor.numpy().transpose(0,2,3,1)
  52. rknn_outputs = rknn.inference(inputs=[rknn_input], data_format='nhwc')[0][0]

  53. # === torch inference ===
  54. torch_inference_result = net(input_tensor)[0].detach().cpu().numpy()

  55. # === compare & show results ===
  56. print("--> compare inference")
  57. print("input shape: ", input_tensor.shape)
  58. print("rknn input shape: ", rknn_input.shape)
  59. print("torch_inference shape: ", torch_inference_result.shape)
  60. print("rknn_outputs shape: ", rknn_outputs.shape)

  61. print("max error: ", np.max(torch_inference_result - rknn_outputs))

  62. print("~~~~~~ torch model infer output ~~~~~~")
  63. print(torch_inference_result)
  64. print("~~~~~~ rknn model infer output ~~~~~~")
  65. print(rknn_outputs)
复制代码
输出:
~~~~~~ torch model infer output ~~~~~~
[[[0.05392462 0.12481469 0.        ]
  [0.44090217 0.44217068 0.        ]
  [0.         0.         0.        ]]

[[0.86402655 0.47992283 0.        ]
  [0.72332394 0.12081265 0.        ]
  [0.         0.         0.        ]]

[[0.92382944 0.56915957 0.        ]
  [0.28351116 0.7321489  0.        ]
  [0.         0.         0.        ]]]
~~~~~~ rknn model infer output ~~~~~~
[[[0.9238281  0.56884766 0.56884766]
  [0.28344727 0.7319336  0.7319336 ]
  [0.28344727 0.7319336  0.7319336 ]]

[[0.86376953 0.47973633 0.47973633]
  [0.72314453 0.12078857 0.12078857]
  [0.72314453 0.12078857 0.12078857]]

[[0.05392456 0.12475586 0.12475586]
  [0.44067383 0.44213867 0.44213867]
  [0.44067383 0.44213867 0.44213867]]]


补充:onnx model 和 torch model 输出结果一致


回复

使用道具 举报

kkkaaa

中级会员

积分
203
沙发
 楼主| 发表于 2020-4-24 15:31:59 | 只看该作者
本帖最后由 kkkaaa 于 2020-4-24 15:35 编辑

求助。。。>.<
希望能支持这个 op 的转化。。模型就差这一个 op 了
回复

使用道具 举报

jefferyzhang

版主

积分
13580
板凳
发表于 2020-4-24 15:58:12 | 只看该作者
我先帮你把问题报给NPU部门。。
回复

使用道具 举报

kkkaaa

中级会员

积分
203
地板
 楼主| 发表于 2020-4-27 15:17:37 | 只看该作者
jefferyzhang 发表于 2020-4-24 15:58
我先帮你把问题报给NPU部门。。

有没有可能在近期支持??
回复

使用道具 举报

jefferyzhang

版主

积分
13580
5#
发表于 2020-4-27 16:27:40 | 只看该作者
这个我不知道,我只有权利给他们提问题,他们解决了发布后才会通知我。。。
回复

使用道具 举报

kkkaaa

中级会员

积分
203
6#
 楼主| 发表于 2020-4-27 18:00:48 | 只看该作者
jefferyzhang 发表于 2020-4-27 16:27
这个我不知道,我只有权利给他们提问题,他们解决了发布后才会通知我。。。 ...

版主,我发现 ZeroPad2d 这个op 从 torch -> onnx -> rknn 为啥结果会不一致了

op = nn.ZeroPad2d((0,1,0,1))

输入 tensor 是
  1. tensor([[[[ 0.,  1.],
  2.           [ 2.,  3.]],

  3.          [[ 4.,  5.],
  4.           [ 6.,  7.]],

  5.          [[ 8.,  9.],
  6.           [10., 11.]]]])
复制代码


torch/onnx 的 pad 结果是
  1. [[[ 0.  1.  0.]
  2.   [ 2.  3.  0.]
  3.   [ 0.  0.  0.]]

  4. [[ 4.  5.  0.]
  5.   [ 6.  7.  0.]
  6.   [ 0.  0.  0.]]

  7. [[ 8.  9.  0.]
  8.   [10. 11.  0.]
  9.   [ 0.  0.  0.]]]
复制代码


rknn pad 结果是
  1. [[[ 0.  1.  1.]
  2.   [ 2.  3.  3.]
  3.   [ 2.  3.  3.]]

  4. [[ 4.  5.  5.]
  5.   [ 6.  7.  7.]
  6.   [ 6.  7.  7.]]

  7. [[ 8.  9.  9.]
  8.   [10. 11. 11.]
  9.   [10. 11. 11.]]]
复制代码


不知道这算不算 onnx->rknn 的 bug?? 或者是我哪里又犯错了。谢谢
回复

使用道具 举报

jefferyzhang

版主

积分
13580
7#
发表于 2020-4-27 18:23:27 | 只看该作者
kkkaaa 发表于 2020-4-27 18:00
版主,我发现 ZeroPad2d 这个op 从 torch -> onnx -> rknn 为啥结果会不一致了

op = nn.ZeroPad2d((0,1, ...

如果和原模型不和肯定是我们bug。。。
目前pytorch刚开始支持,问题还是会有的。。
回复

使用道具 举报

kkkaaa

中级会员

积分
203
8#
 楼主| 发表于 2020-4-27 18:27:15 | 只看该作者
jefferyzhang 发表于 2020-4-27 18:23
如果和原模型不和肯定是我们bug。。。
目前pytorch刚开始支持,问题还是会有的。。 ...

那就拜托你们啦
我还发现一个 rknn_input = input_tensor.numpy().transpose(0,2,3,1)的 channel 维的问题,在另一个帖子里提到了

回复

使用道具 举报

jefferyzhang

版主

积分
13580
9#
发表于 2020-5-25 11:46:44 | 只看该作者
NPU Team 答复:
1.3.2已经修复,请尝试下1.3.2是否正常
250242
回复

使用道具 举报

iamher0

注册会员

积分
111
10#
发表于 2020-6-10 14:10:09 | 只看该作者
jefferyzhang 发表于 2020-5-25 11:46
NPU Team 答复:
1.3.2已经修复,请尝试下1.3.2是否正常
250242

我在1.3.2依然遇到这个问题:
KeyError: 'aten::constant_pad_nd'
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表