量化YOLOv8n模型转ONNX报错:quantized::conv2d.new后端不支持
解决方案
1. 修正QAT转换流程中的语法错误
原代码中self.quantized_model.apply(.apply(torch.ao.quantization.disable_observer))存在语法错误,多余的.apply会导致执行异常,修正为:
self.quantized_model.apply(torch.ao.quantization.disable_observer)
2. 调整QuantWrapper的使用时机
QuantWrapper需要在quant.convert()之前包裹模型,而非转换之后。转换操作会将模型中的FakeQuantize节点替换为真实量化节点,提前包裹才能让QuantStub/DeQuantStub被正确处理:
# 在convert之前包裹模型 model_to_wrap = QuantWrapper(self.quantized_model) model_to_wrap.eval() model_to_wrap.apply(torch.ao.quantization.disable_observer) model_to_export = quant.convert(model_to_wrap.cpu(), inplace=False)
3. 优化ONNX导出参数
- 提升opset版本到14或更高,量化算子在高opset下的支持更完善
- 导出前先执行一次前向传播,确保量化节点完成初始化
修改后的导出代码:
dummy_input = torch.randn(1, 3, 25, 256).cpu() # 先执行一次前向传播,初始化量化节点状态 model_to_export(dummy_input) torch.onnx.export( model_to_export, dummy_input, quantized_onnx_path, opset_version=14, # 提升opset版本以获得更好的量化算子支持 input_names=['images'], output_names=['output'], dynamic_axes = { 'images' : {0 : 'batch_size'}, 'output' : {0 : 'batch_size'} } )
4. 兼容YOLOv8自定义层
YOLOv8包含Detect等自定义层,这类层默认无量化支持,可通过以下方式处理:
- 拆分自定义层为标准卷积、激活等可量化层
- 对模型中的Conv-BN-ReLU结构进行层融合,提升兼容性与性能:
# 根据YOLOv8的实际层结构调整融合列表 fuse_list = [["conv1", "bn1", "relu1"], ["conv2", "bn2", "relu2"]] self.quantized_model.fuse_modules(fuse_list, inplace=True)
5. 确保QNNPACK后端配置一致
在QAT训练、模型转换、ONNX导出全流程中保持QNNPACK后端配置一致:
torch.backends.quantized.engine = "qnnpack" torch.backends.qnnpack.enabled = True
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

