直接用torch.quantization.quantize_dynamic通常不行,因其仅对linear/embedding权重量化、不处理激活值且无需校准,对cnn/vit等复杂模型无效;真正可用的是需三步手动介入的静态量化:设qconfig、prepare插入观察器、convert导出。

为什么直接用 torch.quantization.quantize_dynamic 通常不行
很多人一上来就调用 quantize_dynamic,发现模型输出乱码、精度暴跌甚至报错 RuntimeError: expected scalar type Float but found Byte。这不是函数本身有问题,而是它只对部分算子(如 nn.Linear 和 nn.Embedding)做权重量化,不触碰激活值,也不校准——对 CNN、ViT 或带复杂控制流的模型基本无效。真正能落地 INT8 的路径,是 **静态量化(static quantization)**,前提是模型结构稳定、能跑完校准数据集。
必须走通的三步:准备模型、插入观察器、导出部署格式
PyTorch 的 INT8 量化不是“一键转换”,而是一套需人工介入的流程。漏掉任意一步,model.qconfig 就不会生效,prepare 阶段也不会插入 QuantStub/DeQuantStub。
- 确保模型是
eval()模式,训练模式下的 dropout/batchnorm 会干扰校准 - 手动给模型添加
torch.quantization.QuantStub()和torch.quantization.DeQuantStub(),或用torch.quantization.prepare自动插入(但需提前设好qconfig) - 用小批量(50–100 张)真实输入数据运行一次前向,触发
observer收集激活值分布;不能用全零/随机噪声,否则scale和zero_point严重失真
qconfig 选错会导致 INT8 输出完全不可用
PyTorch 默认的 default_qconfig 是 per-tensor 对称量化,对某些层(如 ReLU 后的激活)会浪费动态范围。更稳妥的是:
- 权重用
torch.per_channel_symmetric(尤其nn.Conv2d),提升精度 - 激活用
torch.histogram_observer替代默认的minmax_observer,对非均匀分布更鲁棒 - 显式禁用不支持量化的模块,例如:
model.my_custom_layer.qconfig = None
示例设置:
华为云 Python SDK 查询工具。自动发现已安装 SDK 的服务包、Client类、API 方法、入参详情、类信息(__init__ 参数、属性、类型、描述),支持关键字搜索,快速定位目标 API 使用方法。
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
model.qconfig.activation = torch.quantization.HistogramObserver.with_args(reduce_range=False)
torch.quantization.prepare(model, inplace=True)
导出后务必验证 INT8 推理行为是否一致
调用 torch.quantization.convert 后得到的是一个真正含 nn.quantized.* 层的模型,此时不能再用 float() 或送 GPU。常见翻车点:
- 输入 tensor 必须是
torch.float,但会被内部自动量化——别自己先.to(torch.int8) - 输出仍是
torch.float(已反量化),不是int8;想看原始 INT8 值得从module._packed_params里取 - CPU 核数不足或未绑定线程(
torch.set_num_threads(1))时,fbgemm后端可能降级为慢速实现
最简验证方式:
with torch.no_grad():
int8_out = int8_model(x.float())
fp32_out = fp32_model(x.float())
print(torch.max(torch.abs(int8_out - fp32_out))) # 一般应 <p>真正的难点不在代码行数,而在校准数据是否覆盖边缘 case、各层 observer 是否被正确触发、以及后端(fbgemm / qnnpack)与硬件指令集的匹配程度——这些没法靠 print 调试,得靠逐层 dump scale/zero_point 来定位。</p>Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










