最近在部署一个YOLOv8-seg模型到Jetson Orin上,用PyTorch转ONNX的时候设了dynamic_axes,转TensorRT时也加了--dynamicShapes,但推理时只要输入分辨率不是固定尺寸就报 “The provided input shape is not compatible with the engine” 或者有时直接崩。我看网上教程都说设了dynamic就行,但实际跑起来各种坑。我用的TensorRT是8.6,ONNX是从ultralytics官方脚本导出的。有没有人遇到过类似问题?是ONNX导出时opset版本的问题,还是TensorRT这边min/opt/max的profile设置不对?另外,分割头的输出形状变化是不是也要单独处理?求有实际部署经验的大佬指点一下,卡了两天了,谢谢!
PyTorch转ONNX再转TensorRT,Dynamic Shape一直报错,求大佬指点
全部回复
共 128 条ONNX里dynamic_axes没覆盖到所有输出,TensorRT建engine时profile也得设全,不然就这报错。
ONNX那边dynamic_axes光设batch不够,h和w也得显式标上,不然TRT压根不认。
这个坑我去年在Orin上踩过,YOLOv8-seg的dynamic shape确实比检测模型更容易出问题。你留意一下ONNX导出时的opset,ultralytics默认好像是17,但TensorRT 8.6对某些op的dynamic支持在17上是有bug的,试试降到16或者升到18对比下。另一个隐蔽点是min/opt/max这三个shape,很多人只填了opt,结果engine编译出来的profile只覆盖那一档,输入稍微变一点就报不兼容。分割头里的Resize和Concat节点在dynamic下特别容易让TRT推断出错误的维度范围,建议用trtexec加--minShapes/--optShapes/--maxShapes显式写全,再配合--verbose看它实际吃进去的profile。还有个经验是别直接用ultralytics导出的onnx跑TRT,先用onnxsim过一遍,把那些常量折叠和冗余transpose清掉,dynamic推理会稳很多。如果还是崩,可以先把seg分支单独拆出来测,确认是backbone还是proto那边的问题。
这个坑我去年在Orin上踩过一模一样的,YOLOv8-seg转TRT做动态shape确实比检测模型更容易出问题。你那个报错大概率不是opset的事,opset 12以上一般够用,问题多半出在TensorRT的optimization profile没配好。用trtexec加--dynamicShapes只是开了个口子,真正决定能跑哪些分辨率的是minShapes/optShapes/maxShapes这三个参数,如果只写--dynamicShapes而不显式指定profile,TRT有时会退化成一个很窄的范围,你喂进去的尺寸稍微偏一点就报incompatible。建议你转engine的时候把三个shape都写全,比如--minShapes=images:1x3x640x640 --optShapes=images:1x3x960x960 --maxShapes=images:1x3x1280x1280,注意seg模型还有输出mask的维度也要一起设。另外ultralytics导出的ONNX里如果dynamic_axes只标了batch没标h/w,那TRT那边再怎么设也没用,得回去检查ONNX的输入是不是真的dynamic。还有个隐蔽的点是YOLOv8-seg的proto分支对h/w有整除要求,分辨率不是32的倍数时中间层会直接对不齐崩掉。你可以先用polygraphy跑一下onnxruntime确认动态维度真的生效了,再往TRT走,能省不少排查时间。
这个思路不错,收藏了。
我之前也遇到过类似问题,后来换了方案。
我之前踩过这个坑,YOLOv8-seg导出ONNX时如果dynamic_axes只设了batch没设height/width,TensorRT那侧就算加了--dynamicShapes也会按固定分辨率建engine。建议你用polygraphy或trtexec先dump一下onnx的输入shape,确认h/w维度真的是-1。另外TensorRT 8.6对seg模型的mask分支动态reshape比较敏感,optimization profile的min/opt/max三个shape都要显式给,不能只给opt。
ultralytics那个导出脚本默认opset是17,TensorRT 8.6对高版本opset的dynamic shape支持其实挺挑的,你可以试试降到opset 12或13重新导一次。另外min/opt/max三个shape别只填一组,opt最好取你实际推理最常用的分辨率,不然TRT优化出来的profile对不上也会报这个错。我之前在Orin上跑seg模型也卡过这儿,后来把onnx用polygraphy跑一遍shape infer,看看哪一层的动态维度没传下去,基本就能定位到问题。