# 目标检测模型全量化示例

目录：
- [1.简介](#1简介)
- [2.Benchmark](#2Benchmark)
- [3.开始全量化](#全量化流程)
  - [3.1 环境准备](#31-准备环境)
  - [3.2 准备数据集](#32-准备数据集)
  - [3.3 准备预测模型](#33-准备预测模型)
  - [3.4 测试模型精度](#34-测试模型精度)
  - [3.5 全量化并产出模型](#35-全量化并产出模型)
- [4.预测部署](#4预测部署)
- [5.FAQ](5FAQ)

## 1. 简介
本示例将以目标检测模型PicoDet为例，介绍如何使用PaddleDetection中Inference部署模型进行全量化。本示例使用的全量化策略为全量化加蒸馏。


## 2.Benchmark

### PicoDet-S-NPU

| 模型  | 策略 | mAP | TRT-FP32 | TRT-FP16 | TRT-INT8 |  配置文件 | 模型  |
| :-------- |:-------- |:--------: | :----------------: | :----------------: | :---------------: | :----------------------: | :---------------------: |
| PicoDet-S-NPU | Baseline | 30.1   |   -   |  -  |  -  | [config](https://github.com/PaddlePaddle/PaddleDetection/tree/develop/configs/picodet/picodet_s_416_coco_npu.yml) | [带后处理](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_416_coco_npu.tar) &#124; [不带后处理](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_416_coco_npu_no_postprocess.tar) |
| PicoDet-S-NPU |  量化训练 | 29.7  |   -  |   -   |  -  |  [config](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/example/full_quantization/picodet/configs/picodet_npu_with_postprocess.yaml) | [Model](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_npu_quant.tar) |

- mAP的指标均在COCO val2017数据集中评测得到，IoU=0.5:0.95。

## 3. 全量化流程

#### 3.1 准备环境
- PaddlePaddle >= 2.4 （可从[Paddle官网](https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/pip/linux-pip.html)下载安装）
- PaddleSlim >= 2.4
- PaddleDet >= 2.4
- opencv-python

安装paddlepaddle：
```shell
# CPU
pip install paddlepaddle
# GPU
pip install paddlepaddle-gpu
```

安装paddleslim：
```shell
pip install paddleslim
```

安装paddledet：
```shell
pip install paddledet
```
注：安装PaddleDet的目的是为了直接使用PaddleDetection中的Dataloader组件。


#### 3.2 准备数据集

本案例默认以COCO数据进行全量化实验，如果自定义COCO数据，或者其他格式数据，请参考[PaddleDetection数据准备文档](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/docs/tutorials/PrepareDataSet.md) 来准备数据。

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

以PicoDet-S-NPU模型为例，如果已经准备好数据集，请直接修改[./configs/picodet_reader.yml]中`EvalDataset`的`dataset_dir`字段为自己数据集路径即可。

#### 3.3 准备预测模型

预测模型的格式为：`model.pdmodel` 和 `model.pdiparams`两个，带`pdmodel`的是模型文件，带`pdiparams`后缀的是权重文件。

根据[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模型，具体可参考下方PicoDet-S-NPU模型的导出示例：
- 下载代码
```
git clone https://github.com/PaddlePaddle/PaddleDetection.git
```
- 导出预测模型

PicoDet-S-NPU模型，包含后处理：如快速体验，可直接下载[PicoDet-S-NPU带后处理导出模型](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_416_coco_npu.tar)
```shell
python tools/export_model.py \
        -c configs/picodet/picodet_s_416_coco_npu.yml \
        -o weights=https://paddledet.bj.bcebos.com/models/picodet_s_416_coco_npu.pdparams \
```

导出PicoDet-S-NPU不带后处理模型：（也可直接下载[PicoDet-S-NPU不带后处理导出模型](https://bj.bcebos.com/v1/paddle-slim-models/act/picodet_s_416_coco_npu_no_postprocess.tar)）
```shell
python tools/export_model.py \
        -c configs/picodet/picodet_s_416_coco_npu.yml \
        -o weights=https://paddledet.bj.bcebos.com/models/picodet_s_416_coco_npu.pdparams \
        export.benchmark=True
```

#### 3.4 全量化并产出模型

##### 自动化压缩

全量化示例通过run.py脚本启动，会使用接口```paddleslim.auto_compression.AutoCompression```对模型进行全量化。配置config文件中模型路径、蒸馏、量化、和训练等部分的参数，配置完成后便可对模型进行量化和蒸馏。具体运行命令为：

- 单卡训练：
```
export CUDA_VISIBLE_DEVICES=0
python run.py --config_path=./configs/picodet_npu_with_postprocess.yaml --save_dir='./output/'
```

- 多卡训练：
```
CUDA_VISIBLE_DEVICES=0,1,2,3
python -m paddle.distributed.launch --log_dir=log --gpus 0,1,2,3 run.py \
          --config_path=./configs/picodet_npu_with_postprocess.yaml --save_dir='./output/'
```

- 不带后处理PicoDet模型训练：
```
export CUDA_VISIBLE_DEVICES=0
python run.py --config_path=./configs/picodet_npu.yaml --save_dir='./output/'
```

##### 离线量化

```
python post_quant.py --config_path=./configs/picodet_npu_with_postprocess.yaml --save_dir='./output/'
```

#### 3.5 测试模型精度

- 使用eval.py脚本得到模型的mAP：
```
export CUDA_VISIBLE_DEVICES=0
python eval.py --config_path=./configs/picodet_npu_with_postprocess.yaml
```

- 使用ONNXRuntime测试模型mAP：
如果要导出至ONNX部署，需要将自动化压缩配置文件中`Quantization`里设置：`onnx_format=True`。使用离线量化产出模型需要将配置文件中`PTQ`里设置：`onnx_format=True`。
导出ONNX模型：

```
paddle2onnx --model_dir=picodet_s_416_coco_npu/ \
            --model_filename=model.pdmodel \
            --params_filename=model.pdiparams \
            --save_file=picodet_s_416_coco_npu \
            --deploy_backend='onnxruntime'
```
测试精度：
```
python onnxruntime_eval.py \
        --reader_config=configs/picodet_reader.yml \
        --model_path=picodet_s_416_coco_npu.onnx
```

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

## 4.预测部署


## 5.FAQ
