Qconfig配置

QConfig 的定义

qconfig(Quantization Configuration)指的是量化配置,是深度学习模型量化过程中的关键参数集合,模型的量化方式由 qconfig 决定,在准备 qat / calibration 模型之前,需要先给模型设置 qconfig。

关于qconfig的详细原理,您可以参考 构建QConfig 章节的内容。

使用 QconfigSetter 配置qconfig (推荐)

在实际的大模型或复杂网络中,手动为每个层设置 QConfig 非常繁琐。 QconfigSetter 配合 模板 (Templates) 可以根据计算图自动分发配置。 QconfigSetter 依赖于 prepare 阶段生成的计算图(Graph Mode),它按照模板列表 (templates) 的顺序依次应用规则。 QconfigSetter 的核心结构如下:


QconfigSetter(
    reference_qconfig=...,  # 1. 提供基础的 `observer` 的qconfig
    templates=[...],        # 2. 核心:配置规则列表 (按顺序生效)
    enable_optimize=True,   # 3. if True, 自动开启图优化 
    save_dir=...            # 4. qconfig 配置结果(qconfig.pt 文件)和 changelog 的保存路径
    custom_qconfig_mapping=... # 5. 用字典为单算子指定自定义的qconfig. 
)

reference_qconfig 设置

我们推荐使用 get_qconfig 快速配置reference_qconfig, 参考示例如下:

import torch
from horizon_plugin_pytorch.quantization import get_qconfig
from horizon_plugin_pytorch.quantization.observer_v2 import MinMaxObserver
from horizon_plugin_pytorch.quantization.qconfig import QConfig
from horizon_plugin_pytorch.quantization.fake_quantize import FakeQuantize
from horizon_plugin_pytorch.dtype import qint8
reference_qconfig = get_qconfig(
    observer=MinMaxObserver,   # 输入输出 observer 类型,只支持 horizon_plugin_pytorch.quantization.observer_v2 中的 MinMaxObserver 和 MSEObserver,默认值为 MinMaxObserver。
    in_dtype=None,  # 输入数据类型,考虑算子的支持情况进行设置。None 表示 QConfig 的 input 关键字为 None,默认值为 None。
    weight_dtype=qint8,  # 权重数据类型,考虑算子的支持情况进行设置。None 表示 QConfig 的 weight 关键字为 None,默认值为 qint8。
    out_dtype=qint8,  # 输出数据类型,考虑算子的支持情况进行设置。None 表示 QConfig 的 output 关键字为 None,默认值为 qint8。
    fix_scale=True,   # 是否固定输入输出 scale。
)

qconfig配置模板 (Templates)

模板按列表顺序生效,后定义的模板会覆盖先定义的配置(或者特定名称覆盖全局),更详细的解释可以查看 构建QConfig 章节。

常用模板包括:

  1. ModuleNameTemplate (通用): 通过算子名称或前缀设置 dtype。 "": dtype 表示全局默认配置, 越长的名字(越具体)优先级越高。支持设置固定阈值 (threshold)。

  2. ConvDtypeTemplate: 专门用于批量设置卷积层的 input 和 weight 类型。

  3. MatmulDtypeTemplate: 专门用于批量设置矩阵乘法(Linear/MatMul)的 input 类型。

  4. SensitivityTemplate: 根据敏感度分析结果,自动将 Top-N 的敏感层设置为高精度。

  5. LoadFromFileTemplate: 加载 qconfig.pt 文件,用于复现之前的量化配置。此时 enable_optimize 必须为 False,否则配置结果的正确性无法保证,部署时可能存在 cpu 算子

一个常用的模板配置例子为:

import torch
import copy
import os
from horizon_plugin_pytorch.dtype import qint8, qint16
from horizon_plugin_pytorch.quantization import get_qconfig, observer_v2, prepare, PrepareMethod
from horizon_plugin_pytorch.quantization.qconfig_setter import (
    ConvDtypeTemplate,
    MatmulDtypeTemplate,
    ModuleNameTemplate,
    QconfigSetter,
)

# 1. 定义配置模板 (Templates)
# 这里的顺序非常重要:
# 先设置全局为 Float16,然后用具体的 Conv/Matmul 配置去覆盖它。
q_template = [ 
    # [策略1] 全局兜底:所有算子默认输出 Float16 (模拟伪转换)
    ModuleNameTemplate({"": torch.float16}),
    
    # [策略2] MatMul:将所有 MatMul 算子的输入强制设为 Int16
    MatmulDtypeTemplate(  
        input_dtypes=[qint16, qint16],
    ),
    
    # [策略3] Conv:输入 Int16 (保精度), 权重 Int8 
    ConvDtypeTemplate( 
        input_dtype=qint16,
        weight_dtype=qint8, 
    ),
]

配置custom qconfig

尽管qconfig模板已经可以覆盖大部分的模型qconfig配置需求,但考虑到可能存在一些特殊场景,我们也在 QconfigSetter 中提供了接口,支持您为模型算子单独配置qconfig 。

首先,您可以直接配置qconfig, 一个 qconfig 对象可以设置 input / weight / output 三个关键字,分别表示算子输入/权重/输出的量化配置. prepare 模型时会根据这些配置决定是否要在对应位置插入 FakeQuantize / FakeCast 节点,None 表示不插入任何节点。

FakeQuantize 是伪量化节点,会对输入进行量化反量化操作,插入伪量化可以在浮点模型的前向中模拟量化产生的误差,主要用于定点类型算子的量化, 例如 qint8 和 qint16 。

FakeCast 是伪转换节点,会将输入转换为 float32 类型,如果数据类型是 float16,那么还会在中间模拟转 float16 产生的截断误差,此节点主要用于标志需要浮点计算的算子。

一个 Qconfig 定义的例子是:

import torch
from horizon_plugin_pytorch.quantization.qconfig import QConfig
from horizon_plugin_pytorch.quantization.fake_quantize import FakeQuantize
from horizon_plugin_pytorch.quantization.fake_cast import FakeCast
from horizon_plugin_pytorch.quantization.observer_v2 import MinMaxObserver
from horizon_plugin_pytorch.dtype import qint8

qconfig = QConfig(
    input=None,
    weight=FakeQuantize.with_args(
        observer=MinMaxObserver,
        dtype=qint8,
        qscheme=torch.per_channel_symmetric,
        ch_axis=0,
    ),
    output=FakeCast.with_args(dtype=torch.float16),
    # activation=xxx 早期用法,作用与 output 关键字一致,当前仍兼容,但建议您使用 output 关键字。
)

这个 qconfig 定义了 weight类型为 per-channel 对称量化,类型为 qint8 , observer 为 MinMaxObserver

有了qconfig, 您可以用 custom_qconfig_mapping 为模型单算子指定qconfig:

qconfig_mapping={
    "module_name": qconfig
}
QconfigSetter(
    reference_qconfig=..., 
    templates=[...],       
    enable_optimize=True,  
    save_dir=...           
    custom_qconfig_mapping=qconfig_mapping
)

综上,您可以对模型的 qconfig 实现完全的控制。