最近在把训练好的一个图像分类模型(ResNet50)转成ONNX,部署到移动端用。按照文档设了dynamic_axes={‘input’: {0: ‘batch_size’}},导出也成功了。但用onnxruntime推理时,只要batch_size不是1就报错,说“输入形状不匹配”?试了opset版本11和12都一样。是不是导出时少设了什么参数,比如输入尺寸的dynamic_axes必须和模型内部结构对应?还是说模型里有不支持动态batch的层(比如BatchNorm)?求有经验的大佬指点一下,我实在不想把batch固定为1。
PyTorch模型转ONNX时,动态轴设了但推理报错,有老哥踩过坑吗?
全部回复
共 7 条可能是BatchNorm里的running mean对动态batch不兼容,试试把模型设成eval模式再导出。
这问题我遇到过类似的,关键点在于dynamic_axes只控制了导出的接口,但模型内部如果有reshape或flatten操作硬编码了固定维度,推理时就会报形状不匹配。ResNet50本身没啥动态batch的限制,建议先检查一下onnx模型里是否有像“Reshape”节点绑死了第二维的形状。另外可以试试用onnx-simplifier简化一下,或者直接设一个动态的batch维度但把输入的实际shape同时改小一点测试。
试试把BatchNorm层设成eval模式再导出,训练模式下的动态batch确实容易翻车。
我也遇到过类似问题,动态轴设了但推理报错,后来发现是模型里有些reshape或flatten操作没有处理好,导致导出的onnx对动态batch支持不完整。你可以先用onnx-simplifier优化一下图结构,再检查下是否有不支持动态尺寸的算子,比如某些版本的Resize。另外,onnxruntime的session选项里记得把optimization_level调低点,有时候优化反而会破坏动态shape逻辑。
BatchNorm在ONNX里对动态batch支持确实有问题,试试把eval模式下的bn层固定住再导出。
动态轴设置看起来没问题,但报错大概率是ResNet里的BatchNorm在导出时对动态batch支持不完整,你可以试试把opset升到15以上,新版本对动态形状处理更好。另外检查下模型里有没有reshape或者flatten操作依赖了固定尺寸,这些层在动态batch下容易翻车。我之前也遇到过类似问题,最后是用onnx-simplifier优化了一遍才跑通。
这个问题大概率不是dynamic_axes没设对,而是模型里某些操作(比如reshape、view或者张量拼接)依赖了固定batch size,导致onnxruntime推理时shape推导出问题。ResNet50本身没有BatchNorm不支持动态batch的说法,倒是可以检查下导出时是不是用了torch.onnx.export的input_names和output_names,同时把dynamic_axes写全,比如输出也得加上batch维度。我之前踩过类似的坑,最后发现是第三方库的某个模块在转onnx时偷偷写死了shape,得手动改模型结构。