Skip to content

Commit c634106

Browse files
committed
Merge branch 'develop' of https://github.com/PaddlePaddle/PaddleSlim into develop
2 parents 0df32a4 + 9dba994 commit c634106

File tree

6 files changed

+212
-84
lines changed

6 files changed

+212
-84
lines changed

example/auto_compression/detection/README.md

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,20 @@
7878
安装paddlepaddle:
7979
```shell
8080
# CPU
81-
pip install paddlepaddle==2.4.1
82-
# GPU 以Ubuntu、CUDA 11.2为例
83-
python -m pip install paddlepaddle-gpu==2.4.1.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
81+
python -m pip install paddlepaddle==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
82+
#GPU 以ubuntu、CUDA11.6为例
83+
python -m pip install paddlepaddle-gpu==2.6.0.post116 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
8484
```
8585

8686
安装paddleslim:
8787
```shell
8888
pip install paddleslim
8989
```
90-
90+
源码安装(推荐):
91+
```shell
92+
git clone -b release/2.6 https://github.com/PaddlePaddle/PaddleSlim.git & cd PaddleSlim
93+
python setup.py install
94+
```
9195
安装paddledet:
9296
```shell
9397
pip install paddledet
@@ -101,7 +105,7 @@ pip install paddledet
101105

102106
如果数据集为非COCO格式数据,请修改[configs](./configs)中reader配置文件中的Dataset字段。
103107

104-
以PP-YOLOE模型为例,如果已经准备好数据集,请直接修改[./configs/yolo_reader.yml]`EvalDataset``dataset_dir`字段为自己数据集路径即可。
108+
以PP-YOLOE模型为例,如果已经准备好数据集,请直接修改[./configs/yolo_reader.yml]`EvalDataset``TrainDataset'`dataset_dir`字段为自己数据集路径即可。
105109

106110
#### 3.3 准备预测模型
107111

