Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle-Lite
提交
b74c7ebd
P
Paddle-Lite
项目概览
PaddlePaddle
/
Paddle-Lite
通知
331
Star
4
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
271
列表
看板
标记
里程碑
合并请求
78
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle-Lite
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
271
Issue
271
列表
看板
标记
里程碑
合并请求
78
合并请求
78
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
b74c7ebd
编写于
2月 21, 2020
作者:
C
cc
提交者:
GitHub
2月 21, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Doc] Add post training quantization and weight quantization docs (#2960)
* add post training quantization and weight quantization docs
上级
85e802fc
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
339 addition
and
66 deletion
+339
-66
docs/advanced_user_guides/model_quantization.md
docs/advanced_user_guides/model_quantization.md
+40
-66
docs/advanced_user_guides/post_quant_no_data.md
docs/advanced_user_guides/post_quant_no_data.md
+94
-0
docs/advanced_user_guides/post_quant_with_data.md
docs/advanced_user_guides/post_quant_with_data.md
+203
-0
docs/index.rst
docs/index.rst
+2
-0
未找到文件。
docs/advanced_user_guides/model_quantization.md
浏览文件 @
b74c7ebd
# 模型量化
# 模型量化
-量化训练
本文主要介绍使用Paddle-Lite加载PaddlePaddle产出的量化模型,并进行推理执行。我们以MobileNetV1模型为示例,首先
介绍准备量化模型,然后介绍部署执行
。
本文主要介绍使用Paddle-Lite加载PaddlePaddle产出的量化模型,并进行推理执行。我们以MobileNetV1模型为示例,首先
说明产出量化模型,然后说明预测部署
。
##
准备量化模型
##
1 简介
PaddlePaddle使用量化训练和训练后量化两种方法将FP32模型量化成Int8模型,下面分别介绍两种方法如何产出量化模型
。
量化训练是基于大量训练数据,对训练好的预测模型进行量化。该方法使用模拟量化的思想,在训练阶段更新权重,实现减小量化误差
。
### 量化训练
使用条件:
*
有预训练模型
*
有较多训练数据
使用步骤:
*
产出量化模型:使用PaddlePaddle调用量化训练接口,产出量化模型
*
量化模型预测:使用PaddleLite加载量化模型进行预测推理
优点:
*
减小计算量、降低计算内存、减小模型大小
*
模型精度受量化影响小
缺点:
*
使用条件较苛刻,使用门槛稍高
建议首先使用“有校准数据训练后量化”对模型进行量化,然后使用使用量化模型进行预测。如果该量化模型的精度达不到要求,再使用“量化训练”。
## 2 产出量化模型
目前,PaddlePaddle框架的量化训练主要针对卷积层(包括二维卷积和Depthwise卷积)、和全连接层,对应算子是conv2d、depthwise_conv2d和mul,更多量化训练的原理请参考
[
文档
](
https://github.com/PaddlePaddle/models/blob/develop/PaddleSlim/docs/tutorial.md#1-quantization-aware-training%E9%87%8F%E5%8C%96%E4%BB%8B%E7%BB%8D
)
。Paddle-Lite支持运行PaddlePaddle框架量化训练产出的模型,可以进一步加快模型在移动端的执行速度。
目前,PaddlePaddle框架的量化训练主要针对卷积层(包括二维卷积和Depthwise卷积)、和全连接层,对应算子是conv2d、depthwise_conv2d和mul,更多量化训练的原理请参考
[
文档
](
https://github.com/PaddlePaddle/models/blob/develop/PaddleSlim/docs/tutorial.md#1-quantization-aware-training%E9%87%8F%E5%8C%96%E4%BB%8B%E7%BB%8D
)
。Paddle-Lite支持运行PaddlePaddle框架量化训练产出的模型,可以进一步加快模型在移动端的执行速度。
温馨提示:如果您是初次接触PaddlePaddle框架,建议首先学习
[
新人入门
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/beginners_guide/index_cn.html
)
和
[
使用指南
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/user_guides/index_cn.html
)
。
温馨提示:如果您是初次接触PaddlePaddle框架,建议首先学习
[
新人入门
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/beginners_guide/index_cn.html
)
和
[
使用指南
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/user_guides/index_cn.html
)
。
您可以选择下载训练好的量化模型,或者使用PaddleSlim模型压缩工具训练得到量化模型。
您可以选择下载训练好的量化模型,或者使用PaddleSlim模型压缩工具训练得到量化模型。
###
#
下载量化模型
### 下载量化模型
官方发布了
[
MobileNetV1量化模型
](
https://paddle-inference-dist.bj.bcebos.com/int8%2Fpretrain%2Fmobilenet_v1_quant%2Ffloat.zip
)
,直接下载到本地。
官方发布了
[
MobileNetV1量化模型
](
https://paddle-inference-dist.bj.bcebos.com/int8%2Fpretrain%2Fmobilenet_v1_quant%2Ffloat.zip
)
,直接下载到本地。
...
@@ -23,9 +40,9 @@ PaddlePaddle使用量化训练和训练后量化两种方法将FP32模型量化
...
@@ -23,9 +40,9 @@ PaddlePaddle使用量化训练和训练后量化两种方法将FP32模型量化
wget https://paddle-inference-dist.bj.bcebos.com/int8%2Fpretrain%2Fmobilenet_v1_quant%2Ffloat.zip
wget https://paddle-inference-dist.bj.bcebos.com/int8%2Fpretrain%2Fmobilenet_v1_quant%2Ffloat.zip
```
```
###
#
使用PaddleSlim模型压缩工具训练量化模型
### 使用PaddleSlim模型压缩工具训练量化模型
####
#
安装PaddlePaddle
#### 安装PaddlePaddle
根据操作系统、安装方式、Python版本和CUDA版本,按照
[
官方说明
](
https://paddlepaddle.org.cn/start
)
安装PaddlePaddle。例如:
根据操作系统、安装方式、Python版本和CUDA版本,按照
[
官方说明
](
https://paddlepaddle.org.cn/start
)
安装PaddlePaddle。例如:
...
@@ -39,7 +56,7 @@ Ubuntu 16.04.4 LTS操作系统,CPU版本安装:
...
@@ -39,7 +56,7 @@ Ubuntu 16.04.4 LTS操作系统,CPU版本安装:
pip
install
paddlepaddle
==
1.6.0
-i
https://mirrors.aliyun.com/pypi/simple/
pip
install
paddlepaddle
==
1.6.0
-i
https://mirrors.aliyun.com/pypi/simple/
```
```
####
#
克隆量化训练所需的代码库
#### 克隆量化训练所需的代码库
克隆
[
PaddlePaddle/models
](
https://github.com/PaddlePaddle/models
)
到本地,并进入models/PaddleSlim路径。
克隆
[
PaddlePaddle/models
](
https://github.com/PaddlePaddle/models
)
到本地,并进入models/PaddleSlim路径。
...
@@ -48,12 +65,13 @@ git clone https://github.com/PaddlePaddle/models.git
...
@@ -48,12 +65,13 @@ git clone https://github.com/PaddlePaddle/models.git
cd
models/PaddleSlim
cd
models/PaddleSlim
```
```
##### 数据准备
#### 准备数据和模型
###### 训练数据准备
##### 训练数据准备
参考
[
models/PaddleCV/image_classification
](
https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/image_classification#data-preparation
)
中的数据准备教程,下载训练数据,并且保存到PaddleSlim/data路径下。
参考
[
models/PaddleCV/image_classification
](
https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/image_classification#data-preparation
)
中的数据准备教程,下载训练数据,并且保存到PaddleSlim/data路径下。
#####
#
预训练模型准备
##### 预训练模型准备
参考/models/PaddleSlim/run.sh脚本, 从
[
models/PaddleCV/image_classification
](
https://github.com/PaddlePaddle/models/tree/develop/fluid/PaddleCV/image_classification#supported-models-and-performances
)
下载MobileNetV1的预训练模型,并保存到PaddleSlim/pretrain路径下。
参考/models/PaddleSlim/run.sh脚本, 从
[
models/PaddleCV/image_classification
](
https://github.com/PaddlePaddle/models/tree/develop/fluid/PaddleCV/image_classification#supported-models-and-performances
)
下载MobileNetV1的预训练模型,并保存到PaddleSlim/pretrain路径下。
...
@@ -84,8 +102,7 @@ cd models/PaddleSlim
...
@@ -84,8 +102,7 @@ cd models/PaddleSlim
在
`compress.py`
中定义了执行压缩任务需要的所有模型相关的信息,这里对几个关键的步骤进行简要介绍:
在
`compress.py`
中定义了执行压缩任务需要的所有模型相关的信息,这里对几个关键的步骤进行简要介绍:
###### 目标网络的定义
**目标网络的定义**
compress.py的以下代码片段定义了train program, 这里train program只有前向计算操作。
compress.py的以下代码片段定义了train program, 这里train program只有前向计算操作。
```
python
```
python
out
=
model
.
net
(
input
=
image
,
class_dim
=
args
.
class_dim
)
out
=
model
.
net
(
input
=
image
,
class_dim
=
args
.
class_dim
)
...
@@ -103,7 +120,7 @@ val_program = fluid.default_main_program().clone()
...
@@ -103,7 +120,7 @@ val_program = fluid.default_main_program().clone()
定义完目标网络结构,需要对其初始化,并根据需要加载预训练模型。
定义完目标网络结构,需要对其初始化,并根据需要加载预训练模型。
###### 定义feed_list和fetch_list
**定义feed_list和fetch_list**
对于train program, 定义train_feed_list用于指定从train data reader中取的数据feed给哪些variable。定义train_fetch_list用于指定在训练时,需要在log中展示的结果。如果需要在训练过程中在log中打印accuracy信心,则将('acc_top1', acc_top1.name)添加到train_fetch_list中即可。
对于train program, 定义train_feed_list用于指定从train data reader中取的数据feed给哪些variable。定义train_fetch_list用于指定在训练时,需要在log中展示的结果。如果需要在训练过程中在log中打印accuracy信心,则将('acc_top1', acc_top1.name)添加到train_fetch_list中即可。
```
python
```
python
train_feed_list
=
[(
'image'
,
image
.
name
),
(
'label'
,
label
.
name
)]
train_feed_list
=
[(
'image'
,
image
.
name
),
(
'label'
,
label
.
name
)]
...
@@ -119,7 +136,7 @@ val_feed_list = [('image', image.name), ('label', label.name)]
...
@@ -119,7 +136,7 @@ val_feed_list = [('image', image.name), ('label', label.name)]
val_fetch_list
=
[(
'acc_top1'
,
acc_top1
.
name
),
(
'acc_top5'
,
acc_top5
.
name
)]
val_fetch_list
=
[(
'acc_top1'
,
acc_top1
.
name
),
(
'acc_top5'
,
acc_top5
.
name
)]
```
```
###### Compressor和量化配置文件
**Compressor和量化配置文件**
`compress.py`
主要使用Compressor和yaml文件完成对模型的量化训练工作。Compressor类的定义如下:
`compress.py`
主要使用Compressor和yaml文件完成对模型的量化训练工作。Compressor类的定义如下:
```
python
```
python
class
Compressor
(
object
):
class
Compressor
(
object
):
...
@@ -192,7 +209,7 @@ compressor:
...
@@ -192,7 +209,7 @@ compressor:
>
>
> 3)**目前,Paddle-Lite仅支持运行weight量化方式使用`abs_max`且activation量化方式使用`moving_average_abs_max`或`range_abs_max`产出的量化模型**。
> 3)**目前,Paddle-Lite仅支持运行weight量化方式使用`abs_max`且activation量化方式使用`moving_average_abs_max`或`range_abs_max`产出的量化模型**。
####
# 执行int8
量化训练
####
执行
量化训练
修改run.sh,即注释掉
`# enable GC strategy`
与
`# for sensitivity filter pruning`
之间的内容并打开
`#for quantization`
相关的脚本命令(所需打开注释的命令如下所示)。
修改run.sh,即注释掉
`# enable GC strategy`
与
`# for sensitivity filter pruning`
之间的内容并打开
`#for quantization`
相关的脚本命令(所需打开注释的命令如下所示)。
...
@@ -214,52 +231,9 @@ python compress.py \
...
@@ -214,52 +231,9 @@ python compress.py \
*
int8目录: 参数范围为int8范围且参数数据类型为int8的量化模型。
*
int8目录: 参数范围为int8范围且参数数据类型为int8的量化模型。
*
mobile目录:参数特点与int8目录相同且兼容paddle-mobile的量化模型(目前paddle-mobile已升级为Paddle-Lite)。
*
mobile目录:参数特点与int8目录相同且兼容paddle-mobile的量化模型(目前paddle-mobile已升级为Paddle-Lite)。
### 训练后量化
## 3 使用Paddle-Lite运行量化模型推理
下面以MobileNetV1为例,介绍使用训练后量化方法产出量化模型。关于训练后量化的原理和详细使用方法,请参考
[
文档
](
https://github.com/PaddlePaddle/models/tree/develop/PaddleSlim/quant_low_level_api
)
。
> 该示例的代码放在[models/PaddleSlim/quant_low_level_api/](https://github.com/PaddlePaddle/models/tree/develop/PaddleSlim/quant_low_level_api)目录下。如果需要执行该示例,首先clone下来[models](https://github.com/PaddlePaddle/models.git),安装具有训练后量化功能的PaddlePaddle。因为目前Lite支持支持对conv2d、depthwise_conv2d和mul量化,所以修改[run_post_training_quanzation.sh](https://github.com/PaddlePaddle/models/blob/develop/PaddleSlim/quant_low_level_api/run_post_training_quanzation.sh) 脚本,设置is_full_quantize=False,然后执行该脚本;执行结束后,量化模型保存在`mobilenetv1_int8_model`目录下。下面介绍详细步骤。
1)
**准备模型和校准数据**
安装PaddlePaddle的develop分支编译的whl包,准备已经训练好的FP32预测模型。
准备校准数据,文件结构如下。val文件夹中有100张图片,val_list.txt文件中包含图片的label。
```
bash
samples_100
└──val
└──val_list.txt
```
2)
**配置校准数据生成器**
MobileNetV1的输入是图片和标签,所以配置读取校准数据的sample_generator,每次返回一张图片和一个标签。详细代码在
[
models/PaddleSlim/reader.py
](
https://github.com/PaddlePaddle/models/blob/develop/PaddleSlim/reader.py
)
。
3)
**调用训练后量化**
调用训练后量化的核心代码如下,详细代码在
[
post_training_quantization.py
](
https://github.com/PaddlePaddle/models/blob/develop/PaddleSlim/quant_low_level_api/post_training_quantization.py
)
。
```
python
place
=
fluid
.
CUDAPlace
(
0
)
if
args
.
use_gpu
==
"True"
else
fluid
.
CPUPlace
()
exe
=
fluid
.
Executor
(
place
)
sample_generator
=
reader
.
val
(
data_dir
=
args
.
data_path
)
ptq
=
PostTrainingQuantization
(
executor
=
exe
,
sample_generator
=
sample_generator
,
model_dir
=
args
.
model_dir
,
model_filename
=
args
.
model_filename
,
params_filename
=
args
.
params_filename
,
batch_size
=
args
.
batch_size
,
batch_nums
=
args
.
batch_nums
,
algo
=
args
.
algo
,
is_full_quantize
=
args
.
is_full_quantize
==
"True"
)
quantized_program
=
ptq
.
quantize
()
ptq
.
save_quantized_model
(
args
.
save_model_path
)
```
## 使用Paddle-Lite运行量化模型推理
###
#
使用模型优化工具对量化模型进行优化
### 使用模型优化工具对量化模型进行优化
接下来,使用原始的量化模型生成适合在移动端直接部署的模型。
接下来,使用原始的量化模型生成适合在移动端直接部署的模型。
...
@@ -276,7 +250,7 @@ ptq.save_quantized_model(args.save_model_path)
...
@@ -276,7 +250,7 @@ ptq.save_quantized_model(args.save_model_path)
如前所述,量化训练后,float目录下的模型参数范围为int8,但参数数据类型仍为float32类型,这样确实没有起到模型参数压缩的效果。但是,经过model
\_
optimize
\_
tool工具优化后对应的量化参数均会以int8类型重新存储达到参数压缩的效果,且模型结构也被优化(如进行了各种operator fuse操作)。
如前所述,量化训练后,float目录下的模型参数范围为int8,但参数数据类型仍为float32类型,这样确实没有起到模型参数压缩的效果。但是,经过model
\_
optimize
\_
tool工具优化后对应的量化参数均会以int8类型重新存储达到参数压缩的效果,且模型结构也被优化(如进行了各种operator fuse操作)。
###
#
在手机端准备量化模型文件
### 在手机端准备量化模型文件
使用如下命令将mobilenet_v1_quant_opt目录下的量化模型文件导入到手机端:
使用如下命令将mobilenet_v1_quant_opt目录下的量化模型文件导入到手机端:
...
@@ -284,7 +258,7 @@ ptq.save_quantized_model(args.save_model_path)
...
@@ -284,7 +258,7 @@ ptq.save_quantized_model(args.save_model_path)
adb push mobilenet_v1_quant_opt /data/local/tmp
adb push mobilenet_v1_quant_opt /data/local/tmp
```
```
###
#
使用mobilenetv1\_light\_api运行优化后的量化模型
### 使用mobilenetv1\_light\_api运行优化后的量化模型
参考
[
源码编译
](
../source_compile
)
配置编译环境后,在Paddle-Lite执行如下命令获取轻量级API的demo:
参考
[
源码编译
](
../source_compile
)
配置编译环境后,在Paddle-Lite执行如下命令获取轻量级API的demo:
...
@@ -316,7 +290,7 @@ Output[900]: 0.000969
...
@@ -316,7 +290,7 @@ Output[900]: 0.000969
```
```
在C++中使用Paddle-Lite API的方法请猛戳
[
此处
](
../cpp_demo
)
,用户也可参考
[
mobilenetv1_light_api.cc
](
https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc
)
的代码示例。
在C++中使用Paddle-Lite API的方法请猛戳
[
此处
](
../cpp_demo
)
,用户也可参考
[
mobilenetv1_light_api.cc
](
https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/demo/cxx/mobile_light/mobilenetv1_light_api.cc
)
的代码示例。
##
#
FAQ
## FAQ
**问题**
:Compiled with WITH_GPU, but no GPU found in runtime
**问题**
:Compiled with WITH_GPU, but no GPU found in runtime
...
...
docs/advanced_user_guides/post_quant_no_data.md
0 → 100644
浏览文件 @
b74c7ebd
# 模型量化-无校准数据训练后量化
本文首先简单介绍无校准数据训练后量化,然后说明产出量化模型,最好阐述量化模型预测。
## 1 简介
无校准数据训练后量化,将模型中特定OP的权重从FP32类型量化成INT8/16类型,可以减小预测模型的大小。使用该量化模型预测,首先将INT8/16类型的权重反量化成FP32类型,然后再进行预测。
使用条件:
*
有训练好的预测模型
使用步骤:
*
产出量化模型:使用PaddlePaddle调用无校准数据训练后量化接口,产出量化模型
*
量化模型预测:使用PaddleLite加载量化模型进行预测推理
优点:
*
权重量化成INT16类型,模型精度不受影响,模型大小为原始的1/2
*
权重量化成INT8类型,模型精度会受到影响,模型大小为原始的1/4
缺点:
*
暂无
## 2 产出量化模型
大家可以使用PaddlePaddle调用无校准数据训练后量化接口,得到量化模型。
### 2.1 安装PaddlePaddle
参考PaddlePaddle
[
官网
](
https://www.paddlepaddle.org.cn/install/quick
)
,安装PaddlePaddle CPU/GPU 1.7版本。
### 2.2 准备模型
准备已经训练好的FP32预测模型,即
`save_inference_model()`
保存的模型。
### 2.3 调用无校准数据训练后量化
对于调用无校准数据训练后量化,首先给出一个例子。
```
python
model_dir
=
path
/
to
/
fp32_model_params
save_model_dir
=
path
/
to
/
save_model_path
weight_quant
=
WeightQuantization
(
model_dir
=
model_dir
)
weight_quant
.
quantize_weight_to_int
(
save_model_dir
=
save_model_dir
,
weight_bits
=
8
,
quantizable_op_type
=
[
'conv2d'
,
'depthwise_conv2d'
,
'mul'
])
```
对于调用无校准数据训练后量化,以下对api接口进行详细介绍。
```
python
class
WeightQuantization
(
model_dir
,
model_filename
=
None
,
params_filename
=
None
)
```
参数说明如下:
*
model_dir(str):待量化模型的路径,其中保存模型文件和权重文件。
*
model_filename(str, optional):待量化模型的模型文件名,如果模型文件名不是
`__model__`
,则需要使用model_filename设置模型文件名。
*
params_filename(str, optional):待量化模型的权重文件名,如果所有权重保存成一个文件,则需要使用params_filename设置权重文件名。
```
python
WeightQuantization
.
quantize_weight_to_int
(
save_model_dir
,
save_model_filename
=
None
,
save_params_filename
=
None
,
quantizable_op_type
=
[
'conv2d'
,
'mul'
],
weight_bits
=
8
,
threshold_rate
=
0.0
)
```
参数说明如下:
*
save_model_dir(str):保存量化模型的路径。
*
save_model_filename(str, optional):如果save_model_filename等于None,则模型的网络结构保存到__model__文件,如果save_model_filename不等于None,则模型的网络结构保存到特定的文件。默认为None。
*
save_params_filename(str, optional):如果save_params_filename等于None,则模型的参数分别保存到一系列文件中,如果save_params_filename不等于None,则模型的参数会保存到一个文件中,文件名为设置的save_params_filename。默认为None。
*
quantizable_op_type(list[str]): 需要量化的op类型,默认是
`['conv2d', 'mul']`
,列表中的值可以是任意支持量化的op类型
`['conv2d', 'depthwise_conv2d', 'mul']`
。
*
weight_bits(int, optional):权重量化保存的比特数,可以是8~16,一般设置为8/16。默认为8。
## 3 量化模型预测
首先,使用PaddleLite提供的模型转换工具(model_optimize_tool)将量化模型转换成移动端预测的模型,然后加载转换后的模型进行预测部署。
### 3.1 模型转换
参考
[
模型转换
](
../user_guides/model_optimize_tool
)
准备模型转换工具,建议从Release页面下载。
参考
[
模型转换
](
../user_guides/model_optimize_tool
)
使用模型转换工具。
因为该模型会将量化的权重反量化,然后实际加载并执行FP32预测模型,所以opt命令的输入参数--prefer_int8_kernel不需要设置为true,同时其他参数按照实际情况参考文档设置。
比如在安卓手机ARM端进行预测,模型转换的命令为:
```
bash
./opt
--model_dir
=
./mobilenet_v1_quant
\
--optimize_out_type
=
naive_buffer
\
--optimize_out
=
mobilenet_v1_quant_opt
\
--valid_targets
=
arm
```
### 3.2 量化模型预测
和FP32模型一样,转换后的量化模型可以在Android/IOS APP中加载预测,建议参考
[
C++ Demo
](
../user_guides/cpp_demo
)
、
[
Java Demo
](
../user_guides/java_demo
)
、
[
Android/IOS Demo
](
../user_guides/android_ios_app_demo
)
。
docs/advanced_user_guides/post_quant_with_data.md
0 → 100644
浏览文件 @
b74c7ebd
# 模型量化-有校准数据训练后量化
本文首先简单介绍有校准数据训练后量化,然后说明产出量化模型、量化模型预测,最后给出一个使用示例。
如果想快速上手,大家可以先参考使用示例,再查看详细使用方法。
## 1 简介
有校准数据训练后量化,使用少量校准数据计算量化因子,可以快速得到量化模型。使用该量化模型进行预测,可以减少计算量、降低计算内存、减小模型大小。
有校准数据训练后量化中,有两种计算量化因子的方法,非饱和量化方法和饱和量化方法。非饱和量化方法计算整个Tensor的绝对值最大值
`abs_max`
,将其映射为127。饱和量化方法使用KL散度计算一个合适的阈值
`T`
(
`0<T<mab_max`
),将其映射为127。一般而言,待量化Op的权重采用非饱和量化方法,待量化Op的激活(输入和输出)采用饱和量化方法 。
使用条件:
*
有训练好的预测模型
*
有少量校准数据,比如100~500张图片
使用步骤:
*
产出量化模型:使用PaddlePaddle或者PaddleSlim调用有校准数据训练后量化接口,产出量化模型
*
量化模型预测:使用PaddleLite加载量化模型进行预测推理
优点:
*
减小计算量、降低计算内存、减小模型大小
*
不需要大量训练数据
*
快速产出量化模型,简单易用
缺点:
*
对少部分的模型,尤其是计算量小、精简的模型,量化后精度可能会受到影响
## 2 产出量化模型
大家可以使用PaddlePaddle或者PaddleSlim调用有校准数据训练后量化接口,得到量化模型。本文主要介绍使用PaddlePaddle产出量化模型,使用PaddleSlim可以参考
[
文档
](
https://github.com/PaddlePaddle/models/tree/develop/PaddleSlim
)
。
### 2.1 安装PaddlePaddle
参考PaddlePaddle
[
官网
](
https://www.paddlepaddle.org.cn/install/quick
)
,安装PaddlePaddle CPU/GPU 1.7版本。
### 2.2 准备模型和校准数据
准备已经训练好的FP32预测模型,即
`save_inference_model()`
保存的模型。
准备校准数据集,校准数据集应该是测试集/训练集中随机挑选的一部分,量化因子才会更加准确。对常见的视觉模型,建议校准数据的数量为100~500张图片。
### 2.3 配置校准数据生成器
有校准数据训练后量化内部使用异步数据读取的方式读取校准数据,大家只需要根据模型的输入,配置读取数据的sample_generator。sample_generator是Python生成器,
**必须每次返回单个样本数据**
,会用作
`DataLoader.set_sample_generator()`
的数据源。
建议参考
[
异步数据读取文档
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/user_guides/howto/prepare_data/use_py_reader.html
)
和本文示例,学习如何配置校准数据生成器。
### 2.4 调用有校准数据训练后量化
对于调用有校准数据训练后量化,首先给出一个例子,让大家有个直观了解。
```
python
import
paddle.fluid
as
fluid
from
paddle.fluid.contrib.slim.quantization
import
PostTrainingQuantization
exe
=
fluid
.
Executor
(
fluid
.
CPUPlace
())
model_dir
=
path
/
to
/
fp32_model_params
# set model_filename as None when the filename is __model__,
# otherwise set it as the real filename
model_filename
=
None
# set params_filename as None when all parameters were saved in
# separate files, otherwise set it as the real filename
params_filename
=
None
save_model_path
=
path
/
to
/
save_model_path
# prepare the sample generator according to the model, and the
# sample generator must return a sample every time. The reference
# document: https://www.paddlepaddle.org.cn/documentation/docs/zh
# /user_guides/howto/prepare_data/use_py_reader.html
sample_generator
=
your_sample_generator
batch_size
=
10
batch_nums
=
10
algo
=
"KL"
quantizable_op_type
=
[
"conv2d"
,
"depthwise_conv2d"
,
"mul"
]
ptq
=
PostTrainingQuantization
(
executor
=
exe
,
sample_generator
=
sample_generator
,
model_dir
=
model_dir
,
model_filename
=
model_filename
,
params_filename
=
params_filename
,
batch_size
=
batch_size
,
batch_nums
=
batch_nums
,
algo
=
algo
,
quantizable_op_type
=
quantizable_op_type
)
ptq
.
quantize
()
ptq
.
save_quantized_model
(
save_model_path
)
```
对于调用有校准数据训练后量化,以下对接口进行详细介绍。
```
python
class
PostTrainingQuantization
(
executor
=
None
,
scope
=
None
,
model_dir
=
None
,
model_filename
=
None
,
params_filename
=
None
,
sample_generator
=
None
,
batch_size
=
10
,
batch_nums
=
None
,
algo
=
"KL"
,
quantizable_op_type
=
[
"conv2d"
,
"depthwise_conv2d"
,
"mul"
],
is_full_quantize
=
False
,
weight_bits
=
8
,
activation_bits
=
8
,
is_use_cache_file
=
False
,
cache_dir
=
"./temp_post_training"
):
```
调用上述api,传入必要的参数。参数说明如下:
*
executor(fluid.Executor):执行模型的executor,可以指定在cpu或者gpu上执行。
*
scope(fluid.Scope, optional):模型运行时使用的scope,默认为None,则会使用global_scope()。行首有optional,说明用户可以不设置该输入参数,直接使用默认值,下同。
*
model_dir(str):待量化模型的路径,其中保存模型文件和权重文件。
*
model_filename(str, optional):待量化模型的模型文件名,如果模型文件名不是
`__model__`
,则需要使用model_filename设置模型文件名。
*
params_filename(str, optional):待量化模型的权重文件名,如果所有权重保存成一个文件,则需要使用params_filename设置权重文件名。
*
sample_generator(Python Generator):配置的校准数据生成器。
*
batch_size(int, optional):一次读取校准数据的数量。
*
batch_nums(int, optional):读取校准数据的次数。如果设置为None,则从sample_generator中读取所有校准数据进行训练后量化;如果设置为非None,则从sample_generator中读取
`batch_size*batch_nums`
个校准数据。
*
algo(str, optional):计算待量化激活Tensor的量化因子的方法。设置为
`KL`
,则使用饱和量化方法,设置为
`direct`
,则使用非饱和量化方法。默认为
`KL`
。
*
quantizable_op_type(list[str], optional): 需要量化的op类型,默认是
`["conv2d", "depthwise_conv2d", "mul"]`
,列表中的值可以是任意支持量化的op类型。
*
is_full_quantize(bool, optional):是否进行全量化。设置为True,则对模型中所有支持量化的op进行量化;设置为False,则只对
`quantizable_op_type`
中op类型进行量化。目前支持的量化类型如下:'conv2d', 'depthwise_conv2d', 'mul', "pool2d", "elementwise_add", "concat", "softmax", "argmax", "transpose", "equal", "gather", "greater_equal", "greater_than", "less_equal", "less_than", "mean", "not_equal", "reshape", "reshape2", "bilinear_interp", "nearest_interp", "trilinear_interp", "slice", "squeeze", "elementwise_sub"。
*
weight_bits(int, optional):权重量化的比特数,可以设置为1~16。PaddleLite目前仅支持加载权重量化为8bit的量化模型。
*
activation_bits(int, optional): 激活量化的比特数,可以设置为1~16。PaddleLite目前仅支持加载激活量化为8bit的量化模型。
*
is_use_cache_file(bool, optional):是否使用缓存文件。如果设置为True,训练后量化过程中的采样数据会保存到磁盘文件中;如果设置为False,所有采样数据会保存到内存中。当待量化的模型很大或者校准数据数量很大,建议设置is_use_cache_file为True。默认为False。
*
cache_dir(str, optional):当is_use_cache_file等于True,会将采样数据保存到该文件中。量化完成后,该文件中的临时文件会自动删除。
```
python
PostTrainingQuantization
.
quantize
()
```
调用上述接口开始训练后量化。根据校准数据数量、模型的大小和量化op类型不同,训练后量化需要的时间也不一样。比如使用ImageNet2012数据集中100图片对
`MobileNetV1`
进行训练后量化,花费大概1分钟。
```
python
PostTrainingQuantization
.
save_quantized_model
(
save_model_path
)
```
调用上述接口保存训练后量化模型,其中save_model_path为保存的路径。
训练后量化支持部分量化功能:
*
方法1:设置quantizable_op_type,则只会对quantizable_op_type中的Op类型进行量化,模型中其他Op类型保持不量化。
*
方法2:构建网络的时候,将不需要量化的特定Op定义在
`skip_quant`
的name_scope中,则可以跳过特定Op的量化,示例如下。
```
python
with
fluid
.
name_scope
(
'skip_quant'
):
pool
=
fluid
.
layers
.
pool2d
(
input
=
hidden
,
pool_size
=
2
,
pool_type
=
'avg'
,
pool_stride
=
2
)
# 不对pool2d进行量化
```
## 3 量化模型预测
首先,使用PaddleLite提供的模型转换工具(model_optimize_tool)将量化模型转换成移动端预测的模型,然后加载转换后的模型进行预测部署。
### 3.1 模型转换
参考
[
模型转换
](
../user_guides/model_optimize_tool
)
准备模型转换工具,建议从Release页面下载。
参考
[
模型转换
](
../user_guides/model_optimize_tool
)
使用模型转换工具。注意opt命令的输入参数--prefer_int8_kernel必须设置为true,其他参数按照实际情况参考文档设置。比如在安卓手机ARM端进行预测,模型转换的命令为:
```
bash
./opt
--model_dir
=
./mobilenet_v1_quant
\
--optimize_out_type
=
naive_buffer
\
--optimize_out
=
mobilenet_v1_quant_opt
\
--valid_targets
=
arm
\
--prefer_int8_kernel
=
true
```
### 3.2 量化模型预测
和FP32模型一样,转换后的量化模型可以在Android/IOS APP中加载预测,建议参考
[
C++ Demo
](
../user_guides/cpp_demo
)
、
[
Java Demo
](
../user_guides/java_demo
)
、
[
Android/IOS Demo
](
../user_guides/android_ios_app_demo
)
。
## 4 使用示例
### 4.1 产出量化模型
参考本文 “2.1 安装PaddlePaddle” 安装PaddlePaddle。
下载
[
打包文件
](
https://paddle-inference-dist.cdn.bcebos.com/PaddleLite/quantization_demo/post_training_quantization_withdata.tgz
)
,解压到本地。
```
bash
wget https://paddle-inference-dist.cdn.bcebos.com/PaddleLite/quantization_demo/post_training_quantization_withdata.tgz
tar
zxvf post_training_quantization_withdata.tgz
cd
post_training_quantization_withdata
```
执行下面的命令,自动下载预测模型(mobilenetv1_fp32_model)和校准数据集,然后调用有校准数据训练后方法产出量化模型。
```
bash
sh run_post_training_quanzation.sh
```
量化模型保存在mobilenetv1_int8_model文件夹中。
### 4.2 量化模型预测
下载测试文件(
[
benchmark_bin
](
https://paddle-inference-dist.cdn.bcebos.com/PaddleLite/quantization_demo/benchmark_bin
)
)或者参考
[
Benchmark测试方法
](
../benchmark/benchmark_tools
)
编译测试文件。
将mobilenetv1_fp32_model、mobilenetv1_int8_model和benchmark_bin文件都保存到手机上。
```
bash
adb push mobilenetv1_fp32_model /data/local/tmp
adb push mobilenetv1_int8_model /data/local/tmp
chmod
777 benchmark_bin
adb push benchmark_bin /data/local/tmp
```
测试量化模型和原始模型的性能,依次执行下面命令:
```
bash
./benchmark_bin
--is_quantized_model
=
true
--run_model_optimize
=
true
--result_filename
=
res.txt
--warmup
=
10
--repeats
=
30
--model_dir
=
mobilenetv1_int8_model/
./benchmark_bin
--is_quantized_model
=
true
--run_model_optimize
=
true
--result_filename
=
res.txt
--warmup
=
10
--repeats
=
30
--model_dir
=
mobilenetv1_fp32_model/
cat
res.txt
```
在res.txt文件中可以看到INT8量化模型和FP32原始模型的速度。
举例来说,在骁龙855手机、单线程的情况下测试mobilenetv1,INT8量化模型的计算时间是14.52ms,FP32原始模型的计算时间是31.7ms。
docs/index.rst
浏览文件 @
b74c7ebd
...
@@ -49,6 +49,8 @@ Welcome to Paddle-Lite's documentation!
...
@@ -49,6 +49,8 @@ Welcome to Paddle-Lite's documentation!
advanced_user_guides/x2paddle
advanced_user_guides/x2paddle
advanced_user_guides/x2paddle_models_doc
advanced_user_guides/x2paddle_models_doc
advanced_user_guides/post_quant_with_data
advanced_user_guides/post_quant_no_data
advanced_user_guides/model_quantization
advanced_user_guides/model_quantization
advanced_user_guides/support_operation_list
advanced_user_guides/support_operation_list
advanced_user_guides/add_operation
advanced_user_guides/add_operation
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录