Skip to content

Commit 76e0e62

Browse files
authored
Merge pull request #145 from Channingss/exporter/v0.5.1
add op_mapper register function/support convert Paddle model(not combined)/add tutorial.ipynb/...
2 parents 3171997 + 136d997 commit 76e0e62

File tree

11 files changed

+379
-65
lines changed

11 files changed

+379
-65
lines changed

README.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,34 @@ paddle2onnx is a toolkit for converting trained model to **ONNX** from **PaddleP
4545
## 使用方式
4646
### 静态图模型导出
4747

48-
paddle2onnx --model_dir paddle_model --save_file onnx_file --opset_version 10 --enable_onnx_checker True
49-
50-
### 动态图模型导出
48+
#### 命令行
5149

52-
处于实验状态,Paddle 2.0正式版发布后,会提供详细使用教程。
50+
paddle2onnx --model_dir paddle_model --save_file onnx_file --opset_version 10 --enable_onnx_checker True
5351

54-
### 参数选项
52+
#### 参数选项
5553
| 参数 |参数说明 |
5654
|----------|--------------|
57-
|--model_dir | 指定包含Paddle模型'\_\_model\_\_'和参数'\_\_params\_\_'的路径, 由`paddle.fluid.io.save_inference_model`保存得到|
55+
|--model_dir | 指定包含Paddle模型, 由`paddle.fluid.io.save_inference_model`保存得到|
56+
|--model_filename |**[可选]** 用于指定位于`--model_dir`下存储网络结构的文件名称。当且仅当所有模型参数被保存在一个单独的二进制文件中,它才需要被指定。默认为None|
57+
|--params_filename |**[可选]** 用于指定位于`--model_dir`下存储所有模型参数的文件名称。当且仅当所有模型参数被保存在一个单独的二进制文件中,它才需要被指定。默认为None|
5858
|--save_file | 指定转换后的模型保存目录路径 |
5959
|--opset_version | **[可选]** 该参数可设置转换为ONNX的OpSet版本,目前比较稳定地支持9、10、11三个版本,默认为9 |
6060
|--enable_onnx_checker| **[可选]** 是否检查导出为ONNX模型的正确性, 建议打开此开关。若指定为True,需要安装 pip install onnx==1.7.0, 默认为False|
6161
|--version |**[可选]** 查看paddle2onnx版本 |
6262

63+
> 补充说明:
64+
>
65+
> - PaddlePaddle模型的两种存储形式:
66+
> - 参数被保存在一个单独的二进制文件中(combined),需要在指定--model_dir的前提下,指定--model_filename, --params_filename, 分别表示--model_dir目录下的网络文件名称和参数文件名称。
67+
> - 参数被保存为多个文件(not combined),只需要指定--model_dir,该目录下面需要包含了'\_\_model\_\_',以及多个参数文件。
68+
69+
#### 简单教程
70+
- [静态图导出ONNX教程](docs/tutorial.ipynb)
71+
72+
### 动态图模型导出
73+
74+
处于实验状态,Paddle 2.0正式版发布后,会提供详细使用教程。
75+
6376
## 相关文档
6477

6578
- [paddle2onnx测试模型库](docs/model_zoo.md)

