Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleSlim
提交
0db9a28e
P
PaddleSlim
项目概览
PaddlePaddle
/
PaddleSlim
大约 1 年 前同步成功
通知
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看板
未验证
提交
0db9a28e
编写于
5月 18, 2022
作者:
G
Guanghua Yu
提交者:
GitHub
5月 18, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update ACT quick start demo (#1116)
上级
bdffa0fa
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
153 addition
and
51 deletion
+153
-51
demo/auto_compression/README.md
demo/auto_compression/README.md
+54
-18
demo/auto_compression/image_classification/README.md
demo/auto_compression/image_classification/README.md
+10
-10
demo/auto_compression/image_classification/configs/mobilenetv1_qat_dis.yaml
...ion/image_classification/configs/mobilenetv1_qat_dis.yaml
+0
-0
paddleslim/auto_compression/auto_strategy.py
paddleslim/auto_compression/auto_strategy.py
+31
-9
paddleslim/auto_compression/compressor.py
paddleslim/auto_compression/compressor.py
+58
-14
未找到文件。
demo/auto_compression/README.md
浏览文件 @
0db9a28e
# 自动压缩工具ACT(Auto Compression Tookit)
# 自动
化
压缩工具ACT(Auto Compression Tookit)
## 简介
PaddleSlim推出全新自动
压缩工具(ACT),旨在通过Source-Free的方式,自动对预测模型进行压缩,压缩后模型可直接部署应用。ACT自动
压缩工具主要特性如下:
PaddleSlim推出全新自动
化压缩工具(ACT),旨在通过Source-Free的方式,自动对预测模型进行压缩,压缩后模型可直接部署应用。ACT自动化
压缩工具主要特性如下:
-
**『更便捷』**
:开发者无需了解或修改模型源码,直接使用导出的预测模型进行压缩;
-
**『更智能』**
:开发者简单配置即可启动压缩,ACT工具会自动优化得到最好预测模型;
-
**『更丰富』**
:ACT中提供了量化训练、蒸馏、结构化剪枝、非结构化剪枝、多种离线量化方法及超参搜索等等,可任意搭配使用。
...
...
@@ -14,32 +14,68 @@ PaddleSlim推出全新自动压缩工具(ACT),旨在通过Source-Free的
## 快速上手
-
1.准备模型及数据集
```
shell
# 下载MobileNet预测模型
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/MobileNetV1_infer.tar
tar
-xf
MobileNetV1_infer.tar
# 下载ImageNet小型数据集
wget https://sys-p0.bj.bcebos.com/slim_ci/ILSVRC2012_data_demo.tar.gz
tar
xf ILSVRC2012_data_demo.tar.gz
```
-
2.运行
```
python
# 导入依赖包
from
paddleslim.auto_compression.config_helpers
import
load_config
import
paddle
from
PIL
import
Image
from
paddle.vision.datasets
import
DatasetFolder
from
paddle.vision.transforms
import
transforms
from
paddleslim.auto_compression
import
AutoCompression
from
paddleslim.common.imagenet_reader
import
reader
# 加载配置文件
compress_config
,
train_config
=
load_slim_config
(
"./image_classification/mobilenetv1_qat_dis.yaml"
)
paddle
.
enable_static
()
# 定义DataSet
class
ImageNetDataset
(
DatasetFolder
):
def
__init__
(
self
,
path
,
image_size
=
224
):
super
(
ImageNetDataset
,
self
).
__init__
(
path
)
normalize
=
transforms
.
Normalize
(
mean
=
[
123.675
,
116.28
,
103.53
],
std
=
[
58.395
,
57.120
,
57.375
])
self
.
transform
=
transforms
.
Compose
([
transforms
.
Resize
(
256
),
transforms
.
CenterCrop
(
image_size
),
transforms
.
Transpose
(),
normalize
])
def
__getitem__
(
self
,
idx
):
img_path
,
_
=
self
.
samples
[
idx
]
return
self
.
transform
(
Image
.
open
(
img_path
).
convert
(
'RGB'
))
def
__len__
(
self
):
return
len
(
self
.
samples
)
# 定义DataLoader
train_loader
=
reader
(
mode
=
'test'
)
# DataLoader
train_dataset
=
ImageNetDataset
(
"./ILSVRC2012_data_demo/ILSVRC2012/train/"
)
image
=
paddle
.
static
.
data
(
name
=
'inputs'
,
shape
=
[
None
]
+
[
3
,
224
,
224
],
dtype
=
'float32'
)
train_loader
=
paddle
.
io
.
DataLoader
(
train_dataset
,
feed_list
=
[
image
],
batch_size
=
32
)
# 开始自动压缩
ac
=
AutoCompression
(
model_dir
=
"./
mobilenetv1_infer
"
,
model_filename
=
"
model
.pdmodel"
,
params_filename
=
"
model
.pdiparams"
,
model_dir
=
"./
MobileNetV1_infer/
"
,
model_filename
=
"
inference
.pdmodel"
,
params_filename
=
"
inference
.pdiparams"
,
save_dir
=
"output"
,
strategy_config
=
compress_config
,
train_config
=
train_config
,
strategy_config
=
None
,
train_config
=
None
,
train_dataloader
=
train_loader
,
eval_
callback
=
None
)
# eval_function to verify accuracy
eval_
dataloader
=
train_loader
)
# eval_function to verify accuracy
ac
.
compress
()
```
**提示:**
-
DataLoader传入的数据集是待压缩模型所用的数据集,DataLoader继承自
`paddle.io.DataLoader`
。
-
如无需验证自动压缩过程中模型的精度,
`eval_callback`
可不传入function,程序会自动根据损失来选择最优模型。
-
自动压缩Config中定义量化、蒸馏、剪枝等压缩算法会合并执行,压缩策略有:量化+蒸馏,剪枝+蒸馏等等。
-
如无需验证自动
化
压缩过程中模型的精度,
`eval_callback`
可不传入function,程序会自动根据损失来选择最优模型。
-
自动
化
压缩Config中定义量化、蒸馏、剪枝等压缩算法会合并执行,压缩策略有:量化+蒸馏,剪枝+蒸馏等等。
## 应用示例
...
...
@@ -52,11 +88,11 @@ ac.compress()
#### [NLP](./nlp)
#### 即将发布
-
[ ] 更多自动压缩应用示例
-
[ ] X2Paddle模型自动压缩示例
-
[ ] 更多自动
化
压缩应用示例
-
[ ] X2Paddle模型自动
化
压缩示例
## 其他
-
ACT可以自动处理常见的预测模型,如果有更特殊的改造需求,可以参考
[
ACT超参配置教程
](
./hyperparameter_tutorial.md
)
来进行单独配置压缩策略。
-
如果你发现任何关于ACT自动压缩工具的问题或者是建议, 欢迎通过
[
GitHub Issues
](
https://github.com/PaddlePaddle/PaddleSlim/issues
)
给我们提issues。同时欢迎贡献更多优秀模型,共建开源生态。
-
如果你发现任何关于ACT自动
化
压缩工具的问题或者是建议, 欢迎通过
[
GitHub Issues
](
https://github.com/PaddlePaddle/PaddleSlim/issues
)
给我们提issues。同时欢迎贡献更多优秀模型,共建开源生态。
demo/auto_compression/image_classification/README.md
浏览文件 @
0db9a28e
...
...
@@ -18,9 +18,9 @@
## 2. Benchmark
-
MobileNetV1模型
| 模型 | 策略 | Top-1 Acc | 耗时(ms) threads=4 |
| 模型 | 策略 | Top-1 Acc | 耗时(ms) threads=4 |
|:------:|:------:|:------:|:------:|
| MobileNetV1 | Base模型 | 70.90 | 39.041 |
| MobileNetV1 | Base模型 | 70.90 | 39.041 |
| MobileNetV1 | 量化+蒸馏 | 70.49 | 29.238|
-
测试环境:
`SDM710 2*A75(2.2GHz) 6*A55(1.7GHz)`
...
...
@@ -59,7 +59,7 @@ pip install paddleslim
```
shell
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/MobileNetV1_infer.tar
tar
-
zxv
f
MobileNetV1_infer.tar
tar
-
x
f
MobileNetV1_infer.tar
```
也可根据
[
PaddleClas文档
](
https://github.com/PaddlePaddle/PaddleClas/blob/release/2.3/docs/zh_CN/inference_deployment/export_model.md
)
导出Inference模型。
...
...
@@ -73,20 +73,20 @@ python run.py \
--model_dir
=
'MobileNetV1_infer'
\
--model_filename
=
'inference.pdmodel'
\
--params_filename
=
'inference.pdiparams'
\
--save_dir
=
'./
save_quant_mobilev1/
'
\
--save_dir
=
'./
output
'
\
--batch_size
=
128
\
--config_path
=
'./configs/mobile
v1
.yaml'
\
--config_path
=
'./configs/mobile
netv1_qat_dis
.yaml'
\
--data_dir
=
'ILSVRC2012'
# 多卡启动
python
-m
paddle.distributed.launch run.py
\
--model_dir
=
'MobileNetV1_infer'
\
--model_filename
=
'inference.pdmodel'
\
--params_filename
=
'inference.pdiparams'
\
--save_dir
=
'./
save_quant_mobilev1/
'
\
--save_dir
=
'./
output
'
\
--batch_size
=
128
\
--config_path
=
'./configs/mobile
v1
.yaml'
\
--data_dir
=
'ILSVRC2012'
--config_path
=
'./configs/mobile
netv1_qat_dis
.yaml'
\
--data_dir
=
'ILSVRC2012'
```
...
...
@@ -96,4 +96,4 @@ python -m paddle.distributed.launch run.py \
-
[
Paddle Inference C++部署
](
https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.5/docs/deployment/inference/cpp_inference.md
)
-
[
Paddle Lite部署
](
https://github.com/PaddlePaddle/PaddleSeg/blob/release/2.5/docs/deployment/lite/lite.md
)
## 5.FAQ
\ No newline at end of file
## 5.FAQ
demo/auto_compression/image_classification/configs/mobile
v1
.yaml
→
demo/auto_compression/image_classification/configs/mobile
netv1_qat_dis
.yaml
浏览文件 @
0db9a28e
文件已移动
paddleslim/auto_compression/auto_strategy.py
浏览文件 @
0db9a28e
...
...
@@ -25,16 +25,16 @@ __all__ = [
"prepare_strategy"
,
"create_strategy_config"
,
"get_final_quant_config"
]
#
##
config tester to test the loss of quant_post
# config tester to test the loss of quant_post
hpo_config_tester
=
{
"ptq_algo"
:
[
"avg"
,
"mse"
,
"KL"
],
"ptq_algo"
:
[
"avg"
],
"weight_quantize_type"
:
[
'channel_wise_abs_max'
,
'abs_max'
],
"bias_correct"
:
[
False
],
"batch_num"
:
[
2
,
3
],
"batch_num"
:
[
5
],
"max_quant_count"
:
1
,
}
#
##
default hpo config
# default hpo config
default_hpo_config
=
{
"ptq_algo"
:
[
"KL"
,
"hist"
,
"avg"
,
"mse"
],
"weight_quantize_type"
:
[
'channel_wise_abs_max'
,
'abs_max'
],
...
...
@@ -44,11 +44,26 @@ default_hpo_config = {
"max_quant_count"
:
20
,
}
#
##
default quant config, can be used by ptq&hpo and qat&distillation
# default quant config, can be used by ptq&hpo and qat&distillation
default_quant_config
=
{
'quantize_op_types'
:
[
'conv2d'
,
'depthwise_conv2d'
,
'mul'
,
'matmul'
],
'weight_bits'
:
8
,
'activation_bits'
:
8
'activation_bits'
:
8
,
"is_full_quantize"
:
False
,
"activation_quantize_type"
:
'range_abs_max'
,
"weight_quantize_type"
:
'abs_max'
,
"not_quant_pattern"
:
[
"skip_quant"
],
}
# default train config
DefaultTrainConfig
=
{
"epochs"
:
1
,
"eval_iter"
:
500
,
"learning_rate"
:
0.0001
,
"optimizer"
:
"Momentum"
,
"optim_args"
:
{
"weight_decay"
:
4.0e-05
},
}
EXPERIENCE_STRATEGY_WITHOUT_LOSS
=
[
...
...
@@ -118,6 +133,12 @@ def create_strategy_config(strategy_str, model_type):
return
configs
def
create_train_config
(
strategy_str
,
model_type
):
# TDOD: support more strategy and model_type
train_config
=
TrainConfig
(
**
DefaultTrainConfig
)
return
train_config
def
prepare_strategy
(
model_dir
,
model_filename
,
params_filename
,
...
...
@@ -203,9 +224,9 @@ def prepare_strategy(model_dir,
return
strategy_config
def
get_final_quant_config
(
ptq_loss
):
def
get_final_quant_config
(
ptq_loss
,
mode
=
'DistilQuant'
):
""" transform quantization tester config to real quantization config """
if
ptq_loss
<=
MAGIC_EMD_DISTANCE
:
if
mode
==
'HPO'
:
quant_config
=
Quantization
(
**
default_quant_config
)
hpo_config
=
HyperParameterOptimization
(
**
default_hpo_config
)
configs
=
[{
...
...
@@ -213,10 +234,11 @@ def get_final_quant_config(ptq_loss):
'HyperParameterOptimization'
:
hpo_config
}]
else
:
if
mode
==
'DistilQuant'
:
quant_config
=
Quantization
(
**
default_quant_config
)
dis_config
=
Distillation
()
configs
=
[{
'Quantization'
:
quant_config
,
'Distillation'
:
dis_config
}]
_logger
.
info
(
"Start Quantization and Distillation Training."
)
return
configs
...
...
paddleslim/auto_compression/compressor.py
浏览文件 @
0db9a28e
...
...
@@ -24,14 +24,14 @@ import paddle
import
paddle.distributed.fleet
as
fleet
if
platform
.
system
().
lower
()
==
'linux'
:
from
..quant
import
quant_post_hpo
from
..quant.quanter
import
convert
from
..quant.quanter
import
convert
,
quant_post
from
..common.recover_program
import
recover_inference_program
from
..common
import
get_logger
from
..common.patterns
import
get_patterns
from
..analysis
import
TableLatencyPredictor
from
.create_compressed_program
import
build_distill_program
,
build_quant_program
,
build_prune_program
,
remove_unused_var_nodes
from
.strategy_config
import
ProgramInfo
,
merge_config
from
.auto_strategy
import
prepare_strategy
,
get_final_quant_config
,
create_strategy_config
from
.auto_strategy
import
prepare_strategy
,
get_final_quant_config
,
create_strategy_config
,
create_train_config
_logger
=
get_logger
(
__name__
,
level
=
logging
.
INFO
)
...
...
@@ -143,6 +143,11 @@ class AutoCompression:
self
.
_strategy
,
self
.
_config
=
self
.
_prepare_strategy
(
self
.
strategy_config
)
# If train_config is None, set default train_config
if
self
.
train_config
is
None
:
self
.
train_config
=
create_train_config
(
self
.
strategy_config
,
self
.
model_type
)
def
_prepare_envs
(
self
):
devices
=
paddle
.
device
.
get_device
().
split
(
':'
)[
0
]
places
=
paddle
.
device
.
_convert_to_place
(
devices
)
...
...
@@ -248,8 +253,9 @@ class AutoCompression:
feed_target_names
,
fetch_targets
)
config_dict
=
dict
(
config
.
_asdict
())
if
config_dict
[
"prune_strategy"
]
==
"gmp"
and
config_dict
[
'gmp_config'
]
is
None
:
if
"prune_strategy"
in
config_dict
and
config_dict
[
"prune_strategy"
]
==
"gmp"
and
config_dict
[
'gmp_config'
]
is
None
:
_logger
.
info
(
"Calculating the iterations per epoch……(It will take some time)"
)
# NOTE:XXX: This way of calculating the iters needs to be improved.
...
...
@@ -351,20 +357,57 @@ class AutoCompression:
).
lower
()
==
'linux'
:
ptq_loss
=
quant_post_hpo
.
g_min_emd_loss
final_quant_config
=
get_final_quant_config
(
ptq_loss
)
final_quant_config
=
get_final_quant_config
(
ptq_loss
,
mode
=
'DistilQuant'
)
quant_strategy
,
quant_config
=
self
.
_prepare_strategy
(
final_quant_config
)
self
.
single_strategy_compress
(
quant_strategy
[
0
],
quant_config
[
0
],
strategy_idx
)
old
_model_path
=
os
.
path
.
join
(
tmp
_model_path
=
os
.
path
.
join
(
self
.
save_dir
,
'strategy_{}'
.
format
(
str
(
strategy_idx
+
1
)))
final_model_path
=
os
.
path
.
join
(
self
.
final_dir
)
shutil
.
move
(
old_model_path
,
final_model_path
)
if
not
os
.
path
.
exists
(
final_model_path
):
os
.
makedirs
(
final_model_path
)
tmp_model_file
=
os
.
path
.
join
(
tmp_model_path
,
'model.pdmodel'
)
tmp_params_file
=
os
.
path
.
join
(
tmp_model_path
,
'model.pdiparams'
)
final_model_file
=
os
.
path
.
join
(
final_model_path
,
'model.pdmodel'
)
final_params_file
=
os
.
path
.
join
(
final_model_path
,
'model.pdiparams'
)
shutil
.
move
(
tmp_model_file
,
final_model_file
)
shutil
.
move
(
tmp_params_file
,
final_params_file
)
_logger
.
info
(
"==> Finished the ACT process and the final model is saved in:{}"
.
format
(
final_model_path
))
os
.
_exit
(
0
)
def
single_strategy_compress
(
self
,
strategy
,
config
,
strategy_idx
):
### start compress, including train/eval model
if
strategy
==
'ptq_hpo'
:
# start compress, including train/eval model
# TODO: add the emd loss of evaluation model.
if
strategy
==
'quant_post'
:
quant_post
(
self
.
_exe
,
model_dir
=
self
.
model_dir
,
quantize_model_path
=
os
.
path
.
join
(
self
.
save_dir
,
'strategy_{}'
.
format
(
str
(
strategy_idx
+
1
))),
data_loader
=
self
.
train_dataloader
,
model_filename
=
self
.
model_filename
,
params_filename
=
self
.
params_filename
,
save_model_filename
=
self
.
model_filename
,
save_params_filename
=
self
.
params_filename
,
batch_size
=
1
,
batch_nums
=
config
.
batch_num
,
algo
=
config
.
ptq_algo
,
round_type
=
'round'
,
bias_correct
=
config
.
bias_correct
,
hist_percent
=
config
.
hist_percent
,
quantizable_op_type
=
config
.
quantize_op_types
,
is_full_quantize
=
config
.
is_full_quantize
,
weight_bits
=
config
.
weight_bits
,
activation_bits
=
config
.
activation_bits
,
activation_quantize_type
=
'range_abs_max'
,
weight_quantize_type
=
config
.
weight_quantize_type
,
onnx_format
=
False
)
elif
strategy
==
'ptq_hpo'
:
if
platform
.
system
().
lower
()
!=
'linux'
:
raise
NotImplementedError
(
"post-quant-hpo is not support in system other than linux"
)
...
...
@@ -503,11 +546,12 @@ class AutoCompression:
test_program_info
.
program
,
paddle
.
static
.
CompiledProgram
)
else
test_program_info
.
program
paddle
.
static
.
load
(
test_program
,
os
.
path
.
join
(
self
.
save_dir
,
'best_model'
))
os
.
remove
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdmodel'
))
os
.
remove
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdopt'
))
os
.
remove
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdparams'
))
if
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdparams'
)):
paddle
.
static
.
load
(
test_program
,
os
.
path
.
join
(
self
.
save_dir
,
'best_model'
))
os
.
remove
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdmodel'
))
os
.
remove
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdopt'
))
os
.
remove
(
os
.
path
.
join
(
self
.
save_dir
,
'best_model.pdparams'
))
if
'qat'
in
strategy
:
float_program
,
int8_program
=
convert
(
test_program_info
.
program
.
_program
,
self
.
_places
,
self
.
_quant_config
,
\
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录