前言
在J6工具链的量化精度调优实践中,当 Matmul/Conv 算子的两个输入皆为量化敏感算子时,PTQ 与 QAT 各自面临着难以克服的棘手困境。
在 PTQ 流程里,为了实现双 int16 输入的支持,工作人员不得不借助脚本将原本结构单一的 Matmul/Conv 算子拆解为 2 个 conv + add 算子,随后还要围绕这两个新算子进行一系列复杂且细致的量化配置。这一过程不仅涉及到 onnx 模型的修改,更需要投入人力成本进行反复的测试和验证,操作较为繁琐。
反观 QAT,由于受到技术实现方面的限制,在面对同样的情况时,仅能将其中更为敏感的一个输入配置为 int16,而另一个输入仍只能维持 int8 计算。这种妥协的做法导致在部分对精度要求较高的复杂场景下,模型的精度难以达到预期要求,成为制约模型性能进一步提升的瓶颈,使得许多具有潜在应用价值的模型因为精度问题而无法在实际生产中得到有效应用。
然而,新功能的引入也带来了新的问题和挑战:当因 Gemm 类算子引发精度问题时,PTQ 和 QAT 应如何精准定位问题算子,并进行合理的双 int16 配置呢?
这正是本文即将深入探讨的核心内容。我们将详细剖析 PTQ 和 QAT 链路下双 int16 配置的完整流程,包括如何利用精度 debug 工具准确识别出需要配置为双 int16 的敏感算子,以及在 yaml 文件或代码中进行具体配置的实操步骤和注意事项。通过这些内容的讲解,助力读者在实际工作中能够高效、准确地运用这一强大功能,突破量化精度调优过程中的技术壁垒,让模型在保证高效运行的同时,也能达到理想的精度水平。
PTQ
定位需要配置为双int16的算子
一般来说,当全int8量化精度满足不了需求后,我们才会考虑配置int16,那么在什么场景下我们需要配置双int16呢?
- 运行精度debug工具的hmct-debugger get-sensitivity-of-nodes -n 'activation'和hmct-debugger get-sensitivity-of-nodes -n 'weight'后,某个conv算子的敏感度均居于前列;
同理,运行精度debug后,Matmul算子的两个输入敏感度都居于前列。
工具链用户手册上有非常完整的精度debug工具使用流程,如下所示:

PTQ双int16配置示例
确定两个输入都敏感的Matmul/Conv算子后,我们需要在yaml中对其做双int16的精度配置,配置示例如下:
ec全称为error compensate, 是一种通过创建相同算子来补偿特定算子int8量化精度损失的方案。当前仅支持如下算子, 其他算子配置不生效。
Conv和ConvTranspose算子的权重输入(通过node_config的三级参数input1指定)。
MatMul算子的任一输入(通过node_config的三级参数input0或input1指定)。
GridSample和Resize算子的第0个输入(通过node_config的三级参数input0指定)。
QAT
定位需要配置为双int16的算子
与PTQ类似,需要先使用精度debug工具获得敏感度列表,当conv/linear算子的activation和weight都处于敏感度列表前列时,则考虑将此算子配置为双iint16,Matmul算子则需要其两个输入节点都处于敏感度前列。
QAT精度debug工具使用教程可以参考工具链手册如下章节:

QAT精度debug工具的敏感度列表如下所示:

QAT双int16配置示例
根据上图的敏感度列表,我们可以看出backbone.res_layers.2.blocks.4.branch2c.conv 是weight敏感的算子,下面我们就以这个算子为例进行双int16的配置,如下所示:
linear算子的双int16输入配置和conv相同,为了保证linear/conv的激活输入是int16,建议直接配置上层算子的输出为int16.
Matmul的双int16输入配置和conv有所不同,这里举例说明。比如存在两个输入都敏感的matmul算子matmul_id_0,其两个输入的算子名称分别是matmul_id_0_input0和matmul_id_0_input1,那么此算子的双int16配置为:
这里有3点特别需要注意:
必须要配置QconfigCanonicalizer.set_fallback_strategy_version(FallbackStrategyVersion.V2),从而支持gemm的双int16;
在配置双int16时,hbdk4-compiler版本至少需要是4.3.3,即OE3.2.0集成的正式对外版本;
在将conv/matmul/linear的输入配置为双int16后,其输出暂不支持再配置为int32高精度输出。
