1. HistogramObserver基础用法
有了全局直方图后,需要通过搜索策略从分布中选出最优scale。常用的搜索方式如下:
搜索方式 | 说明 | 建议 |
mse | 默认方式。根据数据分布计算不同 scale 下伪量化前后的误差,选择损失更小的 scale。 | mse大多数情况下效果较好,推荐作为首选 |
percentile | 控制有效值在总体数据中的占比。percentile=1.0 时可理解为 minmax搜索percentile=0.9999(默认)时可轻微裁剪极端值。 | 作为 mse 之后的备选 |
HistogramObserver通常用于校准,得到最佳的校准精度,然后固定激活scale,使用速度更快的MinMaxObserver进行QAT,基于此,qconfig配置示例如下:
2. HistogramObserver进阶用法
一次校准,复用校准结果设置不同搜索策略
一次校准,复用校准结果切换量化dtype
2.1 设置不同搜索策略
reset_scale中每个参数含义如下:
参数 | 类型 | 作用 | 详细说明 |
cls | class | 当前类本身 | 该函数是 @classmethod 修饰的方法,cls 表示当前类对象,而不是实例对象 self |
model | torch.nn.Module | 待处理模型 | 已经完成 calibration 的 PyTorch 模型。函数会遍历其中的 FakeQuantize 节点,重新计算 scale |
method | str | scale 计算方法 | 指定重新计算scale 的策略。常用'mse'、'percentile' |
method_kwargs | Dict | scale 计算附加参数 | 给 method 提供额外配置参数。用于percentile 方法,可设置:{'percentile': 0.999},表示仅保留 99.9% 数据范围用于量化。 |
prefix | Tuple[str] | 指定处理模块范围 | 用于限制只对特定模块的scale 进行 reset |
dtype | optional | 指定量化数据类型 | 仅重置某种 quant dtype 的 scale。例如只处理qint8、qint16 等特定量化类型的scale。 |
建议优先选用默认的mse策略进行精度调优,绝大部分情况下,mse可以满足需求。
- 切换方式:从默认 mse 改为 percentile,观察能否缓解截断或舍入误差。
- scale 会保存在 state_dict 中,因此reset_scale后需重新保存模型权重。
使用HistogramObserver完成常规校准流程,若精度不满足预期,使用调整搜索策略进行精度调优,可基于校准后的calib_net进行如下操作:
2.2 切换量化dtype
horizon_plugin_pytorch需升级到3.3.5及以上(OE 3.9.0)
2.2.1 load_calib_state_dict接口解析
接口入参详解:
参数 | 类型 | 作用 | 详细说明 |
model | torch.nn.Module | 目标模型 | 由 prepare() 生成的伪量化模型 |
state_dict | dict | 校准模型参数字典 | 已完成 calibration 的模型的 state_dict,包含权重参数及 observer/fake quant 的量化统计信息(min/max、histogram、histogram_edges、scale、zero_point 等)。要求与当前 model 架构一致。 |
strict | bool | 是否严格校验 key | 默认True,存在缺失 key 或非 observer 类 unexpected key 直接报错;为 False 时允许部分 key 不匹配。 |
assign | bool | 是否使用 assign 模式加载 | 透传给 torch.nn.Module.load_state_dict(assign=...)。 |
force_overwrite | bool | 是否强制重算 scale | 默认False,dtype 一致时跳过 scale 重算;为 True 时,对所有量化模块都重算 scale ,而非仅处理 dtype 不一致的模块。 |
reset_kwargs | Optional[dict] | scale 重计算附加参数 | 当 HistogramObserver 模块需要重算 scale 时,传递给 reset_scale()。例如:{'method': 'percentile', 'percentile': 0.999}。 |
verbose | bool | 是否打印初始状态汇总 | 默认True,输出每个模块的 observer 类型、dtype 转换状态 汇总表。 |
接口返回值详解:
返回项 | 类型 | 含义 |
_IncompatibleKeys | namedtuple | 包含 missing_keys 与 unexpected_keys,与 PyTorch load_state_dict() 返回风格一致 |
missing_keys | List[str] | 当前模型存在但 state_dict 中缺失的参数/buffer 名称 |
unexpected_keys | List[str] | state_dict 中存在但当前模型没有对应项的 key(已过滤掉 activation_post_process、activation_pre_process、weight_fake_quant 相关 key) |
2.2.2 支持的 dtype 切换范围
qint8 ↔ qint16
float16 ↔ float32
qint8/qint16 → float32
注意:无法实现qint8/qint16->float16的切换,即使通过float32间接切换也不行。因为qint8/qint16->float32时,minmax信息是空的,转float16需要有minmax信息。
2.2.3 使用流程

- 对浮点模型float_net执行第一次 prepare 并完成 Calibration。
- Calibration 阶段需要在 QconfigSetter 中关闭 Conv + add 的 fuse,因为此时 conv 输入 dtype 尚未最终确定,若后续将 conv 输入改为 qint16,则无法再 fuse。Calibration 阶段不做 fuse,可兼容后续 fuse / 不 fuse 两种情况。
- Calibration 阶段需要在 QconfigSetter 中关闭 Gemm类算子高精度输出,否则可能会出现在修改模型尾部gemm类算子精度类型后,重新加载权重出现missing keys。
- 保存 calib_state_dict = calib_model.state_dict()。
- 在 Calibration 所用 qconfig 基础上,按敏感度分析等结果调整模板qconfig_new(例如将部分层从 qint8 提升为 qint16),对浮点模型重新 prepare,得到 qat_calib_model,可用于后续 评估精度/QAT/导出bc。
- 调用 load_calib_state_dict 加载 Calibration 权重,再进入 Validation 或 QAT。
2.2.4 示例代码
如下示例可直接运行:
