README.md 4.93 KB
Newer Older
yaoht's avatar
yaoht committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# Paddle 模型转换为 ONNX 模型

## 1. 环境搭建

- 安装PaddlePaddle
```shell script
pip install paddlepaddle
```

- 安装onnxruntime >= 1.10.0
```shell script
pip install onnxruntime
```

- 安装onnx
```
pip install onnx
```

- 安装paddle2onnx
```shell script
pip install paddle2onnx
```

## 2. caffe2onnx 工具使用

### 2.1获取PaddlePaddle部署模型

将paddle模型转换成onnx之前,请注意,所必需的模型文件:

- `model_name.pdmodel`: 表示模型结构

- `model_name.pdiparams`: 表示模型参数

  [**注意**] 这里需要注意,两个文件其中参数文件后辍为 `.pdiparams`,如你的参数文件后辍是 `.pdparams` ,那说明你的参数是训练过程中保存的,当前还不是部署模型格式。

示例模型[下载地址](https://bj.bcebos.com/paddle2onnx/model_zoo/resnet50.tar.gz),下载模型后解压文件

```shell
tar -zxvf resnet50.tar.gz
```

## 命令行转换

```bash
paddle2onnx --model_dir resnet50 --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file model.onnx
```

可调整的转换参数如下表,具体可参考[官网](https://github.com/PaddlePaddle/Paddle2ONNX):

| 参数                       | 参数说明                                                     |
| -------------------------- | ------------------------------------------------------------ |
| --model_dir                | 配置包含 Paddle 模型的目录路径                               |
| --model_filename           | **[可选]** 配置位于 `--model_dir` 下存储网络结构的文件名     |
| --params_filename          | **[可选]** 配置位于 `--model_dir` 下存储模型参数的文件名称   |
| --save_file                | 指定转换后的模型保存目录路径                                 |
| --opset_version            | **[可选]** 配置转换为 ONNX 的 OpSet 版本,目前支持 7~16 等多个版本,默认为 9 |
| --enable_onnx_checker      | **[可选]** 配置是否检查导出为 ONNX 模型的正确性, 建议打开此开关, 默认为 False |
| --enable_auto_update_opset | **[可选]** 是否开启 opset version 自动升级功能,当低版本 opset 无法转换时,自动选择更高版本的 opset进行转换, 默认为 True |
| --deploy_backend           | **[可选]** 量化模型部署的推理引擎,支持 onnxruntime、tensorrt 或 others,当选择 others 时,所有的量化信息存储于 max_range.txt 文件中,默认为 onnxruntime |
| --save_calibration_file    | **[可选]** TensorRT 8.X版本部署量化模型需要读取的 cache 文件的保存路径,默认为 calibration.cache |
| --version                  | **[可选]** 查看 paddle2onnx 版本                             |
| --external_filename        | **[可选]** 当导出的 ONNX 模型大于 2G 时,需要设置 external data 的存储路径,推荐设置为:external_data |
| --export_fp16_model        | **[可选]** 是否将导出的 ONNX 的模型转换为 FP16 格式,并用 ONNXRuntime-GPU 加速推理,默认为 False |
| --custom_ops               | **[可选]** 将 Paddle OP 导出为 ONNX 的 Custom OP,例如:--custom_ops '{"paddle_op":"onnx_op"},默认为 {} |

## 修改模型shape

如果想要将输入name为image的模型model.onnx修改为shape[256, 3, 224, 224],可以用一下命令:

```bash
python -m paddle2onnx.optimize --input_model model.onnx --output_model new_model.onnx --input_shape_dict="{'inputs': [256, 3, 224, 224]}"
```

如果不知道模型的输入name,可以使用一下python脚本获知:

```shell
python get_model_input_output_info.py
```

其中get_model_input_output_info.py代码如下,替换model.onnx的路径即可查询自己的模型的输入输出信息。

```python
import onnx

def get_input_details(onnx_file):
    # 加载ONNX模型
    model = onnx.load(onnx_file)

    # 获取输入信息
    input_details = []
    for input in model.graph.input:
        input_name = input.name
        input_shape = [dim.dim_value for dim in input.type.tensor_type.shape.dim]
        input_details.append((input_name, input_shape))

    return input_details

def get_output_details(onnx_file):
    # 加载ONNX模型
    model = onnx.load(onnx_file)

    # 获取输出信息
    output_details = []
    for output in model.graph.output:
        output_name = output.name
        output_shape = [dim.dim_value for dim in output.type.tensor_type.shape.dim]
        output_details.append((output_name, output_shape))

    return output_details

# 调用函数并打印输入和输出信息
onnx_file = "model.onnx"  # 将 "model.onnx" 替换为你的ONNX模型文件路径
input_details = get_input_details(onnx_file)
output_details = get_output_details(onnx_file)

print("输入信息:")
for name, shape in input_details:
    print("Input Name:", name)
    print("Input Shape:", shape)

print("输出信息:")
for name, shape in output_details:
    print("Output Name:", name)
    print("Output Shape:", shape)
```