前言:
本文接下来将在J5上使用YOLOv8x模型演示如何开启后量化的Int16量化功能,并展示使用Int16量化功能对模型性能和精度带来的影响。
环境与依赖:
获取最新的OpenExplorer工具链开发包
hbdk>=3.44.3
horizon-nn>=0.17.1
Int16量化功能开启前:
首先从初始开始,我们配置YOLOv8x模型转换的yaml文件,完成第一次转换编译后发现模型共有2个算子运行在CPU上,为“/model.22/dfl/Softmax”和“/model.22/Mul_2”。接着我们配置yaml文件中run_on_bpu参数将这2个算子强制运行在BPU上,此外calibration_type选择default,optimize_level设置为最高优化O3,上述部分配置如下:
转换成功后利用中间产物original_float_model和optimized_float_model对齐模型输入输出数据并检验前后处理的正确性,确保可以生成正确的可视化结果且两模型推理结果保持一致,例如下图(后处理中bbox置信度阈值和IoU阈值均设置为0.2且在之后都保持不变):
浮点模型推理结果接着我们测试calibrated_model和quantized_model,发现模型推理无可视化结果,如下:
定点模型推理结果此时评测模型在J5板端性能如下:
FPS | Latency/ms |
|---|---|
单核:38.154102/双核:74.087635 | 26.427231 |
此时的模型性能为最优,但精度最低,几乎为0。
开启Int16量化功能:
1、如何开启Int16量化功能
在模型转换yaml文件calibration_parameters参数组中增加optimization参数,例如:
即可使算子类型为Add的节点以Int16精度量化。同理,想要使其他类型算子的节点以Int16精度量化,修改上面示例的算子类型即可。值得注意的是,这里针对的是同类型算子的节点,而不是单个节点,针对单个节点的Int16量化暂未开放。
在模型转换过程中,如果有个别节点不支持Int16量化或者不支持Int16输入或输出,转换工具会使这些节点保留原Int8精度量化。
2、全类型Int16量化
为了更加直观地体现Int16量化对模型性能的影响,这里探索一种极端的情况,即把模型所有支持Int16量化的算子全部采用Int16量化,optimization参数配置如下:
修改后重新进行模型转换,使用生成的calibrated_model和quantized_model进行推理,成功生成了可视化结果,如下:
Int16量化后的定点模型推理结果此时模型的精度最优,定点模型精度为:[IoU=0.50:0.95]=0.431;[IoU=0.50]=0.636。那么它的性能又会怎么样呢,在板端实测的模型性能对比如下:
性能指标 | FPS | Latency/ms |
|---|---|---|
开启Int16量化前 | 单核:38.154102/双核:74.087635 | 26.427231 |
全类型Int16量化 | 单核:11.419144/双核:21.690922 | 88.851227 |
开启全类型Int16量化后相比开启前,单核FPS降低了70.07%,双核FPS降低了70.72%,时延Latency增长了236.21%!!!但是别灰心,开启全类型Int16量化后的模型是性能最差的情况,我们可以关闭一些Int16量化的节点,牺牲一定的精度来换取性能的提升。
3、部分类型Int16量化
calibrated_model因此有必要将HzSwish节点做Int16量化以减少量化误差。此外发现部分Mul节点Int8量化的MSE较高,因此也可以做Int16量化(考虑到Conv节点做Int16量化可能会造成较大的性能损失,故先从Mul节点开始尝试),如下:
节点量化敏感度信息当然同学们也可以尝试将其他节点做Int16量化,来体会Int16量化对模型性能和精度的影响。按照本文的设置,yaml文件中optimization参数配置如下:
对量化后的定点模型做精度的评测,和全类型Int16量化对比,结果如下:
量化类型 | 定点模型精度 |
|---|---|
全类型Int16量化 | [IoU=0.50:0.95] = 0.431/[IoU=0.50] = 0.636 |
部分类型Int16量化 | [IoU=0.50:0.95] = 0.384/[IoU=0.50] = 0.593 |
模型精度最多降低了10.9%,在预料之中,但是我们获得的性能增长呢,见下表:
性能指标 | FPS | Latency/ms |
|---|---|---|
开启Int16量化前 | 单核:38.154102/双核:74.087635 | 26.427231 |
部分类型Int16量化 | 单核:34.162637/双核:66.035364 | 29.559324 |
全类型Int16量化 | 单核:11.419144/双核:21.690922 | 88.851227 |
可见相比于开启全类型的Int16量化,调整之后的部分类型Int16量化牺牲了较少的精度而获得了性能上巨大的提升!!!
总结:
通过本文的演示,相信读者对于如何在后量化中开启Int16量化功能以及Int16量化对于模型性能和精度上的影响有了较为清晰的认识。在实际操作中,还需结合地平线工具链给出的算子量化相似度相关信息,以达到合理选择Int16算子的目的,从而能使模型在后量化中取得性能和精度的平衡。