@@ -113,10 +117,16 @@ pip install paddledet
113117
根据[PaddleDetection文档](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/docs/tutorials/GETTING_STARTED_cn.md#8-%E6%A8%A1%E5%9E%8B%E5%AF%BC%E5%87%BA) 导出Inference模型,具体可参考下方PP-YOLOE模型的导出示例:
114118
- 下载代码
115119
```
116-
git clone https://github.com/PaddlePaddle/PaddleDetection.git
120+
git clone -b release/2.6 https://github.com/PaddlePaddle/PaddleDetection.git
117121
```
118122
- 导出预测模型
119-
123+
- 当你使用Paddle Inference但不使用TensorRT时,运行以下命令导出模型(不包含NMS)
124+
```shell
125+
python tools/export_model.py \
126+
-c configs/ppyoloe/ppyoloe_crn_s_300e_coco.yml \
127+
-o weights=https://paddledet.bj.bcebos.com/models/ppyoloe_crn_s_300e_coco.pdparams \
128+
exclude_post_process=True \
129+
```
120130
PPYOLOE-l模型,包含NMS:如快速体验,可直接下载[PP-YOLOE-l导出模型](https://bj.bcebos.com/v1/paddle-slim-models/act/ppyoloe_crn_l_300e_coco.tar)
121131
```shell
122132
python tools/export_model.py \
@@ -146,7 +156,7 @@ python tools/export_model.py \
146156
#### 3.4 自动压缩并产出模型
147157

148158
蒸馏量化自动压缩示例通过run.py脚本启动,会使用接口```paddleslim.auto_compression.AutoCompression```对模型进行自动压缩。配置config文件中模型路径、蒸馏、量化、和训练等部分的参数,配置完成后便可对模型进行量化和蒸馏。具体运行命令为:
149-
159+
注意!!!,ppyoloe_s_qat_dis.yaml中属性include_nms,它默认为False,如果你导出的模型有nms,则将它修改为True。
150160
- 单卡训练:
151161
```
152162
export CUDA_VISIBLE_DEVICES=0
@@ -155,11 +165,10 @@ python run.py --config_path=./configs/ppyoloe_l_qat_dis.yaml --save_dir='./outpu
155165

156166
- 多卡训练:
157167
```
158-
CUDA_VISIBLE_DEVICES=0,1,2,3 python -m paddle.distributed.launch --log_dir=log --gpus 0,1,2,3 run.py \
159-
--config_path=./configs/ppyoloe_l_qat_dis.yaml --save_dir='./output/'
168+
export CUDA_VISIBLE_DEVICES=0,1,2,3
169+
python -m paddle.distributed.launch run.py --save_dir='./rtdetr_hgnetv2_l_6x_coco_quant' --config_path=./configs/rtdetr_hgnetv2_l_qat_dis.yaml
160170
```
161171

162-
163172
## 4.预测部署
164173

165174
#### 4.1 Paddle Inference 验证性能
@@ -178,20 +187,45 @@ CUDA_VISIBLE_DEVICES=0,1,2,3 python -m paddle.distributed.launch --log_dir=log -
178187
| use_mkldnn | 是否启用```MKL-DNN```加速库,注意```use_mkldnn``````use_gpu```同时为```True```时,将忽略```enable_mkldnn```,而使用```GPU```预测 |
179188
| cpu_threads | CPU预测时,使用CPU线程数量,默认10 |
180189
| precision | 预测精度,包括`fp32/fp16/int8` |
190+
| include_nms | 是否包含nms,如果不包含nms,则设置False,如果包含nms,则设置为True |
191+
| use_dynamic_shape | 是否使用动态shape,如果使用动态shape,则设置为True,否则设置为False |
192+
| image_shape | 输入图片的大小。这里默认为640,意味着图像将被调整到640*640 |
193+
| trt_calib_mode | 如果模型是通过TensorRT离线量化校准生成的,那么需要将此参数设置为True。|
181194

182195

183196
- TensorRT预测:
184197

185198
环境配置:如果使用 TesorRT 预测引擎,需安装 ```WITH_TRT=ON``` 的Paddle,下载地址:[Python预测库](https://paddleinference.paddlepaddle.org.cn/master/user_guides/download_lib.html#python)
186-
199+
带NMS的
187200
```shell
188201
python paddle_inference_eval.py \
189-
--model_path=models/ppyoloe_crn_l_300e_coco_quant \
190-
--reader_config=configs/yoloe_reader.yml \
191-
--use_trt=True \
192-
--precision=int8
202+
--model_path=ppyoloe_crn_s_300e_coco \
203+
--reader_config=configs/yolo_reader.yml \
204+
--use_trt=True \
205+
--precision=fp16 \
206+
--include_nms=True \
207+
--benchmark=True
208+
```
209+
不带NMS的
210+
```shell
211+
python paddle_inference_eval.py \
212+
--model_path=ppyoloe_crn_l_300e_coco \
213+
--reader_config=configs/yolo_reader.yml \
214+
--use_trt=True \
215+
--precision=fp16 \
216+
--include_nms=False \
217+
--benchmark=True
218+
```
219+
- 原生GPU预测:
220+
```shell
221+
python paddle_inference_eval.py \
222+
--model_path=ppyoloe_crn_s_300e_coco \
223+
--reader_config=configs/yolo_reader.yml \
224+
--device=GPU \
225+
--precision=fp16 \
226+
--include_nms=True \
227+
--benchmark=True
193228
```
194-
195229
- MKLDNN预测:
196230

197231
```shell
@@ -206,13 +240,7 @@ python paddle_inference_eval.py \
206240

207241
- 模型为PPYOLOE,同时不包含NMS,可以使用C++预测demo进行测速:
208242

209-
进入[cpp_infer](./cpp_infer_ppyoloe)文件夹内,请按照[C++ TensorRT Benchmark测试教程](./cpp_infer_ppyoloe/README.md)进行准备环境及编译,然后开始测试:
210-
```shell
211-
# 编译
212-
bash complie.sh
213-
# 执行
214-
./build/trt_run --model_file ppyoloe_s_quant/model.pdmodel --params_file ppyoloe_s_quant/model.pdiparams --run_mode=trt_int8
215-
```
243+
直接参考https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B/gpu/ppyoloe_crn_l
216244

217245
## 5.FAQ
218246

example/auto_compression/detection/paddle_inference_eval.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import sys
1919
import cv2
2020
import numpy as np
21+
from tqdm import tqdm
2122

2223
import paddle
2324
from paddle.inference import Config
@@ -82,9 +83,15 @@ def argsparser():
8283
parser.add_argument("--img_shape", type=int, default=640, help="input_size")
8384
parser.add_argument(
8485
'--include_nms',
85-
type=bool,
86-
default=True,
86+
type=str,
87+
default='True',
8788
help="Whether include nms or not.")
89+
parser.add_argument(
90+
"--trt_calib_mode",
91+
type=bool,
92+
default=False,
93+
help="If the model is produced by TRT offline quantitative "
94+
"calibration, trt_calib_mode need to set True.")
8895

8996
return parser
9097

@@ -208,8 +215,9 @@ def load_predictor(
208215
use_mkldnn=False,
209216
batch_size=1,
210217
device="CPU",
211-
min_subgraph_size=3,
218+
min_subgraph_size=4,
212219
use_dynamic_shape=False,
220+
trt_calib_mode=False,
213221
trt_min_shape=1,
214222
trt_max_shape=1280,
215223
trt_opt_shape=640,
@@ -238,9 +246,11 @@ def load_predictor(
238246
config = Config(
239247
os.path.join(model_dir, "model.pdmodel"),
240248
os.path.join(model_dir, "model.pdiparams"))
249+
250+
config.enable_memory_optim()
241251
if device == "GPU":
242252
# initial GPU memory(M), device ID
243-
config.enable_use_gpu(200, 0)
253+
config.enable_use_gpu(1000, 0)
244254
# optimize graph and fuse op
245255
config.switch_ir_optim(True)
246256
else:
@@ -260,12 +270,12 @@ def load_predictor(
260270
}
261271
if precision in precision_map.keys() and use_trt:
262272
config.enable_tensorrt_engine(
263-
workspace_size=(1 << 25) * batch_size,
273+
workspace_size=(1 << 30) * batch_size,
264274
max_batch_size=batch_size,
265275
min_subgraph_size=min_subgraph_size,
266276
precision_mode=precision_map[precision],
267277
use_static=True,
268-
use_calib_mode=False, )
278+
use_calib_mode=False)
269279

270280
if use_dynamic_shape:
271281
dynamic_shape_file = os.path.join(FLAGS.model_path,
@@ -297,6 +307,7 @@ def predict_image(predictor,
297307
img, scale_factor = image_preprocess(image_file, image_shape)
298308
inputs = {}
299309
inputs["image"] = img
310+
300311
if FLAGS.include_nms:
301312
inputs['scale_factor'] = scale_factor
302313
input_names = predictor.get_input_names()
@@ -356,7 +367,8 @@ def eval(predictor, val_loader, metric, rerun_flag=False):
356367
boxes_tensor = predictor.get_output_handle(output_names[0])
357368
if FLAGS.include_nms:
358369
boxes_num = predictor.get_output_handle(output_names[1])
359-
for batch_id, data in enumerate(val_loader):
370+
for batch_id, data in tqdm(
371+
enumerate(val_loader), total=len(val_loader), desc='Evaluating'):
360372
data_all = {k: np.array(v) for k, v in data.items()}
361373
for i, _ in enumerate(input_names):
362374
input_tensor = predictor.get_input_handle(input_names[i])
@@ -382,7 +394,6 @@ def eval(predictor, val_loader, metric, rerun_flag=False):
382394
res = {'bbox': np_boxes, 'bbox_num': np_boxes_num}
383395
metric.update(data_all, res)
384396
if batch_id % 100 == 0:
385-
print("Eval iter:", batch_id)
386397
sys.stdout.flush()
387398
metric.accumulate()
388399
metric.log()
@@ -421,7 +432,6 @@ def main():
421432
repeats=repeats)
422433
else:
423434
reader_cfg = load_config(FLAGS.reader_config)
424-
425435
dataset = reader_cfg["EvalDataset"]
426436
global val_loader
427437
val_loader = create("EvalReader")(
@@ -432,6 +442,7 @@ def main():
432442
anno_file = dataset.get_anno()
433443
metric = COCOMetric(
434444
anno_file=anno_file, clsid2catid=clsid2catid, IouType="bbox")
445+
435446
eval(predictor, val_loader, metric, rerun_flag=rerun_flag)
436447

437448
if rerun_flag:
@@ -444,8 +455,12 @@ def main():
444455
paddle.enable_static()
445456
parser = argsparser()
446457
FLAGS = parser.parse_args()
458+
if FLAGS.include_nms == 'True':
459+
FLAGS.include_nms = True
460+
else:
461+
FLAGS.include_nms = False
447462

448463
# DataLoader need run on cpu
449464
paddle.set_device("cpu")
450465

451-
main()
466+
main()

example/auto_compression/detection/post_process.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ def hard_nms(box_scores, iou_threshold, top_k=-1, candidate_size=200):
4141
rest_boxes = boxes[indexes, :]
4242
iou = iou_of(
4343
rest_boxes,
44-
np.expand_dims(
45-
current_box, axis=0), )
44+
np.expand_dims(current_box, axis=0), )
4645
indexes = indexes[iou <= iou_threshold]
4746

4847
return box_scores[picked, :]
@@ -122,7 +121,7 @@ def _non_max_suppression(self, prediction, scale_factor):
122121
picked_labels.extend([class_index] * box_probs.shape[0])
123122

124123
if len(picked_box_probs) == 0:
125-
out_boxes_list.append(np.empty((0, 4)))
124+
out_boxes_list.append(np.empty((0, 6)))
126125

127126
else:
128127
picked_box_probs = np.concatenate(picked_box_probs)
@@ -135,9 +134,8 @@ def _non_max_suppression(self, prediction, scale_factor):
135134
# clas score box
136135
out_box = np.concatenate(
137136
[
138-
np.expand_dims(
139-
np.array(picked_labels), axis=-1), np.expand_dims(
140-
picked_box_probs[:, 4], axis=-1),
137+
np.expand_dims(np.array(picked_labels), axis=-1),
138+
np.expand_dims(picked_box_probs[:, 4], axis=-1),
141139
picked_box_probs[:, :4]
142140
],
143141
axis=1)
@@ -152,6 +150,6 @@ def _non_max_suppression(self, prediction, scale_factor):
152150
return out_boxes_list, box_num_list
153151

154152
def __call__(self, outs, scale_factor):
155-
out_boxes_list, box_num_list = self._non_max_suppression(outs,
156-
scale_factor)
153+
out_boxes_list, box_num_list = self._non_max_suppression(
154+
outs, scale_factor)
157155
return {'bbox': out_boxes_list, 'bbox_num': box_num_list}

example/post_training_quantization/pytorch_yolo_series/README.md

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ python eval.py --config_path=./configs/yolov5s_ptq.yaml
122122
#### 3.6 提高离线量化精度
123123

124124
###### 3.6.1 量化分析工具
125-
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisPTQ```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。```paddleslim.quant.AnalysisPTQ```详解见[AnalysisPTQ.md](../../../docs/zh_cn/tutorials/quant/AnalysisPTQ.md)
125+
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。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)
126126

127127

128128
由于YOLOv6离线量化效果较差,以YOLOv6为例,量化分析工具具体使用方法如下:
@@ -207,7 +207,70 @@ python fine_tune.py --config_path=./configs/yolov6s_fine_tune.yaml --simulate_ac
207207

208208
## 4.预测部署
209209
预测部署可参考[YOLO系列模型自动压缩示例](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/example/auto_compression/pytorch_yolo_series)
210-
211-
210+
量化模型在GPU上可以使用TensorRT进行加速,在CPU上可以使用MKLDNN进行加速。
211+
| 参数名 | 含义 |
212+
| model_path | inference模型文件所在路径,该目录下需要有文件model.pdmodel和params.pdiparams两个文件 |
213+
| dataset_dir | 指定COCO数据集的目录,这是存储数据集的根目录 |
214+
| image_file | 如果只测试单张图片效果,直接根据image_file指定图片路径 |
215+
| val_image_dir | COCO数据集中验证图像的目录名,默认为val2017 |
216+
| val_anno_path | 指定COCO数据集的注释(annotation)文件路径,这是包含验证集标注信息的JSON文件,默认为annotations/instances_val2017.json |
217+
| benchmark | 指定是否运行性能基准测试。如果设置为True,程序将会进行性能测试 |
218+
| device | 使用GPU或者CPU预测,可选CPU/GPU/XPU,默认设置为GPU |
219+
| use_trt | 是否使用TensorRT进行预测|
220+
| use_mkldnn | 是否使用MKL-DNN加速库,注意use_mkldnn与use_gpu同时为True时,将忽略enable_mkldnn,而使用GPU预测|
221+
| use_dynamic_shape | 是否使用动态形状(dynamic_shape)功能 |
222+
| precision | fp32/fp16/int8|
223+
| arch | 指定所使用的模型架构的名称,例如YOLOv5 |
224+
| img_shape | 指定模型输入的图像尺寸 |
225+
| batch_size | 指定模型输入的批处理大小 |
226+
| use_mkldnn | 指定是否使用MKLDNN加速(主要针对CPU)|
227+
| cpu_threads | 指定在CPU上使用的线程数 |
228+
229+
首先,我们拥有的yolov6.onnx,我们需要把ONNX模型转成paddle模型,具体参考使用[X2Paddle迁移推理模型](https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/model_convert/convert_with_x2paddle_cn.html#x2paddle)
230+
- 安装X2Paddle
231+
方式一:pip 安装
232+
```shell
233+
pip install X2Paddle==1.3.9
234+
```
235+
方式二:源码安装
236+
```shell
237+
git clone https://github.com/PaddlePaddle/X2Paddle.git
238+
cd X2Paddle
239+
python setup.py install
240+
```
241+
使用命令将YOLOv6.onnx模型转换成paddle模型
242+
```shell
243+
x2paddle --framework=onnx --model=yolov6s.onnx --save_dir=yolov6_model
244+
```
245+
- TensorRT Python部署
246+
使用[paddle_inference_eval.py](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/example/auto_compression/pytorch_yolo_series/paddle_inference_eval.py)部署
247+
```shell
248+
python paddle_inference_eval.py --model_path=yolov6_model/inference_model --dataset_dir=datasets/coco --use_trt=True --precision=fp32 --arch=YOLOv6
249+
```
250+
执行int8量化
251+
```shell
252+
python paddle_inference_eval.py --model_path=yolov6s_ptq_out --dataset_dir==datasets/coco --use_trt=True --precision=int8 --arch=YOLOv6
253+
```
254+
- C++部署
255+
具体可参考[运行PP-YOLOE-l目标检测模型样例](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B/gpu/ppyoloe_crn_l)
256+
将compile.sh中DEMO_NAME修改为yolov6_test,并且将ppyoloe_crn_l.cc修改为yolov6_test.cc,根据环境修改相关配置库
257+
运行bash compile.sh编译样例。
258+
- 运行样例
259+
-使用原生GPU运行样例(将ONNX模型转成的paddle模型复制到Paddle-Inference-demo/c++/gpu/ppyoloe_crn_l/目录下)
260+
```shell
261+
./build/yolov6_test --model_file yolov6s_infer/model.pdmodel --params_file yolov6s_infer/model.pdiparams
262+
```
263+
- 使用TensorRT FP32运行样例
264+
```shell
265+
./build/yolov6_test --model_file yolov6s_infer/model.pdmodel --params_file yolov6s_infer/model.pdiparams --run_mode=trt_fp32
266+
```
267+
- 使用TensorRT FP16运行样例
268+
```shell
269+
./build/yolov6_test --model_file yolov6s_infer/model.pdmodel --params_file yolov6s_infer/model.pdiparams --run_mode=trt_fp16
270+
```
271+
- 使用TensorRT INT8运行样例
272+
```shell
273+
./build/yolov6_test --model_file yolov6s_infer/model.pdmodel --params_file yolov6s_infer/model.pdiparams --run_mode=trt_int8
274+
```
212275
## 5.FAQ
213276
- 如果想对模型进行自动压缩,可进入[YOLO系列模型自动压缩示例](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/example/auto_compression/pytorch_yolo_series)中进行实验。

0 commit comments

Comments
 (0)