专栏算法工具链深度学习模型优化技巧:Conv 算子拆分原理与实现

深度学习模型优化技巧:Conv 算子拆分原理与实现

Huanghui2025-08-28
214
0

写在前面:

在 PTQ量化模型的过程中,往往存在一些敏感节点,如Conv算子,matmul算子等,我们通常倾向于将其设定为高精度的int16输入。但由于硬件原因限制,即使指定Conv算子的精度为int16,但实际指定结果是只有其中一个以int16精度输入,另一个仍然是int8,例如激活是int16.而权重weight是int8.如下图所示:

其中激活的量化数据类型是int16,而权重的量化数据类型是int8,明明我们是设置的all_node_type=int16,为什么还是会出现int8类型数据呢,这在前面我们也已经说过了,主要由于硬件原因限制,为此,

一种解决思路是:
将卷积权重拆分为两部分(高权重+低权重)分别构造两个卷积算子,再通过加法融合,得到与原始卷积等价的结果。

这样既能减少单个算子的量化误差,又能保持整体计算图的正确性。

代码实现:

原理解析:

拆分逻辑的关键步骤:

  1. 权重最大值归一化
    每个卷积通道独立找到最大绝对值,计算 scale 因子 moded。
  2. 权重拆分

    • conv_weight_high:通过量化公式约束在 [-127, 127] 范围内的部分,相当于主分量。
    • conv_weight_low:残差部分,补偿量化损失。

    这样就避免了单次量化对所有权重“一刀切”的问题。

  3. 双卷积 + Add 融合

    • 第一个卷积算子处理主要信息(high)。

    • 第二个卷积算子处理残差(low)。

    • Add 节点融合两个结果,恢复接近原始 Conv 的精度。

  4. 好处

    • 双卷积结果相加可以近似还原原始高精度双int16卷积。

    • 误差相比单 Conv 量化更小。

使用方法:

定义好上面的split函数之后,可以参考如下代码在下面主函数调用:

可以看到需要定义需要拆分的原始模型和算子列表,需要注意被拆分的原始模型需要选择ptq输出目录下的optimized的模型,至于敏感算子的信息可通过精度debug工具的get_sensitivity_of_node获取( debug工具的使用可自行查看用户手册,这里不赘述)。算子拆分后会生成新的onnx模型,可以将之作为ptq流程的原始模型进行输入,再次校准转化查看拆分效果。

总结:

这段实现展示了一种Conv算子拆分技巧模拟双int16输入:

  • 通过High+Low的方式拆分权重,构建两个卷积节点;

  • 最终用 Add 节点融合输出,替代原始卷积;

  • 有效降低了量化误差,提升模型在低精度推理下的表现。

 

算法工具链
技术深度解析征程6官方教程
评论0
0/1000