专栏算法工具链PTQ精度调优手段—设置Int16量化

PTQ精度调优手段—设置Int16量化

芯链情报局2023-07-04
367
0

前言:

在我们进行模型后量化的过程中,往往会面临在模型性能和模型精度之间权衡的问题。具体来说,我们希望模型的全部或者绝大多数算子运行在BPU上,以Int8的精度量化,从而使模型在板端部署时有着更快的推理速度,有着更好的性能(例如较低的Latency和较高的FPS)。但是对于少数的模型,可能存在部分节点的数据分布范围较大,使用全Int8量化可能存在较大的精度风险。而解决这一权衡问题的思路也很直观,我们可以将对Int8量化敏感的算子退而求其次,使用更高的量化精度进行量化,例如使用Int16精度量化,此举可以有效地减少算子在量化时累积较多的量化误差。然而使用更高的量化精度量化算子必然会带来模型的性能损失,这就需要我们合理地选择需要进行Int16量化的算子。

那么该如何合理地选择Int16量化的算子以达到模型性能和模型精度的平衡呢?具体做法是依据后量化模型转换过程中给出的余弦相似度Cosine Similarity和其他指标如MSE,对Int8量化敏感的算子进行排序,将Int8量化误差大的算子采用Int16量化,在此过程中不断评测中间模型的性能和精度,直至达到平衡。而对于”平衡“这一概念则取决于开发者,即是愿意牺牲模型一定的性能去换取高精度还是愿意牺牲模型一定的精度去换取高性能。

值得注意的是,只有J5工具链支持PTQ设置Int16量化的功能,接下来本文将介绍如何在PTQ过程中设置部分节点为Int16量化来进行模型的精度调优。

一、选取Int16量化节点

首先,对于Int8量化风险较大的模型,对其后量化过程进行精度Debug分析,量化后余弦相似度Cosine Similarity较低或MSE较高的节点为Int8量化敏感节点,也就是我们要选取的Int16量化节点。详细的PTQ Debug工具使用方法和结果分析方法可以参考社区文章PTQ精度Debug工具或者查看用户手册用户手册—PTQ精度Debug工具

此外我们还提供了3个使用示例帮助您快速上手这个工具,可以查看如下社区文章:

二、开启Int16量化功能

本文针对OpenExplorer V1.1.49b及其之后版本的工具链开发包讲解如何开启Int16量化功能。相关版本的获取途径为OE开发包获取

Int16量化功能通过配置模型转换YAML文件中的参数开启,功能包括:模型尾部节点输出Int16和单个节点输入输出Int16,以及同类型节点输入输出Int16(仅在OpenExplorer V1.1.62及其之后版本支持)。如遇到部分节点的算子不支持Int16量化,将自动退回Int8量化,无需用户额外操作。在此建议用户升级使用最新版本的OpenExplorer开发包以获得更多的算子支持,最新支持配置Int16的算子范围可参考算子支持约束列表

1、配置模型尾部节点输出Int16

支持配置YAML文件中校准参数组的参数optimization,使模型尾部节点以Int16精度输出,如下:

配置完成后可以在输出的“hb_mapper_makertbin.log”文件中验证查看,如下,红框标示的内容表示:输入该节点的数据类型/输出该节点的数据类型。

2、配置单个节点输入输出Int16

支持配置单个节点的输入或者输出采用Int16量化,其中NodeName表示节点名称,多输入的节点支持指定单个输入采用Int16量化(InputType0表示第1个输入,依次类推),多输出的节点不支持指定单个输出的精度,如下:

这里涉及判断输入的次序,方法为在Netron可视化下点开对应节点,在INPUTS栏从上往下数,分别为InputType0、InputType1、......。如下所示:

多输入节点输入顺序多输入节点输入顺序
配置完成后也可以通过Netron可视化查看model_output路径下生成的calibrated_model和quantized_model来验证配置是否成功:
  • calibrated_model
    配置“Conv_41”节点输出为Int16前:

    配置“Conv_41”节点输出为Int16后:
  • quantized_model
    配置“Conv_41”节点输出为Int16前:

    配置“Conv_41”节点输出为Int16后:

3、配置同类型节点输入输出Int16

此功能仅在OpenExplorer V1.1.62及其之后版本支持。

配置YAML文件中校准参数组的参数optimization,指定模型中同类型节点以Int16量化精度输入输出,其中NodeKind为标准ONNX算子类型,写法如Conv、Mul、Sigmoid等(区分大小写),具体请参考ONNX官方OP文档或算子支持约束列表。配置如下:

配置完成后可以在输出的“hb_mapper_makertbin.log”文件中验证查看,配置Conv类型节点输入输出Int16量化前:

配置Conv类型节点输入输出Int16量化后:

三、精度和性能的权衡

如前言部分提到的那样,相比于Int8量化,设置Int16量化能够调优模型精度,但是不可避免地会牺牲模型的性能,体现在FPS的下降。以MobileNetV2在bayes架构下采用O3编译,horizon-nn==0.19.3为例,量化精度损失 = (原浮点模型精度 - 量化后的定点模型精度) / 原浮点模型精度:

量化方式

FPS

量化精度损失

Int8

单核:1791.62

1.18%

部分Int16

单核:1674.85

0.87%

模型做部分Int16的配置如下:

上述配置仅作为示例,用户可以自己尝试不同的配置来体会Int16量化对模型精度和性能的影响。在实际开发中,需要用户结合第一部分提及的精度Debug工具合理地选择需要进行Int16量化的节点,以达到模型精度和性能的平衡。

总结

通过本文的讲解,相信读者对于如何在后量化中开启Int16量化功能以及Int16量化对于模型性能和精度上的影响有了较为清晰的认识。在实际操作中,还需结合精度Debug工具给出的算子量化余弦相似度等相关信息,以达到合理选择Int16算子的目的,从而能使模型在后量化中取得性能和精度的平衡。

算法工具链
杂谈
评论0
0/1000