未验证 提交 18d3524a 编写于 作者: C Chang Xu 提交者: GitHub

Update Quant Analysis (#1463)

上级 12ec1002
# 量化分析工具详细教程
## 1. 量化分析工具功能
1. 遍历模型所有层,依次量化该层,计算量化后精度。为所有只量化一层的模型精度排序,可视化不适合量化的层,以供量化时可选择性跳过不适合量化的层。
2. 可视化激活箱状图,以供分析每个可量化OP的激活分布对量化效果的影响。
3. 量化效果较好和较差的层的权重和激活直方分布图,以供分析其对量化效果的影响。
4. 输入预期精度,直接产出符合预期精度的量化模型。
1. statistical_analyse:
- 可视化激活和权重箱状图。箱状图可发现是否出现离群点。
- 可视化权重和激活直方分布图。直方分布图可观察更具体的数值分布。
- 提供量化前后权重和激活的具体数据信息,包括min,max,mean,std等
2. metric_error_analyse:
- 遍历量化模型的每层,并计算量化后精度。该功能可以定位具体某层导致的量化损失。
3. get_target_quant_model:
- 输入预期精度,直接产出符合预期精度的量化模型。
## 2. paddleslim.quant.AnalysisQuant 可传入参数解析
```yaml
......@@ -14,25 +21,23 @@ params_filename: None
eval_function: None
data_loader: None
save_dir: 'analysis_results'
checkpoint_name: 'analysis_checkpoint.pkl'
num_histogram_plots: 10
resume: False
ptq_config
```
- model_dir: 必须传入的模型文件路径,可为文件夹名;若模型为ONNX类型,直接输入'.onnx'模型文件名称即可。
- model_filename: 默认为None,若model_dir为文件夹名,则必须传入以'.pdmodel'结尾的模型名称,若model_dir为'.onnx'模型文件名称,则不需要传入。
- params_filename: 默认为None,若model_dir为文件夹名,则必须传入以'.pdiparams'结尾的模型名称,若model_dir为'.onnx'模型文件名称,则不需要传入。
- eval_function:目前不支持为None,需要传入自定义的验证函数。
- eval_function:若需要验证精度,需要传入自定义的验证函数。
- data_loader:模型校准时使用的数据,DataLoader继承自`paddle.io.DataLoader`。可以直接使用模型套件中的DataLoader,或者根据[paddle.io.DataLoader](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/io/DataLoader_cn.html#dataloader)自定义所需要的DataLoader。
- save_dir:分析后保存模型精度或pdf等文件的文件夹,默认为`analysis_results`
- checkpoint_name:由于模型可能存在大量层需要分析,因此分析过程中会中间保存结果,如果程序中断会自动加载已经分析好的结果,默认为`analysis_checkpoint.pkl`
- num_histogram_plots:需要可视化的直方分布图数量。可视化量化效果最好和最坏的该数量个权重和激活的分布图。默认为10。若不需要可视化直方图,设置为0即可。
- resume:是否加载中间分析文件
- ptq_config:可传入的离线量化中的参数,详细可参考[离线量化文档](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/demo/quant/quant_post)
## 3. 量化分析工具的使用
1. 创建量化分析工具
**创建量化分析工具**
```
analyzer = AnalysisQuant(
model_dir=config["model_dir"],
......@@ -44,45 +49,47 @@ analyzer = AnalysisQuant(
ptq_config=config['PTQ'])
```
2. 绘制所有可量化层的激活箱状图
**统计分析**
```
analyzer.plot_activation_distribution()
analyzer.statistical_analyse()
```
以检测模型中的picodet-s为例,从以下激活箱状图(部分层)中可以发现,`conv2d_7.w_0``conv2d_9.w_0` 这两层的激活输入有大量离群点,会导致量化效果较差。
<p align="center">
<img src="./detection/images/act_distribution.png" width=849 hspace='10'/> <br />
</p>
3. 计算每层的量化敏感度并且绘制直方分布图
调用该接口,会统计量化前和量化后每一个可量化权重和其对应激活的数据。只使用该接口可以不输入Eval Function,但需要输入DataLoader,少量数据即可。会产出以下文件:
- `fp_activation_boxplot.pdf`:量化前Float数据类型的模型激活箱状图
- `fp_weight_boxplot.pdf`:量化前Float数据类型的模型权重箱状图
- `quantized_activation_boxplot.pdf`:量化后INT数据类型的模型激活箱状图
- `quantized_weight_boxplot.pdf`:量化后INT数据类型的模型权重箱状图
- `fp_activation_histplot.pdf`:量化前Float数据类型的模型激活直方图
- `fp_weight_histplot.pdf`:量化前Float数据类型的模型权重直方图
- `quantized_activation_histplot.pdf`:量化后INT数据类型的模型激活直方图
- `quantized_weight_histplot.pdf`:量化后INT数据类型的模型权重直方图
- `statistic.csv`:量化前后权重和激活的具体数据信息,表格中会保存的信息有:
- Var Name: Variable的名称
- Var Type:Variable的类型,Weight或Activation
- Corresponding Weight Name:如果为Activation,其对应的Weight名称
- FP32 Min:量化前Float数据类型的最小值
- FP32 Max:量化前Float数据类型的最大值
- FP32 Mean:量化前Float数据类型的平均值
- FP32 Std:量化前Float数据类型的方差值
- Quantized Min:量化后INT数据类型的最小值
- Quantized Max:量化后INT数据类型的最大值
- Quantized Mean:量化后INT数据类型的平均值
- Quantized Std:量化后INT数据类型的方差值
- Diff Min:量化前后该Variable的相差的最小值
- Diff Max:量化前后该Variable的相差的最大值
- Diff Mean:量化前后该Variable的相差的平均值
- Diff Std:量化前后该Variable的相差的方差值
**精度误差分析**
```
analyzer.compute_quant_sensitivity(plot_hist=True)
analyzer.metric_error_analyse()
```
`plot_hist` 默认为True,如不需要获得量化效果较好和较差的层的权重和激活分布图,可设置为False。
量化分析工具会默认会产出以下目录:
```
analysis_results/
├── analysis.txt
├── best_weight_hist_result.pdf
├── best_act_hist_result.pdf
├── worst_weight_hist_result.pdf
├── worst_act_hist_result.pdf
```
- 所有只量化一层的模型精度排序,将默认保存在 `./analysis_results/analysis.txt` 中。
- 通过设置参数`num_histogram_plots`,可选择绘出该数量个量化效果最好和最差层的weight和activation的直方分布图,将以PDF形式保存在 `./analysis_results` 文件夹下, 分别保存为 `best_weight_hist_result.pdf``best_act_hist_result.pdf``worst_weight_hist_result.pdf``worst_act_hist_result.pdf` 中以供对比分析。
调用该接口,会遍历量化模型中的一层,并计算量化该层后模型的损失。调用该接口时,需要输入Eval Function。会产出所有只量化一层的模型精度排序,将默认保存在 `./analysis_results/analysis.txt` 中。
以检测模型中的picodet-s为例,从`analysis.txt`可以发现`conv2d_1.w_0``conv2d_3.w_0``conv2d_5.w_0``conv2d_7.w_0``conv2d_9.w_0` 这些层会导致较大的精度损失。这一现象符合对激活箱状图的观察。
<p align="center">
<img src="./detection/images/picodet_analysis.png" width=849 hspace='10'/> <br />
</p>
4. 直接产出符合预期精度的量化模型
**直接产出符合预期精度的量化模型**
```
analyzer.get_target_quant_model(target_metric)
```
......
......@@ -130,7 +130,8 @@ python eval.py --config_path=./configs/ppyoloe_s_ptq.yaml
- 要测试的模型路径可以在配置文件中`model_dir`字段下进行修改。
#### 3.6 提高离线量化精度
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisQuant```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisQuant```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。```paddleslim.quant.AnalysisQuant```详解见[AnalysisQuant.md](../../../../docs/zh_cn/tutorials/quant/AnalysisQuant.md)
经过多个实验,包括尝试多种激活算法(avg,KL等)、weight的量化方式(abs_max,channel_wise_abs_max),对PicoDet-s进行离线量化后精度均为0,以PicoDet-s为例,量化分析工具具体使用方法如下:
......
......@@ -168,14 +168,11 @@ def main():
eval_function=eval_function,
data_loader=ptq_data_loader,
save_dir=config['save_dir'],
ptq_config=ptq_config)
ptq_config=ptq_config,
resume=True, )
# plot the boxplot of activations of quantizable weights
analyzer.plot_activation_distribution()
# get the rank of sensitivity of each quantized layer
# plot the histogram plot of best and worst activations and weights if plot_hist is True
analyzer.compute_quant_sensitivity(plot_hist=config['plot_hist'])
analyzer.statistical_analyse()
analyzer.metric_error_analyse()
if config['get_target_quant_model']:
if 'FastEvalDataset' in config:
......
......@@ -116,7 +116,7 @@ python eval.py --config_path=./configs/yolov5s_ptq.yaml
#### 3.6 提高离线量化精度
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisQuant```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。
本节介绍如何使用量化分析工具提升离线量化精度。离线量化功能仅需使用少量数据,且使用简单、能快速得到量化模型,但往往会造成较大的精度损失。PaddleSlim提供量化分析工具,会使用接口```paddleslim.quant.AnalysisQuant```,可视化展示出不适合量化的层,通过跳过这些层,提高离线量化模型精度。```paddleslim.quant.AnalysisQuant```详解见[AnalysisQuant.md](../../../../docs/zh_cn/tutorials/quant/AnalysisQuant.md)
由于YOLOv6离线量化效果较差,以YOLOv6为例,量化分析工具具体使用方法如下:
......@@ -148,6 +148,8 @@ python post_quant.py --config_path=./configs/yolov6s_analyzed_ptq.yaml --save_di
如想分析之后直接产出符合目标精度的量化模型,可在 `yolov6s_analysis.yaml` 中将`get_target_quant_model`设置为True,并填写 `target_metric`,注意 `target_metric` 不能比原模型精度高。
**加速分析过程**
使用量化分析工具时,因需要逐层量化模型并进行验证,因此过程可能较慢,若想加速分析过程,可以在配置文件中设置 `fast_val_anno_path` ,输入一个图片数量较少的annotation文件路径。注意,用少量数据验证的模型精度不一定等于全量数据验证的模型精度,若只需分析时获得不同层量化效果的相对排序,可以使用少量数据集;若要求准确精度,请使用全量验证数据集。如需要全量验证数据,将 `fast_val_anno_path` 设置为None即可。
......
......@@ -113,12 +113,8 @@ def main():
resume=FLAGS.resume,
ptq_config=ptq_config)
# plot the boxplot of activations of quantizable weights
analyzer.plot_activation_distribution()
# get the rank of sensitivity of each quantized layer
# plot the histogram plot of best and worst activations and weights if plot_hist is True
analyzer.compute_quant_sensitivity(plot_hist=config['plot_hist'])
analyzer.statistical_analyse()
analyzer.metric_error_analyse()
if config['get_target_quant_model']:
if config['fast_val_anno_path'] is not None:
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册