docs/tutorial.ipynb

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"import paddle.fluid as fluid\n",
10+
"import os"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"metadata": {},
16+
"source": [
17+
"## 定义ResNet模型"
18+
]
19+
},
20+
{
21+
"cell_type": "code",
22+
"execution_count": 2,
23+
"metadata": {},
24+
"outputs": [],
25+
"source": [
26+
"def conv_bn_layer(input,\n",
27+
" ch_out,\n",
28+
" filter_size,\n",
29+
" stride,\n",
30+
" padding,\n",
31+
" act='relu',\n",
32+
" bias_attr=False):\n",
33+
" tmp = fluid.layers.conv2d(\n",
34+
" input=input,\n",
35+
" filter_size=filter_size,\n",
36+
" num_filters=ch_out,\n",
37+
" stride=stride,\n",
38+
" padding=padding,\n",
39+
" act=None,\n",
40+
" bias_attr=bias_attr)\n",
41+
" return fluid.layers.batch_norm(input=tmp, act=act)\n",
42+
"\n",
43+
"def shortcut(input, ch_in, ch_out, stride):\n",
44+
" if ch_in != ch_out:\n",
45+
" return conv_bn_layer(input, ch_out, 1, stride, 0, None)\n",
46+
" else:\n",
47+
" return input\n",
48+
"\n",
49+
"def basicblock(input, ch_in, ch_out, stride):\n",
50+
" tmp = conv_bn_layer(input, ch_out, 3, stride, 1)\n",
51+
" tmp = conv_bn_layer(tmp, ch_out, 3, 1, 1, act=None, bias_attr=True)\n",
52+
" short = shortcut(input, ch_in, ch_out, stride)\n",
53+
" return fluid.layers.elementwise_add(x=tmp, y=short, act='relu')\n",
54+
"\n",
55+
"def layer_warp(block_func, input, ch_in, ch_out, count, stride):\n",
56+
" tmp = block_func(input, ch_in, ch_out, stride)\n",
57+
" for i in range(1, count):\n",
58+
" tmp = block_func(tmp, ch_out, ch_out, 1)\n",
59+
" return tmp\n",
60+
"\n",
61+
"def resnet_cifar10(ipt, depth=32):\n",
62+
" # depth should be one of 20, 32, 44, 56, 110, 1202\n",
63+
" assert (depth - 2) % 6 == 0\n",
64+
" n = (depth - 2) // 6\n",
65+
" nStages = {16, 64, 128}\n",
66+
" conv1 = conv_bn_layer(ipt, ch_out=16, filter_size=3, stride=1, padding=1)\n",
67+
" res1 = layer_warp(basicblock, conv1, 16, 16, n, 1)\n",
68+
" #res2 = layer_warp(basicblock, res1, 16, 32, n, 2)\n",
69+
" #res3 = layer_warp(basicblock, res2, 32, 64, n, 2)\n",
70+
" pool = fluid.layers.pool2d(\n",
71+
" input=res1, pool_size=8, pool_type='avg', pool_stride=1)\n",
72+
" predict = fluid.layers.fc(input=pool, size=10, act='softmax')\n",
73+
" return predict\n",
74+
"\n",
75+
"data_shape = [None, 3, 32, 32]\n",
76+
"images = fluid.data(name='pixel', shape=data_shape, dtype='float32')\n",
77+
"predict = resnet_cifar10(images, 32)\n",
78+
"exe = fluid.Executor(fluid.CPUPlace())\n",
79+
"_ =exe.run(fluid.default_startup_program())"
80+
]
81+
},
82+
{
83+
"cell_type": "markdown",
84+
"metadata": {},
85+
"source": [
86+
"# 转换模型(数被保存为多个文件(not combined))"
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": 3,
92+
"metadata": {},
93+
"outputs": [
94+
{
95+
"data": {
96+
"text/plain": [
97+
"['save_infer_model/scale_0.tmp_0']"
98+
]
99+
},
100+
"execution_count": 3,
101+
"metadata": {},
102+
"output_type": "execute_result"
103+
}
104+
],
105+
"source": [
106+
"model_dir = './resnet_not_combined/'\n",
107+
"fluid.io.save_inference_model(model_dir, [\"pixel\"], [predict], exe)"
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": 4,
113+
"metadata": {},
114+
"outputs": [
115+
{
116+
"name": "stdout",
117+
"output_type": "stream",
118+
"text": [
119+
"__model__ batch_norm_2.w_2 batch_norm_6.w_2 conv2d_10.w_0\n",
120+
"batch_norm_0.b_0 batch_norm_3.b_0 batch_norm_7.b_0 conv2d_2.b_0\n",
121+
"batch_norm_0.w_0 batch_norm_3.w_0 batch_norm_7.w_0 conv2d_2.w_0\n",
122+
"batch_norm_0.w_1 batch_norm_3.w_1 batch_norm_7.w_1 conv2d_3.w_0\n",
123+
"batch_norm_0.w_2 batch_norm_3.w_2 batch_norm_7.w_2 conv2d_4.b_0\n",
124+
"batch_norm_1.b_0 batch_norm_4.b_0 batch_norm_8.b_0 conv2d_4.w_0\n",
125+
"batch_norm_1.w_0 batch_norm_4.w_0 batch_norm_8.w_0 conv2d_5.w_0\n",
126+
"batch_norm_1.w_1 batch_norm_4.w_1 batch_norm_8.w_1 conv2d_6.b_0\n",
127+
"batch_norm_1.w_2 batch_norm_4.w_2 batch_norm_8.w_2 conv2d_6.w_0\n",
128+
"batch_norm_10.b_0 batch_norm_5.b_0 batch_norm_9.b_0 conv2d_7.w_0\n",
129+
"batch_norm_10.w_0 batch_norm_5.w_0 batch_norm_9.w_0 conv2d_8.b_0\n",
130+
"batch_norm_10.w_1 batch_norm_5.w_1 batch_norm_9.w_1 conv2d_8.w_0\n",
131+
"batch_norm_10.w_2 batch_norm_5.w_2 batch_norm_9.w_2 conv2d_9.w_0\n",
132+
"batch_norm_2.b_0 batch_norm_6.b_0 conv2d_0.w_0 fc_0.b_0\n",
133+
"batch_norm_2.w_0 batch_norm_6.w_0 conv2d_1.w_0 fc_0.w_0\n",
134+
"batch_norm_2.w_1 batch_norm_6.w_1 conv2d_10.b_0\n"
135+
]
136+
}
137+
],
138+
"source": [
139+
"!ls ./resnet_not_combined/"
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": null,
145+
"metadata": {},
146+
"outputs": [],
147+
"source": [
148+
"# 执行shell命令,jupyter可能因为shell环境问题找到paddle2onnx命令,出现问题请到命令行执行\n",
149+
"!paddle2onnx --model_dir ./resnet_not_combined/ --save_file onnx-model/model.onnx --opset_version 10"
150+
]
151+
},
152+
{
153+
"cell_type": "markdown",
154+
"metadata": {},
155+
"source": [
156+
"# 转换模型(参数被保存在一个单独的二进制文件中(combined))"
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"execution_count": 5,
162+
"metadata": {},
163+
"outputs": [
164+
{
165+
"data": {
166+
"text/plain": [
167+
"['save_infer_model/scale_0.tmp_1']"
168+
]
169+
},
170+
"execution_count": 5,
171+
"metadata": {},
172+
"output_type": "execute_result"
173+
}
174+
],
175+
"source": [
176+
"model_dir = './resnet_combined/'\n",
177+
"fluid.io.save_inference_model(model_dir, [\"pixel\"], [predict], exe, model_filename='__model__', params_filename='__params__')"
178+
]
179+
},
180+
{
181+
"cell_type": "code",
182+
"execution_count": 6,
183+
"metadata": {},
184+
"outputs": [
185+
{
186+
"name": "stdout",
187+
"output_type": "stream",
188+
"text": [
189+
"__model__ __params__\n"
190+
]
191+
}
192+
],
193+
"source": [
194+
"!ls ./resnet_combined/"
195+
]
196+
},
197+
{
198+
"cell_type": "code",
199+
"execution_count": null,
200+
"metadata": {},
201+
"outputs": [],
202+
"source": [
203+
"# 执行shell命令,jupyter可能因为shell环境问题找到paddle2onnx命令,出现问题请到命令行执行\n",
204+
"!paddle2onnx --model_dir ./resnet_combined/ --model_filename '__model__' --params_filename '__params__' --save_file onnx-model/model.onnx --opset_version 10"
205+
]
206+
},
207+
{
208+
"cell_type": "code",
209+
"execution_count": null,
210+
"metadata": {},
211+
"outputs": [],
212+
"source": []
213+
}
214+
],
215+
"metadata": {
216+
"kernelspec": {
217+
"display_name": "Python [conda env:x2paddle]",
218+
"language": "python",
219+
"name": "conda-env-x2paddle-py"
220+
},
221+
"language_info": {
222+
"codemirror_mode": {
223+
"name": "ipython",
224+
"version": 3
225+
},
226+
"file_extension": ".py",
227+
"mimetype": "text/x-python",
228+
"name": "python",
229+
"nbconvert_exporter": "python",
230+
"pygments_lexer": "ipython3",
231+
"version": "3.6.0"
232+
}
233+
},
234+
"nbformat": 4,
235+
"nbformat_minor": 4
236+
}

paddle2onnx/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
__version__ = "0.4"
1717

1818
from .convert import dygraph2onnx, program2onnx
19+
from .op_mapper import register_op_mapper

paddle2onnx/command.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,31 @@ def arg_parser():
2929
"-m",
3030
type=_text_type,
3131
default=None,
32-
help="paddle model path, '__model__' and '__params__' files need under this path, which saved by 'paddle.fluid.io.save_inference_model'."
32+
help="PaddlePaddle model directory, if params stored in single file, you need define '--model_filename' and 'params_filename'."
33+
)
34+
parser.add_argument(
35+
"--model_filename",
36+
"-mf",
37+
type=_text_type,
38+
default=None,
39+
help="PaddlePaddle model's network file name, which under directory seted by --model_dir"
40+
)
41+
parser.add_argument(
42+
"--params_filename",
43+
"-pf",
44+
type=_text_type,
45+
default=None,
46+
help="PaddlePaddle model's param file name(param files combined in single file), which under directory seted by --model_dir."
3347
)
3448
parser.add_argument(
3549
"--save_file",
3650
"-s",
3751
type=_text_type,
3852
default=None,
3953
help="file path to save onnx model")
40-
parser.add_argument(
41-
"--version",
42-
"-v",
43-
action="store_true",
44-
default=False,
45-
help="get version of paddle2onnx")
4654
parser.add_argument(
4755
"--opset_version",
48-
"-oo",
56+
"-ov",
4957
type=int,
5058
default=9,
5159
help="set onnx opset version to export")
@@ -55,12 +63,20 @@ def arg_parser():
5563
default=False,
5664
help="whether check onnx model validity, if True, please 'pip install onnx'"
5765
)
66+
parser.add_argument(
67+
"--version",
68+
"-v",
69+
action="store_true",
70+
default=False,
71+
help="get version of paddle2onnx")
5872
return parser
5973

