Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleSlim
提交
5758b66d
P
PaddleSlim
项目概览
PaddlePaddle
/
PaddleSlim
接近 2 年 前同步成功
通知
51
Star
1434
Fork
344
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
53
列表
看板
标记
里程碑
合并请求
16
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleSlim
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
53
Issue
53
列表
看板
标记
里程碑
合并请求
16
合并请求
16
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
5758b66d
编写于
8月 09, 2022
作者:
W
whs
提交者:
GitHub
8月 09, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refine the tutorial of config (#1321)
* Refine the tutorial of config * Fix typo
上级
8d9c1162
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
160 addition
and
25 deletion
+160
-25
example/auto_compression/hyperparameter_tutorial.md
example/auto_compression/hyperparameter_tutorial.md
+160
-25
未找到文件。
example/auto_compression/hyperparameter_tutorial.md
浏览文件 @
5758b66d
# ACT超参详细教程
#
1.
ACT超参详细教程
## 各压缩方法超参解析
##
1.1
各压缩方法超参解析
###
# 配置定制量化方案
###
1.1.1 量化(quantization)
量化参数主要设置量化比特数和量化op类型,其中量化op包含卷积层(conv2d, depthwise_conv2d)和全连接层(mul, matmul_v2)。以下为只量化卷积层的示例:
量化参数主要设置量化比特数和量化op类型,其中量化op包含卷积层(conv2d, depthwise_conv2d)和全连接层(mul, matmul_v2)。以下为只量化卷积层的示例:
```
yaml
```
yaml
...
@@ -23,67 +23,145 @@ Quantization:
...
@@ -23,67 +23,145 @@ Quantization:
onnx_format
:
false
# 是否采用ONNX量化标准格式
onnx_format
:
false
# 是否采用ONNX量化标准格式
```
```
#### 配置定制蒸馏策略
以上配置项说明如下:
-
use_pact: 是否开启PACT。一般情况下,开启PACT后,量化产出的模型精度会更高。算法原理请参考:
[
PACT: Parameterized Clipping Activation for Quantized Neural Networks
](
https://arxiv.org/abs/1805.06085
)
-
activation_bits: 激活量化bit数,可选1~8。默认为8。
-
weight_bits: 参数量化bit数,可选1~8。默认为8。
-
activation_quantize_type: 激活量化方式,可选 'abs_max' , 'range_abs_max' , 'moving_average_abs_max' 。如果使用 TensorRT 加载量化后的模型来预测,请使用 'range_abs_max' 或 'moving_average_abs_max' 。默认为 'moving_average_abs_max'。
-
weight_quantize_type: 参数量化方式。可选 'abs_max' , 'channel_wise_abs_max' , 'range_abs_max' , 'moving_average_abs_max' 。如果使用 TensorRT 加载量化后的模型来预测,请使用 'channel_wise_abs_max' 。 默认 'channel_wise_abs_max' 。
-
not_quant_pattern: 所有
`name_scope`
包含 'not_quant_pattern' 字符串的 op ,都不量化。
`name_scope`
设置方式请参考
[
paddle.static.name_scope
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/static/name_scope_cn.html#name-scope
)
。
-
quantize_op_types:需要进行量化的OP类型。通过以下代码输出所有支持量化的OP类型:
```
from paddleslim.quant.quanter import TRANSFORM_PASS_OP_TYPES,QUANT_DEQUANT_PASS_OP_TYPES
print(TRANSFORM_PASS_OP_TYPES + QUANT_DEQUANT_PASS_OP_TYPES)
```
-
dtype: 量化后的参数类型,默认 int8 , 目前仅支持 int8
-
window_size: 'range_abs_max' 量化方式的 window size ,默认10000。
-
moving_rate: 'moving_average_abs_max' 量化方式的衰减系数,默认 0.9。
-
for_tensorrt: 量化后的模型是否使用 TensorRT 进行预测。默认值为False. 通过以下代码,输出for_tensorrt=True时会量化到的OP:
```
from paddleslim.quant.quanter import TENSORRT_OP_TYPES
print(TENSORRT_OP_TYPES)
```
-
is_full_quantize: 是否量化所有可支持op类型。默认值为False.
### 1.1.2 知识蒸馏(knowledge distillation)
蒸馏参数主要设置蒸馏节点(
`node`
)和教师预测模型路径,如下所示:
蒸馏参数主要设置蒸馏节点(
`node`
)和教师预测模型路径,如下所示:
```
yaml
```
yaml
Distillation
:
Distillation
:
# alpha: 蒸馏loss所占权重;可输入多个数值,支持不同节点之间使用不同的ahpha值
alpha
:
1.0
alpha
:
1.0
# loss: 蒸馏loss算法;可输入多个loss,支持不同节点之间使用不同的loss算法
loss
:
l2
loss
:
l2
# node: 蒸馏节点,即某层输出的变量名称,可以选择:
# 1. 使用自蒸馏的话,蒸馏结点仅包含学生网络节点即可, 支持多节点蒸馏;
# 2. 使用其他蒸馏的话,蒸馏节点需要包含教师网络节点和对应的学生网络节点,
# 每两个节点组成一对,分别属于教师模型和学生模型,支持多节点蒸馏。
node
:
node
:
-
relu_30.tmp_0
-
relu_30.tmp_0
# teacher_model_dir: 保存预测模型文件和预测模型参数文件的文件夹名称
teacher_model_dir
:
./inference_model
teacher_model_dir
:
./inference_model
# teacher_model_filename: 预测模型文件,格式为 *.pdmodel 或 __model__
# teacher_model_filename: 预测模型文件,格式为 *.pdmodel 或 __model__
teacher_model_filename
:
model.pdmodel
teacher_model_filename
:
model.pdmodel
# teacher_params_filename: 预测模型参数文件,格式为 *.pdiparams 或 __params__
# teacher_params_filename: 预测模型参数文件,格式为 *.pdiparams 或 __params__
teacher_params_filename
:
model.pdiparams
teacher_params_filename
:
model.pdiparams
```
```
以上配置项说明如下:
-
alpha: 蒸馏loss所占权重;可输入多个数值,支持不同节点之间使用不同的alpha值。
-
loss: 蒸馏loss算法;可输入多个loss,支持不同节点之间使用不同的loss算法。 可选"soft_label"、“l2”或“fsp”。也可自定义loss。具体定义和使用可参考
[
知识蒸馏API文档
](
https://paddleslim.readthedocs.io/zh_CN/latest/api_cn/static/dist/single_distiller_api.html
)
。
-
node: 蒸馏节点,即某层输出的变量名称。该选项设置方式分两种情况:
-
蒸馏loss目前支持的有:fsp,l2,soft_label,也可自定义loss。具体定义和使用可参考
[
知识蒸馏API文档
](
https://paddleslim.readthedocs.io/zh_CN/latest/api_cn/static/dist/single_distiller_api.html
)
。
-
自蒸馏:教师模型为压缩前的推理模型,学生模型为压缩后的推理模型。‘node’ 可设置为变量名称的列表,ACT会自动在该列表中的变量上依次添加知识蒸馏loss。示例如下:
```
node:
- relu_30.tmp_0
- relu_31.tmp_0
```
上述示例,会添加两个知识蒸馏loss。第一个loss的输入为教师模型和学生模型的 'relu_30.tmp_0',第二个loss的输入为教师模型和学生模型的'relu_31.tmp_0'。
-
普通蒸馏:教师模型为任意模型,学生模型为压缩后的推理模型。‘node’ 可设置为变量名称的列表,列表中元素数量必须为偶数。示例如下:
```
node:
- teacher_relu_0.tmp_0
- student_relu_0.tmp_0
- teacher_relu_1.tmp_0
- student_relu_1.tmp_0
```
#### 配置定制结构化稀疏策略
上述示例,会添加两个知识蒸馏loss。第一个loss的输入为教师模型的变量“teacher_relu_0.tmp_0”和学生模型的变量“student_relu_0.tmp_0”,第二个loss的输入为教师模型的变量“teacher_relu_1.tmp_0”和学生模型的“student_relu_1.tmp_0”。
如果不设置
`node`
,则分别取教师模型和学生模型的最后一个带参数的层的输出,组成知识蒸馏loss.
-
teacher_model_dir: 用于监督压缩后模型训练的教师模型所在的路径。如果不设置该选项,则使用压缩前的模型做为教师模型。
-
teacher_model_filename: 教师模型的模型文件名称,格式为
*
.pdmodel 或 __model__。仅当设置
`teacher_model_dir`
后生效。
-
teacher_params_filename: 教师模型的参数文件名称,格式为
*
.pdiparams 或 __params__。仅当设置
`teacher_model_dir`
后生效。
### 1.1.3 结构化稀疏(sparsity)
结构化稀疏参数设置如下所示:
结构化稀疏参数设置如下所示:
```
yaml
```
yaml
ChannelPrune
:
ChannelPrune
:
# pruned_ratio: 裁剪比例
pruned_ratio
:
0.25
pruned_ratio
:
0.25
# prune_params_name: 需要裁剪的参数名字
prune_params_name
:
prune_params_name
:
-
conv1_weights
-
conv1_weights
# criterion: 评估一个卷积层内通道重要性所参考的指标
criterion
:
l1_norm
criterion
:
l1_norm
```
```
-
criterion目前支持的有:l1_norm , bn_scale , geometry_median。具体定义和使用可参考
[
结构化稀疏API文档
](
https://paddleslim.readthedocs.io/zh_CN/latest/api_cn/static/prune/prune_api.html
)
。
#### 配置定制ASP半结构化稀疏策略
-
pruned_ratio: 每个卷积层的通道数被剪裁的比例。
-
prune_params_name: 待剪裁的卷积层的权重名称。通过以下脚本获得推理模型中所有卷积层的权重名称:
```
import paddle
paddle.enable_static()
model_dir="./inference_model"
exe = paddle.static.Executor(paddle.CPUPlace())
[inference_program, feed_target_names, fetch_targets] = (
paddle.static.load_inference_model(model_dir, exe))
for var_ in inference_program.list_vars():
if var_.persistable and "conv2d" in var_.name:
print(f"{var_.name}")
```
或者,使用
[
Netron工具
](
https://netron.app/
)
可视化
`*.pdmodel`
模型文件,选择合适的卷积层进行剪裁。
-
criterion: 评估卷积通道重要性的指标。可选 “l1_norm” , “bn_scale” , “geometry_median”。具体定义和使用可参考
[
结构化稀疏API文档
](
https://paddleslim.readthedocs.io/zh_CN/latest/api_cn/static/prune/prune_api.html
)
。
### 1.1.4 ASP半结构化稀疏
半结构化稀疏参数设置如下所示:
半结构化稀疏参数设置如下所示:
```
yaml
```
yaml
ASPPrune
:
ASPPrune
:
# prune_params_name: 需要裁剪的参数名字
prune_params_name
:
prune_params_name
:
-
conv1_weights
-
conv1_weights
```
```
#### 配置定制针对Transformer结构的结构化剪枝策略
-
prune_params_name: 待剪裁的卷积层的权重名称。通过以下脚本获得推理模型中所有卷积层的权重名称:
```
import paddle
paddle.enable_static()
model_dir="./inference_model"
exe = paddle.static.Executor(paddle.CPUPlace())
[inference_program, feed_target_names, fetch_targets] = (
paddle.static.load_inference_model(model_dir, exe))
for var_ in inference_program.list_vars():
if var_.persistable and "conv2d" in var_.name:
print(f"{var_.name}")
```
或者,使用
[
Netron工具
](
https://netron.app/
)
可视化
`*.pdmodel`
模型文件,选择合适的卷积层进行剪裁。
### 1.1.5 Transformer结构化剪枝
针对Transformer结构的结构化剪枝参数设置如下所示:
针对Transformer结构的结构化剪枝参数设置如下所示:
```
yaml
```
yaml
TransformerPrune
:
TransformerPrune
:
# pruned_ratio: 每个全链接层的裁剪比例
pruned_ratio
:
0.25
pruned_ratio
:
0.25
```
```
-
pruned_ratio: 每个全链接层的被剪裁的比例。
###
# 配置定制
非结构化稀疏策略
###
1.1.6
非结构化稀疏策略
非结构化稀疏参数设置如下所示:
非结构化稀疏参数设置如下所示:
```
yaml
```
yaml
...
@@ -123,7 +201,7 @@ UnstructurePrune:
...
@@ -123,7 +201,7 @@ UnstructurePrune:
-
local_sparsity 表示剪裁比例(ratio)应用的范围,仅在 'ratio' 模式生效。local_sparsity 开启时意味着每个参与剪裁的参数矩阵稀疏度均为 'ratio', 关闭时表示只保证模型整体稀疏度达到'ratio',但是每个参数矩阵的稀疏度可能存在差异。各个矩阵稀疏度保持一致时,稀疏加速更显著。
-
local_sparsity 表示剪裁比例(ratio)应用的范围,仅在 'ratio' 模式生效。local_sparsity 开启时意味着每个参与剪裁的参数矩阵稀疏度均为 'ratio', 关闭时表示只保证模型整体稀疏度达到'ratio',但是每个参数矩阵的稀疏度可能存在差异。各个矩阵稀疏度保持一致时,稀疏加速更显著。
-
更多非结构化稀疏的参数含义详见
[
非结构化稀疏API文档
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/zh_cn/api_cn/dygraph/pruners/unstructured_pruner.rst
)
-
更多非结构化稀疏的参数含义详见
[
非结构化稀疏API文档
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/zh_cn/api_cn/dygraph/pruners/unstructured_pruner.rst
)
###
# 配置
训练超参
###
1.1.7
训练超参
训练参数主要设置学习率、训练次数(epochs)和优化器等。
训练参数主要设置学习率、训练次数(epochs)和优化器等。
```
yaml
```
yaml
...
@@ -144,12 +222,69 @@ TrainConfig:
...
@@ -144,12 +222,69 @@ TrainConfig:
boundaries
:
[
4500
]
# 设置策略参数
boundaries
:
[
4500
]
# 设置策略参数
values
:
[
0.005
,
0.0005
]
# 设置策略参数
values
:
[
0.005
,
0.0005
]
# 设置策略参数
```
```
##
其他参数配置
##
1.2 FAQ
###
#
1.自动蒸馏效果不理想,怎么自主选择蒸馏节点?
### 1.自动蒸馏效果不理想,怎么自主选择蒸馏节点?
首先使用
[
Netron工具
](
https://netron.app/
)
可视化
`model.pdmodel`
模型文件,选择模型中某些层输出Tensor名称,对蒸馏节点进行配置。(一般选择Backbone或网络的输出等层进行蒸馏)
首先使用
[
Netron工具
](
https://netron.app/
)
可视化
`model.pdmodel`
模型文件,选择模型中某些层输出Tensor名称,对蒸馏节点进行配置。(一般选择Backbone或网络的输出等层进行蒸馏)
<div
align=
"center"
>
<div
align=
"center"
>
<img
src=
"../../docs/images/dis_node.png"
width=
"600"
>
<img
src=
"../../docs/images/dis_node.png"
width=
"600"
>
</div>
</div>
### 2.如何获得推理模型中的OP类型
执行以下代码获取推理模型中的OP类型,其中
`model_dir`
为推理模型存储路径。
```
import paddle
paddle.enable_static()
model_dir="./inference_model"
exe = paddle.static.Executor(paddle.CPUPlace())
inference_program, _, _ = (
paddle.static.load_inference_model(model_dir, exe))
op_types = {}
for block in inference_program.blocks:
for op in block.ops:
op_types[op.type] = 1
print(f"Operators in inference model:\n{op_types.keys()}")
```
所用飞桨框架接口:
-
[
load_inference_model
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/static/load_inference_model_cn.html#load-inference-model
)
-
[
Program
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/static/Program_cn.html#program
)
-
[
Executor
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/static/Executor_cn.html#executor
)
### 3. 量化支持对哪些OP进行量化
执行以下代码,查看当前PaddlePaddle版本的量化功能所支持的OP类型:
```
from paddle.fluid.contrib.slim.quantization.utils import _weight_supported_quantizable_op_type, _act_supported_quantizable_op_type
print(f"_supported_quantizable_op_type:\n{_weight_supported_quantizable_op_type}")
print(f"_supported_quantizable_op_type:\n{_act_supported_quantizable_op_type}")
```
### 4. 如何设置推理模型中OP的‘name_scope’属性
以下代码,将输出变量为
`conv2d_52.tmp_0`
的OP的
`name_scope`
设置为'skip_quant':
```
import paddle
paddle.enable_static()
model_dir="./original_model"
exe = paddle.static.Executor(paddle.CPUPlace())
[inference_program, feed_target_names, fetch_targets] = (
paddle.static.load_inference_model(model_dir, exe))
skips = ['conv2d_52.tmp_0']
for block in inference_program.blocks:
for op in block.ops:
if op.output_arg_names[0] in skips:
op._set_attr("name_scope", "skip_quant")
feed_vars = []
for var_ in inference_program.list_vars():
if var_.name in feed_target_names:
feed_vars.append(var_)
paddle.static.save_inference_model("./infer_model", feed_vars, fetch_targets, exe, program=inference_program)
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录