PaddlePaddle / Paddle2ONNX

ONNX Model Exporter for PaddlePaddle
Apache License 2.0
728 stars 172 forks source link

得到onnx的IR version为7,这个跟onnx版本有关么?如何得到IR version为3的模型 #164

Closed Z-Xiong closed 3 years ago

Channingss commented 3 years ago

@Z-Xiong 请问您想问的是算子的版本,还是protobuf的版本?

ONNX关于IR的官方介绍可以看这个文档: https://github.com/onnx/onnx/blob/master/docs/IR.md#open-neural-network-exchange---onnx

Z-Xiong commented 3 years ago

@Channingss 这个问题我已经解决,确实如您所说高版本IR兼容低版本,我使用onnx.load模型后对ir_version参数进行了修改。

但是碰到了一个问题: 我的目标框架只支持onnx1.4.1版本,我看到paddle2onnx对onnx最低的要求是onnx1.5版本,请问有方法可以把paddle转换到onnx1.4.1版本么?

Channingss commented 3 years ago

@Z-Xiong 你那边使用onnx1.4.1加载转换paddle2onnx转换出去的模型报什么错误?我们讨论onnx的版本问题,最好直接讨论如图中的:File format version 和Opset version ai.onnx 。我理解的你现在是遇到了File format version 的问题对吗?

image

Z-Xiong commented 3 years ago

@Channingss 感谢您的回答,我遇到的问题具体如下: 我的onnx版本如下: ir_version = 4 opset_verion=9

因为onnx.check会报告版本过高, 所以我通过onnx.load改为了ir_version = 3,并且将输入维度固定:

import onnx

# Preprocessing: load the model to be converted.
model_path = 'model-ir4-opset9-sim.onnx'
original_model = onnx.load(model_path)
original_model.ir_version = 3

dim_proto0 = original_model.graph.input[0].type.tensor_type.shape.dim[0]
dim_proto0.dim_value = 1

dim_proto2 = original_model.graph.input[0].type.tensor_type.shape.dim[2]
dim_proto2.dim_value = 224

dim_proto3 = original_model.graph.input[0].type.tensor_type.shape.dim[3]
dim_proto3.dim_value = 224

onnx.save(original_model, 'model-ir3-opset9-sim.onnx')
print('The model before conversion:\n{}'.format(original_model))

我是准备在rknpu上使用onxx,在onnx2rknn的过程中出现如下错误,好像是维度的问题:

warnings.warn(message) (op_type:Conv, name:): Inferred shape and existing shape differ in dimension 2: (112) vs (0) W Catch exception when polishing onnx model: RuntimeError('Inferred shape and existing shape differ in dimension 2: (112) vs (0)',). Ignored! (op_type:Conv, name:): Inferred shape and existing shape differ in dimension 2: (112) vs (0) E Catch exception when loading onnx model: paddle2onnx_model_sim_224.onnx! E Traceback (most recent call last): E File "rknn/api/rknn_base.py", line 556, in rknn.api.rknn_base.RKNNBase.load_onnx E File "rknn/base/RKNNlib/converter/convert_onnx.py", line 497, in rknn.base.RKNNlib.converter.convert_onnx.convert_onnx.__init__ E File "rknn/base/RKNNlib/converter/convert_onnx.py", line 519, in rknn.base.RKNNlib.converter.convert_onnx.convert_onnx.__init__ E File "/home/pxierra/miniconda3/envs/rknn1.4/lib/python3.6/site-packages/onnx/shape_inference.py", line 36, in infer_shapes E inferred_model_str = C.infer_shapes(model_str) E RuntimeError: Inferred shape and existing shape differ in dimension 2: (112) vs (0) Load mobilenetv1 failed!

模型部分netron可视化: 图片

paddle模型和转换到onnx并onnxsim后的模型链接如下: https://github.com/Z-Xiong/model.git

Channingss commented 3 years ago

@Z-Xiong 由于你手动改了onnx模型的输入shape,然后模型在shape inference的时候推理出来各节点的shape,和本身模型保存的各节点shape不一致,我建议你使用onnx-sim的时候,在不改onnx模型输入shape的基础上,指定input_shapes参数来固定shape:

https://github.com/daquexian/onnx-simplifier/blob/656f41748d0fce36ff57eaf39218401499570e84/onnxsim/onnx_simplifier.py#L298

Z-Xiong commented 3 years ago

@Channingss 我之前使用onnx-sim时有指定input shape如下: python -m onnxsim onnx_model/paddle2onnx_model.onnx onnx_model/paddle2onnx_model_sim.onnx --input-shape 1,3,224,224 但是导出的模型在使用时会出现如下错误:

W The channel_mean_value filed will not be used in the future!
E Catch exception when building RKNN model!
E Traceback (most recent call last):
E   File "rknn/api/rknn_base.py", line 895, in rknn.api.rknn_base.RKNNBase.build
E   File "rknn/api/rknn_base.py", line 1797, in rknn.api.rknn_base.RKNNBase._quantize2
E   File "rknn/base/RKNNlib/app/medusa/quantization.py", line 105, in rknn.base.RKNNlib.app.medusa.quantization.Quantization.run
E   File "rknn/base/RKNNlib/app/medusa/quantization.py", line 41, in rknn.base.RKNNlib.app.medusa.quantization.Quantization._run_quantization
E   File "rknn/base/RKNNlib/range/analyze_range.py", line 381, in rknn.base.RKNNlib.range.analyze_range.sparse_network
E   File "rknn/base/RKNNlib/range/analyze_range.py", line 360, in rknn.base.RKNNlib.range.analyze_range.analyze_activation_range
E   File "/home/pxierra/miniconda3/envs/rknn1.4/lib/python3.6/site-packages/numpy/core/numeric.py", line 192, in ones
E     a = empty(shape, dtype, order)
E ValueError: negative dimensions are not allowed

也正是因为错误中显示出现了负数维度,我才手动修改了sim后的模型输入维度,然后该报错会消失,产生昨天那种错误E RuntimeError: Inferred shape and existing shape differ in dimension 2: (112) vs (0) Load mobilenetv1 failed!。 我疑惑的是:

Channingss commented 3 years ago

@Z-Xiong paddle2onnx导出来的模型shape存在h,w=0,0,是因为该paddle模型的输入h,w都是不固定的,你的paddle模型是从哪里来的,你可以在导出paddle模型的时候固定shape。

Z-Xiong commented 3 years ago

@Channingss 是从paddleX可视化客户端导出的,paddlex导出的模型可以使用一些工具固定输入h和w么?

Z-Xiong commented 3 years ago

@Channingss 是从paddleX可视化客户端导出的,paddlex导出的模型可以使用一些工具固定输入h和w么?

已找到方法: https://paddlex.readthedocs.io/zh_CN/develop/deploy/export_model.html

PaddleX客户端在发布模型时没有固定输入大小,因此对于可视化客户端,请找到任务所在目录,从里面的output文件夹找到best_model模型目录,将此目录使用如上命令进行固定shape导出即可。---https://paddlex.readthedocs.io/zh_CN/develop/deploy/openvino/export_openvino_model.html

感谢大佬的耐心解答~