6074

6175
def program2onnx(model_dir,
6276
save_file,
63-
opset_version=10,
77+
model_filename=None,
78+
params_filename=None,
79+
opset_version=9,
6480
enable_onnx_checker=False):
6581
try:
6682
import paddle
@@ -79,15 +95,18 @@ def program2onnx(model_dir,
7995
if hasattr(paddle, 'enable_static'):
8096
paddle.enable_static()
8197
exe = fluid.Executor(fluid.CPUPlace())
82-
[program, feed, fetchs] = fluid.io.load_inference_model(
83-
model_dir,
84-
exe,
85-
model_filename='__model__',
86-
params_filename='__params__')
98+
if model_filename is None and params_filename is None:
99+
[program, feed, fetchs] = fluid.io.load_inference_model(model_dir, exe)
100+
else:
101+
[program, feed, fetchs] = fluid.io.load_inference_model(
102+
model_dir,
103+
exe,
104+
model_filename=model_filename,
105+
params_filename=params_filename)
87106
p2o.program2onnx(
88107
program,
108+
fluid.global_scope(),
89109
save_file,
90-
scope=fluid.global_scope(),
91110
opset_version=opset_version,
92111
enable_onnx_checker=enable_onnx_checker)
93112

@@ -114,6 +133,8 @@ def main():
114133
program2onnx(
115134
args.model_dir,
116135
args.save_file,
136+
args.model_filename,
137+
args.params_filename,
117138
opset_version=args.opset_version,
118139
enable_onnx_checker=args.enable_onnx_checker)
119140

paddle2onnx/convert.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def export_onnx(paddle_graph,
3939

4040

4141
def program2onnx(program,
42+
scope,
4243
save_file,
43-
scope=None,
4444
feeded_var_names=None,
4545
target_vars=None,
4646
opset_version=9,

0 commit comments

Comments
 (0)