1
- # 模型量化-量化训练
1
+ # 模型量化
2
2
3
3
首先我们介绍一下Paddle支持的模型量化方法,让大家有一个整体的认识。
4
4
@@ -22,7 +22,9 @@ Paddle模型量化包含三种量化方法,分别是动态离线量化方法
22
22
23
23
本文主要介绍使用PaddleSlim量化训练方法产出的量化模型,使用PaddleLite加载量化模型进行推理部署,
24
24
25
- ## 1 简介
25
+ ## 量化训练
26
+
27
+ ### 1 简介
26
28
27
29
量化训练是使用较多训练数据,对训练好的预测模型进行量化。该方法使用模拟量化的思想,在训练阶段更新权重,实现减小量化误差。
28
30
@@ -43,7 +45,7 @@ Paddle模型量化包含三种量化方法,分别是动态离线量化方法
43
45
44
46
建议首先使用“静态离线量化”方法对模型进行量化,然后使用使用量化模型进行预测。如果该量化模型的精度达不到要求,再使用“量化训练”方法。
45
47
46
- ## 2 产出量化模型
48
+ ### 2 产出量化模型
47
49
48
50
目前,PaddleSlim 的量化训练主要针对卷积层和全连接层,对应算子是conv2d、depthwise_conv2d、conv2d_tranpose和mul。Paddle-Lite支持运行PaddleSlim量化训练产出的模型,可以进一步加快模型在移动端的执行速度。
49
51
@@ -55,11 +57,11 @@ Paddle模型量化包含三种量化方法,分别是动态离线量化方法
55
57
* 量化训练[ Demo] ( https://github.com/PaddlePaddle/PaddleSlim/tree/develop/demo/quant )
56
58
57
59
58
- ## 3 使用Paddle-Lite运行量化模型推理
60
+ ### 3 使用Paddle-Lite运行量化模型推理
59
61
60
62
首先,使用PaddleLite提供的模型转换工具(model_optimize_tool)将量化模型转换成移动端预测的模型,然后加载转换后的模型进行预测部署。
61
63
62
- ### 3.1 模型转换
64
+ #### 3.1 模型转换
63
65
64
66
参考[ 模型转换] ( ../user_guides/model_optimize_tool ) 准备模型转换工具,建议从Release页面下载。
65
67
@@ -71,12 +73,12 @@ Paddle模型量化包含三种量化方法,分别是动态离线量化方法
71
73
--valid_targets=arm
72
74
```
73
75
74
- ### 3.2 量化模型预测
76
+ #### 3.2 量化模型预测
75
77
76
78
和FP32模型一样,转换后的量化模型可以在Android/IOS APP中加载预测,建议参考[ C++ Demo] ( ../quick_start/cpp_demo ) 、[ Java Demo] ( ../quick_start/java_demo ) 、[ Android/IOS Demo] ( ../demo_guides/android_app_demo ) 。
77
79
78
80
79
- ## FAQ
81
+ ### FAQ
80
82
81
83
** 问题** :Compiled with WITH_GPU, but no GPU found in runtime
82
84
@@ -85,3 +87,235 @@ Paddle模型量化包含三种量化方法,分别是动态离线量化方法
85
87
** 问题** :Inufficient GPU memory to allocation. at [ /paddle/paddle/fluid/platform/gpu_info.cc:262]
86
88
87
89
** 解答** :正确设置run.sh脚本中` CUDA_VISIBLE_DEVICES ` ,确保显卡剩余内存大于需要内存。
90
+
91
+
92
+ ## 离线量化-动态离线量化
93
+
94
+ 本部分首先简单介绍动态离线量化,然后说明产出量化模型,最后阐述量化模型预测。
95
+
96
+ ### 1 简介
97
+
98
+ 动态离线量化,将模型中特定OP的权重从FP32类型量化成INT8/16类型。
99
+
100
+ 该量化模型有两种预测方式:
101
+ * 第一种是反量化预测方式,即是首先将INT8/16类型的权重反量化成FP32类型,然后再使用FP32浮运算运算进行预测;
102
+ * 第二种量化预测方式,即是预测中动态计算量化OP输入的量化信息,基于量化的输入和权重进行INT8整形运算。
103
+
104
+ 注意:目前PaddleLite仅支持第一种反量化预测方式。
105
+
106
+ 使用条件:
107
+ * 有训练好的预测模型
108
+
109
+ 使用步骤:
110
+ * 产出量化模型:使用PaddlePaddle调用动态离线量化离线量化接口,产出量化模型
111
+ * 量化模型预测:使用PaddleLite加载量化模型进行预测推理
112
+
113
+ 优点:
114
+ * 权重量化成INT16类型,模型精度不受影响,模型大小为原始的1/2
115
+ * 权重量化成INT8类型,模型精度会受到影响,模型大小为原始的1/4
116
+
117
+ 缺点:
118
+ * 目前只支持反量化预测方式,主要可以减小模型大小,对特定加载权重费时的模型可以起到一定加速效果
119
+
120
+ 和静态离线量化相比,目前Paddle-Lite只支持反量化预测方式,对于预测过程的加速有限;但是动态离线量化不需要训练数据即可完成量化,达到减小模型大小的目的。
121
+
122
+ ### 2 产出量化模型
123
+
124
+ PaddleLite opt工具和PaddleSlim都提供了动态离线量化功能,两者原理相似,都可以产出动态离线量化的模型。
125
+
126
+ #### 2.1 使用PaddleLite opt产出量化模型
127
+
128
+ PaddleLite opt工具将动态离线量化功能集成到模型转换中,使用简便,只需要设置对应参数,就可以产出优化后的量化模型。
129
+
130
+ ##### 2.1.1 准备工具opt
131
+
132
+ 参考[ opt文档] ( ./model_optimize_tool ) ,准备opt工具,其中可执行文件opt和python版本opt都提供了动态图离线量化功能。
133
+
134
+ ##### 2.1.2 准备模型
135
+
136
+ 准备已经训练好的FP32预测模型,即 ` save_inference_model() ` 保存的模型。
137
+
138
+ ##### 2.1.3 产出量化模型
139
+
140
+ 参考[ opt文档] ( ./model_optimize_tool ) 中使用opt工具的方法,在模型优化中启用动态离线量化方法产出优化后的量化模型。
141
+
142
+ 如果是使用可执行文件opt工具,参考[ 直接下载并执行opt可执行工具] ( ./opt/opt_bin ) 。
143
+ 设置常规模型优化的参数后,可以通过 ` --quant_model ` 设置是否使用opt中的动态离线量化功能,通过 ` --quant_type ` 参数指定opt中动态离线量化功能的量化类型,可以设置为QUANT_INT8和QUANT_INT16,即分别量化为int8和int16。量化为int8对模型精度有一点影响,模型体积大概减小4倍。量化为int16对模型精度基本没有影响,模型体积大概减小2倍。
144
+ 举例如下:
145
+ ``` shell
146
+ ./opt \
147
+ --model_dir=< model_param_dir> \
148
+ --model_file=< model_path> \
149
+ --param_file=< param_path> \
150
+ --optimize_out_type=naive_buffer \
151
+ --optimize_out= < output_optimize_model_dir> \
152
+ --quant_model=true \
153
+ --quant_type=QUANT_INT16
154
+ ```
155
+
156
+ 如果使用python版本opt工具,请参考[ 安装 python版本opt后,使用终端命令] ( ./opt/opt_python ) 和[ 安装python版本opt后,使用python脚本] ( ../api_reference/python_api/opt ) ,都有介绍设置动态离线量化的参数和方法。
157
+
158
+ #### 2.2 使用PaddleSlim产出量化模型
159
+
160
+ 大家可以使用PaddleSlim调用动态离线量化接口,得到量化模型。
161
+
162
+ ##### 2.2.1 安装PaddleSlim
163
+
164
+ 参考PaddleSlim[ 文档] ( https://paddleslim.readthedocs.io/zh_CN/latest/index.html ) 进行安装。
165
+
166
+ #### 2.2.2 准备模型
167
+
168
+ 准备已经训练好的FP32预测模型,即 ` save_inference_model() ` 保存的模型。
169
+
170
+ ##### 2.2.3 调用动态离线量化
171
+
172
+ 对于调用动态离线量化,首先给出一个例子。
173
+
174
+ ``` python
175
+ from paddleslim.quant import quant_post_dynamic
176
+
177
+ model_dir = path/ to/ fp32_model_params
178
+ save_model_dir = path/ to/ save_model_path
179
+ quant_post_dynamic(model_dir = model_dir,
180
+ save_model_dir = save_model_dir,
181
+ weight_bits = 8 ,
182
+ quantizable_op_type = [' conv2d' , ' mul' ],
183
+ weight_quantize_type = " channel_wise_abs_max" ,
184
+ generate_test_model = False )
185
+ ```
186
+
187
+ 执行完成后,可以在 ` save_model_dir/quantized_model ` 目录下得到量化模型。
188
+
189
+ 动态离线量化api的详细介绍,请参考[ 链接] ( https://paddleslim.readthedocs.io/zh_CN/latest/api_cn/quantization_api.html#quant-post-dynamic ) 。
190
+
191
+ ### 3 量化模型预测
192
+
193
+ 目前,对于动态离线量化产出的量化模型,只能使用PaddleLite进行预测部署。
194
+
195
+ 很简单,首先使用PaddleLite提供的模型转换工具(opt)将量化模型转换成移动端预测的模型,然后加载转换后的模型进行预测部署。
196
+
197
+ 注意,PaddleLite 2.3版本才支持动态离线量化产出的量化,所以转换工具和预测库必须是2.3及之后的版本。
198
+
199
+ #### 3.1 模型转换
200
+
201
+ 参考[ 模型转换] ( ../user_guides/model_optimize_tool ) 准备模型转换工具,建议从Release页面下载。
202
+
203
+ 参考[ 模型转换] ( ../user_guides/model_optimize_tool ) 使用模型转换工具。
204
+ 比如在安卓手机ARM端进行预测,模型转换的命令为:
205
+ ``` bash
206
+ ./opt --model_dir=./mobilenet_v1_quant \
207
+ --optimize_out_type=naive_buffer \
208
+ --optimize_out=mobilenet_v1_quant_opt \
209
+ --valid_targets=arm
210
+ ```
211
+
212
+ #### 3.2 量化模型预测
213
+
214
+ 和FP32模型一样,转换后的量化模型可以在Android/IOS APP中加载预测,建议参考[ C++ Demo] ( ../quick_start/cpp_demo ) 、[ Java Demo] ( ../quick_start/java_demo ) 、[ Android/IOS Demo] ( ../demo_guides/android_app_demo ) 。
215
+
216
+
217
+ ## 离线量化-静态离线量化
218
+
219
+ #### 1 简介
220
+
221
+ 静态离线量化,使用少量校准数据计算量化因子,可以快速得到量化模型。使用该量化模型进行预测,可以减少计算量、降低计算内存、减小模型大小。
222
+
223
+ 静态离线量化中,有两种计算量化因子的方法,非饱和量化方法和饱和量化方法。非饱和量化方法计算整个Tensor的绝对值最大值` abs_max ` ,将其映射为127。饱和量化方法使用KL散度计算一个合适的阈值` T ` (` 0<T<mab_max ` ),将其映射为127。一般而言,待量化Op的权重采用非饱和量化方法,待量化Op的激活(输入和输出)采用饱和量化方法 。
224
+
225
+ 使用条件:
226
+ * 有训练好的预测模型
227
+ * 有少量校准数据,比如100~ 500张图片
228
+
229
+ 使用步骤:
230
+ * 产出量化模型:使用PaddleSlim调用静态离线量化接口,产出量化模型
231
+ * 量化模型预测:使用PaddleLite加载量化模型进行预测推理
232
+
233
+ 优点:
234
+ * 减小计算量、降低计算内存、减小模型大小
235
+ * 不需要大量训练数据
236
+ * 快速产出量化模型,简单易用
237
+
238
+ 缺点:
239
+ * 对少部分的模型,尤其是计算量小、精简的模型,量化后精度可能会受到影响
240
+
241
+ #### 2 产出量化模型
242
+
243
+ 大家可以使用PaddleSlim调用静态离线量化接口,得到量化模型。
244
+
245
+ ###### 2.1 安装PaddleSlim
246
+
247
+ 参考PaddleSlim[ 文档] ( https://paddleslim.readthedocs.io/zh_CN/latest/index.html ) 进行安装。
248
+
249
+ ###### 2.2 准备模型和校准数据
250
+
251
+ 准备已经训练好的FP32预测模型,即 ` save_inference_model() ` 保存的模型。
252
+ 准备校准数据集,校准数据集应该是测试集/训练集中随机挑选的一部分,量化因子才会更加准确。对常见的视觉模型,建议校准数据的数量为100~ 500张图片。
253
+
254
+ ###### 2.3 配置校准数据生成器
255
+
256
+ 静态离线量化内部使用异步数据读取的方式读取校准数据,大家只需要根据模型的输入,配置读取数据的sample_generator。sample_generator是Python生成器,** 必须每次返回单个样本数据** ,会用作` DataLoader.set_sample_generator() ` 的数据源。
257
+ 建议参考[ 异步数据读取文档] ( https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/data_preparing/static_mode/use_py_reader.html ) 和本文示例,学习如何配置校准数据生成器。
258
+
259
+ ###### 2.4 调用静态离线量化
260
+
261
+ 对于调用静态离线量化,首先给出一个例子,让大家有个直观了解。
262
+
263
+ ``` python
264
+ import paddle.fluid as fluid
265
+ from paddleslim.quant import quant_post_static
266
+
267
+ exe = fluid.Executor(fluid.CPUPlace())
268
+ model_dir = path/ to/ fp32_model_params
269
+ # # set model_filename as None when the filename is __model__,
270
+ # # otherwise set it as the real filename
271
+ model_filename = None
272
+ # # set params_filename as None when all parameters were saved in
273
+ # # separate files, otherwise set it as the real filename
274
+ params_filename = None
275
+ save_model_path = path/ to/ save_model_path
276
+ # # prepare the sample generator according to the model, and the
277
+ # # sample generator must return a sample every time. The reference
278
+ # # document: https://www.paddlepaddle.org.cn/documentation/docs/zh
279
+ # # /user_guides/howto/prepare_data/use_py_reader.html
280
+ sample_generator = your_sample_generator
281
+ batch_size = 10
282
+ batch_nums = 10
283
+ algo = " KL"
284
+ quantizable_op_type = [" conv2d" , " depthwise_conv2d" , " mul" ]
285
+ quant_post_static(executor = exe,
286
+ model_dir = model_dir,
287
+ model_filename = model_filename,
288
+ params_filename = params_filename,
289
+ quantize_model_path = save_model_path,
290
+ sample_generator = sample_generator,
291
+ batch_size = batch_size,
292
+ batch_nums = batch_nums,
293
+ algo = algo,
294
+ quantizable_op_type = quantizable_op_type)
295
+ ```
296
+
297
+ 快速开始请参考[ 文档] ( https://paddleslim.readthedocs.io/zh_CN/latest/quick_start/quant_post_static_tutorial.html ) 。
298
+
299
+ API接口请参考[ 文档] ( https://paddleslim.readthedocs.io/zh_CN/latest/api_cn/index.html ) 。
300
+
301
+ Demo请参考[ 文档] ( https://github.com/PaddlePaddle/PaddleSlim/tree/develop/demo/quant/quant_post ) 。
302
+
303
+ #### 3 量化模型预测
304
+
305
+ 首先,使用PaddleLite提供的模型转换工具(model_optimize_tool)将量化模型转换成移动端预测的模型,然后加载转换后的模型进行预测部署。
306
+
307
+ ###### 3.1 模型转换
308
+
309
+ 参考[ 模型转换] ( ../user_guides/model_optimize_tool ) 准备模型转换工具,建议从Release页面下载。
310
+
311
+ 参考[ 模型转换] ( ../user_guides/model_optimize_tool ) 使用模型转换工具,参数按照实际情况设置。比如在安卓手机ARM端进行预测,模型转换的命令为:
312
+ ``` bash
313
+ ./opt --model_dir=./mobilenet_v1_quant \
314
+ --optimize_out_type=naive_buffer \
315
+ --optimize_out=mobilenet_v1_quant_opt \
316
+ --valid_targets=arm
317
+ ```
318
+
319
+ ###### 3.2 量化模型预测
320
+
321
+ 和FP32模型一样,转换后的量化模型可以在Android/IOS APP中加载预测,建议参考[ C++ Demo] ( ../quick_start/cpp_demo ) 、[ Java Demo] ( ../quick_start/java_demo ) 、[ Android/IOS Demo] ( ../demo_guides/android_app_demo ) 。
0 commit comments