Skip to content

Commit 3c84fbf

Browse files
committed
目标检测模型离线量化示例
1 parent e61ce8d commit 3c84fbf

File tree

5 files changed

+237
-20
lines changed

5 files changed

+237
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
metric: COCO
2+
num_classes: 80
3+
4+
# Datset configuration
5+
TrainDataset:
6+
!COCODataSet
7+
image_dir: train2017
8+
anno_path: annotations/instances_train2017.json
9+
dataset_dir: /work/GETR-Lite-paddle-new/inference/datasets/coco/
10+
EvalDataset:
11+
!COCODataSet
12+
image_dir: val2017
13+
anno_path: annotations/instances_val2017.json
14+
dataset_dir: /work/GETR-Lite-paddle-new/inference/datasets/coco/
15+
16+
eval_height: &eval_height 608
17+
eval_width: &eval_width 608
18+
eval_size: &eval_size [*eval_height, *eval_width]
19+
20+
worker_num: 0
21+
22+
EvalReader:
23+
inputs_def:
24+
image_shape: [1, 3, *eval_height, *eval_width]
25+
sample_transforms:
26+
- Decode: {}
27+
- Resize: {interp: 2, target_size: *eval_size, keep_ratio: False}
28+
- NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
29+
- Permute: {}
30+
batch_size: 4

example/post_training_quantization/detection/README.md

+162-12
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,37 @@
1717
## 1. 简介
1818
本示例将以目标检测模型PP-YOLOE和PicoDet为例,介绍如何使用PaddleDetection中Inference部署模型,使用离线量化功能进行压缩,并使用敏感度分析功能提升离线量化精度。
1919

20+
注意:[Paddle-Inference-demo/c++/gpu/yolov3](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/python/gpu/yolov3)使用量化校准表会有精度不对齐的情况,可对yolov3_r50vd_dcn_270e_coco模型进行离线量化。
2021

2122
## 2.Benchmark
2223

