静态量化必须严格按prepare→calibration→convert三步执行,跳过calibration会因缺失观测器报错;校准需用与推理分布一致的真实数据,且模型仅支持cpu推理。

静态量化必须走完 prepare → calibration → convert 三步
跳过校准直接调用 convert 会报错 AttributeError: 'Conv2d' object has no attribute '_observer',因为观测器没插入。PyTorch 静态量化不是“一键转换”,而是分阶段注入量化逻辑:
-
model.qconfig = get_default_qconfig('fbgemm'):指定后端(CPU 推荐fbgemm,ARM 设备用qnnpack) -
model_prepared = prepare(model):在所有待量化层插入QuantStub/DeQuantStub和观测器(Observer) - 用真实数据(哪怕 10–100 张图)跑一遍前向传播,让观测器记录激活值分布
-
final_model = convert(model_prepared):把带观测器的模型转成真正含torch.nn.quantized.*层的量化模型
校准数据必须和推理时输入分布一致
校准不是“随便喂几张图”,它直接影响 scale/zero_point 的准确性。如果校准用 ImageNet 子集但推理时全是灰度图,量化后精度可能暴跌 5%+。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 校准 batch size 建议 ≥32,避免 batch norm 统计偏差
- 图像预处理(归一化、resize)必须和推理完全一致,否则
input_tensor的数值范围对不上 - 不需要标签,只做前向:用
with torch.no_grad(): model_prepared(x) - 若校准数据受限,可复用训练集最后 1% 或验证集子集,但别用全零/全 1 输入
层融合能绕过量化误差累积
单独量化 Conv2d + BatchNorm2d + ReLU 会导致三次量化误差叠加。PyTorch 提供 fuse_modules 在 prepare 前合并这些层,让整个模块只经历一次量化。
- 写法:
fuse_modules(model, [['conv', 'bn', 'relu']], inplace=True),注意模块名要和 model 属性名严格匹配 - 融合后,
model_prepared中对应位置变成单个QuantizedConvReLU2d,不再有 BN 伪量化开销 - MobileNetV2 等含
InvertedResidual的结构,需先确保其子模块命名规范,否则融合失败 - 融合不是必须,但不融合时建议禁用 BN 层量化:
qconfig_dict = {'': get_default_qconfig('fbgemm'), 'bn': None}
量化后模型不能直接 .to(device) 移动到 GPU
PyTorch 原生静态量化目前只支持 CPU 推理。试图把 quantized_model 调用 .cuda() 会触发 RuntimeError: Cannot copy out of a quantized tensor。
- INT8 量化模型只能在 CPU 上运行,GPU 加速需靠 TensorRT 或 ONNX Runtime 导出后再部署
- 即使你有 GPU,也得显式指定
device = torch.device('cpu'),并确保 input tensor 在 CPU 上 - 想在 GPU 加速?得走
torch.onnx.export→ TensorRT INT8 校准流程,PyTorch 原生不提供 GPU 量化执行引擎 - 别被
torch.qint8名字误导——它只是数据类型标记,不代表硬件加速能力
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