2324
| 模型 | 策略 | 输入尺寸 | mAP<sup>val<br>0.5:0.95 | 预测时延<sup><small>FP32</small><sup><br><sup>(ms) |预测时延<sup><small>FP16</small><sup><br><sup>(ms) | 预测时延<sup><small>INT8</small><sup><br><sup>(ms) | 配置文件 | Inference模型 |
2425
| :-------- |:-------- |:--------: | :---------------------: | :----------------: | :----------------: | :---------------: | :-----------------------------: | :-----------------------------: |
25-
| PP-YOLOE-s | Base模型 | 640*640 | 43.1 | 11.2ms | 7.7ms | - | - | [Model](https://bj.bcebos.com/v1/paddle-slim-models/act/ppyoloe_crn_s_300e_coco.tar) |
26-
| PP-YOLOE-s | 离线量化 | 640*640 | 42.6 | - | - | 6.7ms | - | [Model](https://bj.bcebos.com/v1/paddle-slim-models/act/ppyoloe_s_ptq.tar) |
26+
| yolov3_r50vd_dcn_270e_coco | Base模型 | 608*608 | 40.6 | 92.2ms | 41.3ms | - | - | [Model](https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo/yolov3_r50vd_dcn_270e_coco.tgz) |
27+
| yolov3_r50vd_dcn_270e_coco | 离线量化 | 608*608 | 40.3 | - | - | 27.9ms | - | |
2728
| | | | | | | | | |
28-
| PicoDet-s | Base模型 | 416*416 | 32.5 | - | - | - | - | [Model](https://paddledet.bj.bcebos.com/deploy/Inference/picodet_s_416_coco_lcnet.tar) |
29-
| PicoDet-s | 离线量化(量化分析前) | 416*416 | 0.0 | - | - | - | - | - |
30-
| PicoDet-s | 离线量化(量化分析后) | 416*416 | 24.9 | - | - | - | - | [Infer Model](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_ptq.tar) |
29+
| PicoDet-s | Base模型 | 416*416 | 32.5 | 82.5ms | 59.7ms | - | - | [Model](https://paddledet.bj.bcebos.com/deploy/Inference/picodet_s_416_coco_lcnet.tar) |
30+
| PicoDet-s | 离线量化(量化分析前) | 416*416 | 0.0 | - | - | 39.1ms | - | - |
31+
| PicoDet-s | 离线量化(量化分析后) | 416*416 | 24.9 | - | - | 64.8ms | - | [Infer Model](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_ptq.tar) |
3132

33+
mAP较低,导致目标框增多,NMS会增加耗时。
3234
- mAP的指标均在COCO val2017数据集中评测得到,IoU=0.5:0.95。
33-
35+
测速环境:Tesla T4,TensorRT 8.6.1,CUDA 11.2,batch_size=1,cudnn 8.2.0 Intel(R)Xeon(R)Gold 6271C CPU
3436

3537
## 3. 离线量化流程
3638

3739
#### 3.1 准备环境
38-
- PaddlePaddle >= 2.3 (可从[Paddle官网](https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/pip/linux-pip.html)下载安装)
39-
- PaddleSlim >= 2.3
40+
- PaddlePaddle == 2.6 (可从[Paddle官网](https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/pip/linux-pip.html)下载安装)
41+
- PaddleSlim 2.6
4042
- PaddleDet >= 2.4
4143
- opencv-python
4244

4345
安装paddlepaddle:
4446
```shell
4547
# CPU
46-
pip install paddlepaddle
47-
# GPU
48-
pip install paddlepaddle-gpu
48+
python -m pip install paddlepaddle==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
49+
# GPU 以cuda11.2为例子
50+
python -m pip install paddlepaddle-gpu==2.6.0.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
4951
```
5052

5153
安装paddleslim:
@@ -116,6 +118,12 @@ python post_quant.py --config_path=./configs/ppyoloe_s_ptq.yaml --save_dir=./ppy
116118
export CUDA_VISIBLE_DEVICES=0
117119
python post_quant.py --config_path=./configs/picodet_s_ptq.yaml --save_dir=./picodet_s_ptq
118120
```
121+
- yolov3_r50vd_dcn_270e_coco:
122+
123+
```
124+
export CUDA_VISIBLE_DEVICES=0
125+
python post_quant.py --config_path=./configs/yolov3_r50vd_dcn.yaml --save_dir=./yolov3_r50vd_dcn_270e_coco_ptq
126+
```
119127

120128

121129
#### 3.5 测试模型精度
@@ -125,12 +133,21 @@ python post_quant.py --config_path=./configs/picodet_s_ptq.yaml --save_dir=./pic
125133
export CUDA_VISIBLE_DEVICES=0
126134
python eval.py --config_path=./configs/ppyoloe_s_ptq.yaml
127135
```
136+
ppyoloe_s这个模型测试不出来精度,因为没有NMS
137+
```
138+
export CUDA_VISIBLE_DEVICES=0
139+
python eval.py --config_path=./configs/picodet_s_ptq.yaml
140+
```
141+
```
142+
export CUDA_VISIBLE_DEVICES=0
143+
python eval.py --config_path=./configs/yolov3_r50vd_dcn.yaml
144+
```
128145

129146
**注意**
130147
- 要测试的模型路径可以在配置文件中`model_dir`字段下进行修改。
131148

132149
#### 3.6 提高离线量化精度
133-
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisPTQ```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。```paddleslim.quant.AnalysisPTQ```详解见[AnalysisPTQ.md](../../../docs/zh_cn/tutorials/quant/AnalysisPTQ.md)
150+
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisPTQ```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。```paddleslim.quant.AnalysisPTQ```详解见[AnalysisPTQ.md](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/zh_cn/tutorials/quant/post_training_quantization.md)
134151

135152

136153
经过多个实验,包括尝试多种激活算法(avg,KL等)、weight的量化方式(abs_max,channel_wise_abs_max),对PicoDet-s进行离线量化后精度均为0,以PicoDet-s为例,量化分析工具具体使用方法如下:
@@ -171,6 +188,139 @@ python post_quant.py --config_path=./configs/picodet_s_analyzed_ptq.yaml --save_
171188
## 4.预测部署
172189
预测部署可参考[Detection模型自动压缩示例](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/example/auto_compression/detection)
173190

191+
量化模型可在GPU上可以使用TensorRT进行预测,在CPU上可以使用MKLDNN进行预测。
192+
193+
以下字段可用于配置预测参数:
194+
195+
| 参数名 | 含义 |
196+
|:------:|:------:|
197+
| model_path | inference 模型文件所在目录,该目录下需要有文件 model.pdmodel 和 model.pdiparams 两个文件 |
198+
| reader_config | eval时模型reader的配置文件路径 |
199+
| image_file | 如果只测试单张图片效果,直接根据image_file指定图片路径 |
200+
| device | 使用GPU或者CPU预测,可选CPU/GPU |
201+
| use_trt | 是否使用 TesorRT 预测引擎 |
202+
| use_mkldnn | 是否启用```MKL-DNN```加速库,注意```use_mkldnn``````use_gpu```同时为```True```时,将忽略```enable_mkldnn```,而使用```GPU```预测 |
203+
| cpu_threads | CPU预测时,使用CPU线程数量,默认10 |
204+
| precision | 预测精度,包括`fp32/fp16/int8` |
205+
| include_nms | 是否包含nms,如果不包含nms,则设置False,如果包含nms,则设置为True |
206+
| use_dynamic_shape | 是否使用动态shape,如果使用动态shape,则设置为True,否则设置为False |
207+
| img_shape | 输入图片的大小。这里默认为640,意味着图像将被调整到640*640 |
208+
| trt_calib_mode | 如果模型是通过TensorRT离线量化校准生成的,那么需要将此参数设置为True。|
209+
210+
-TesorRT预测示例:
211+
212+
yolov3_r50vd_dcn_270e_coco模型
213+
```shell
214+
python paddle_inference_eval.py \
215+
--model_path=yolov3_r50vd_dcn_270e_coco \
216+
--reader_config=configs/yolov3_r50vd_dcn.yml \
217+
--use_trt=True \
218+
--precision=fp32 \
219+
--include_nms=True \
220+
--benchmark=True
221+
```
222+
```shell
223+
python paddle_inference_eval.py \
224+
--model_path=yolov3_r50vd_dcn_270e_coco_ptq \
225+
--reader_config=configs/yolov3_r50vd_dcn.yml \
226+
--use_trt=True \
227+
--precision=int8 \
228+
--include_nms=True \
229+
--benchmark=True
230+
```
231+
picodet_s模型
232+
```shell
233+
python paddle_inference_eval.py \
234+
--model_path=picodet_s_416_coco_lcnet \
235+
--reader_config=configs/picodet_reader.yml \
236+
--use_trt=True \
237+
--precision=fp16 \
238+
--include_nms=True \
239+
--benchmark=True
240+
```
241+
量化分析前
242+
```shell
243+
python paddle_inference_eval.py \
244+
--model_path=picodet_s_ptq \
245+
--reader_config=configs/picodet_reader.yml \
246+
--use_trt=True \
247+
--precision= \
248+
--include_nms=True \
249+
--benchmark=True
250+
```
251+
量化分析后
252+
```shell
253+
python paddle_inference_eval.py \
254+
--model_path=picodet_s_analyzed_ptq_out \
255+
--reader_config=configs/picodet_reader.yml \
256+
--use_trt=True \
257+
--precision=int8 \
258+
--include_nms=True \
259+
--benchmark=True
260+
```
261+
#### 4.1 C++部署
262+
请参考[YOLOv3推理](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B/gpu/yolov3)
263+
264+
编译样例
265+
- 文件yolov3_test.cc改成PicoDet-s.cc,为预测的样例程序(程序中的输入为固定值,如果您有opencv或其他方式进行数据读取的需求,需要对程序进行一定的修改)。
266+
- 脚本compile.sh包含了第三方库、预编译库的信息配置。
267+
- 脚本run.sh为一键运行脚本。
268+
编译前,需要根据自己的环境修改compile.sh中的相关代码配置依赖库:
269+
270+
```shell
271+
# 编译的 demo 名称
272+
DEMO_NAME=picoDet-s
273+
274+
# 根据预编译库中的version.txt信息判断是否将以下三个标记打开
275+
WITH_MKL=ON
276+
WITH_GPU=ON
277+
USE_TENSORRT=ON
278+
279+
# 配置预测库的根目录
280+
LIB_DIR=${work_path}/../lib/paddle_inference
281+
282+
# 如果上述的WITH_GPU 或 USE_TENSORRT设为ON,请设置对应的CUDA, CUDNN, TENSORRT的路径。
283+
CUDNN_LIB=/usr/lib/x86_64-linux-gnu/
284+
CUDA_LIB=/usr/local/cuda/lib64
285+
TENSORRT_ROOT=/usr/local/TensorRT-7.1.3.4
286+
```
287+
运行bash compile.sh编译样例
288+
289+
- 运行样例
290+
使用原生GPU运行样例
291+
```shell
292+
./build/picodet-s --model_file picodet_s_416_coco_lenet/model.pdmodel --params_file picodet_s_416_coco_lenet/model.pdiparams
293+
```
294+
使用Trt FP32运行样例
295+
```shell
296+
./build/picodet-s --model_file picodet_s_416_coco_lenet/model.pdmodel --params_file picodet_s_416_coco_lenet/model.pdiparams --run_mode=trt_fp32
297+
```
298+
使用Trt FP16运行样例
299+
```shell
300+
./build/picodet-s --model_file picodet_s_416_coco_lenet/model.pdmodel --params_file picodet_s_416_coco_lenet/model.pdiparams --run_mode=trt_fp16
301+
```
302+
使用Trt Int8运行样例
303+
在使用Trt Int8运行样例时,相同的运行命令需要执行两次。
304+
生成量化校准表
305+
```shell
306+
./build/picodet-s --model_file picodet_s_416_coco_lcnet/model.pdmodel --params_file picodet_s_416_coco_lcnet/model.pdiparams --run_mode=trt_int8
307+
```
308+
加载校准表预测的log:
309+
```shell
310+
I0623 08:40:49.386909 107053 tensorrt_engine_op.h:159] This process is generating calibration table for Paddle TRT int8...
311+
I0623 08:40:49.387279 107057 tensorrt_engine_op.h:352] Prepare TRT engine (Optimize model structure, Select OP kernel etc). This process may cost a lot of time.
312+
I0623 08:41:13.784473 107053 analysis_predictor.cc:791] Wait for calib threads done.
313+
I0623 08:41:14.419198 107053 analysis_predictor.cc:793] Generating TRT Calibration table data, this may cost a lot of time...
314+
```
315+
使用Trt dynamic shape运行样例(以Trt FP32为例)
316+
```shell
317+
./build/picodet-s --model_file picodet_s_416_coco_lcnet/model.pdmodel --params_file picodet_s_416_coco_lcnet/model.pdiparams --run_mode=trt_fp32 --use_dynamic_shape=1
318+
```
319+
| 模型 | trt-fp32 | trt-fp16 | trt-int8 | paddle_gpu fp32 | trt_fp32(dynamic_shape) |
320+
|:------:|:------:|:------:|:------:| :------:| :------:|
321+
| PicoDet-s | 3.05ms | 2.66ms | 2.40ms | 7.51ms | 2.82ms |
322+
测速环境:Tesla T4,TensorRT 8.6.1,CUDA 11.6,batch_size=1,cudnn 8.4.0 Intel(R)Xeon(R)Gold 6271C CPU
323+
174324
## 5.FAQ
175325

176326
- 如果想对模型进行自动压缩,可进入[Detection模型自动压缩示例](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/example/auto_compression/detection)中进行实验。

example/post_training_quantization/detection/configs/picodet_s_analysis.yaml

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
input_list: ['image', 'scale_factor']
2-
model_dir: ./picodet_s_416_coco_lcnet/
2+
model_dir: ./picodet_s_416_coco_lcnet
33
model_filename: model.pdmodel
44
params_filename: model.pdiparams
55
save_dir: ./analysis_results
@@ -26,11 +26,11 @@ EvalDataset:
2626

2727
# Small Dataset to accelerate analysis
2828
# If not exist, delete the dict of FastEvalDataset
29-
FastEvalDataset:
30-
!COCODataSet
31-
image_dir: val2017
32-
anno_path: annotations/small_instances_val2017.json
33-
dataset_dir: /dataset/coco/
29+
# FastEvalDataset:
30+
# !COCODataSet
31+
# image_dir: val2017
32+
# anno_path: annotations/small_instances_val2017.json
33+
# dataset_dir: /dataset/coco/
3434

3535

3636
eval_height: &eval_height 416

example/post_training_quantization/detection/configs/ppyoloe_s_ptq.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
input_list: ['image']
1+
input_list: ['image','scale_factor']
22
arch: PPYOLOE # When export exclude_nms=True, need set arch: PPYOLOE
33
model_dir: ./ppyoloe_crn_s_300e_coco
44
model_filename: model.pdmodel
@@ -29,4 +29,4 @@ EvalReader:
2929
- Resize: {target_size: [640, 640], keep_ratio: False, interp: 2}
3030
- NormalizeImage: {mean: [0.485, 0.456, 0.406], std: [0.229, 0.224, 0.225], is_scale: True}
3131
- Permute: {}
32-
batch_size: 32
32+
batch_size: 16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
input_list: ['image', 'scale_factor','im_shape']
2+
model_dir: ./yolov3_r50vd_dcn_270e_coco
3+
model_filename: model.pdmodel
4+
params_filename: model.pdiparams
5+
metric: COCO
6+
num_classes: 80
7+
8+
# Datset configuration
9+
TrainDataset:
10+
!COCODataSet
11+
image_dir: train2017
12+
anno_path: annotations/instances_train2017.json
13+
dataset_dir: /work/GETR-Lite-paddle-new/inference/datasets/coco/
14+
15+
EvalDataset:
16+
!COCODataSet
17+
image_dir: val2017
18+
anno_path: annotations/instances_val2017.json
19+
dataset_dir: /work/GETR-Lite-paddle-new/inference/datasets/coco/
20+
21+
eval_height: &eval_height 608
22+
eval_width: &eval_width
23+
eval_size: &eval_size [*eval_height, *eval_width]
24+
25+
worker_num: 0
26+
27+
# preprocess reader in test
28+
EvalReader:
29+
inputs_def:
30+
image_shape: [1, 3, *eval_height, *eval_width]
31+
sample_transforms:
32+
- Decode: {}
33+
- Resize: {interp: 2, target_size: *eval_size, keep_ratio: False}
34+
- NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
35+
- Permute: {}
36+
batch_size: 4
37+

0 commit comments

Comments
 (0)