最近在搞一个工业检测的项目,模型已经在PyTorch上训练好了,想用TensorRT加速推理。但遇到动态batch的问题卡了两天。我的模型输入是(1,3,512,512),但实际应用时batch size可能从1到8不等。按照NVIDIA官方文档试了用-1占位,结果trtexec报错说“dynamic dimensions require explicit batch”。用Python API设了opt_profile和min/max,跑是能跑了,但推理结果和PyTorch对不上,怀疑是某些算子不支持动态shape被回退到CPU了。想问下各位大佬,这种场景是不是干脆固定batch size更省事?或者有什么确认算子兼容性的工具推荐?先谢过了。
PyTorch转TensorRT时动态batch到底怎么设?官方文档看得我头晕
全部回复
共 169 条动态batch这块确实挺容易踩坑的,我上次也是被explicit batch这个要求卡了半天。你那个trtexec报错其实就是在说,只要用了-1就必须开explicit batch模式,不然TensorRT不知道去哪一维做动态。另外推理结果对不上,大概率不是算子回退到CPU,TensorRT遇到不支持的动态shape算子一般直接报错或者构建失败,不会偷偷回退。更可能的是你opt_profile里的shape没覆盖到实际推理时用的batch,或者校准/精度设置跟PyTorch不一致,比如fp16下数值误差累积。工业检测这种对精度敏感的,建议先把min=1, opt=1, max=8都显式写清楚,然后拿batch=1单独跑一遍跟PyTorch对齐,再逐级加batch看哪一档开始飘。如果只有1到8这种小范围,其实固定batch=8再补零推理,最后裁掉多余结果,很多时候比折腾动态shape省事得多,性能也不会差太多。
动态shape推理结果对不上,八成是profile没覆盖实际输入的shape范围,或者某些插件层在动态维度下走了fallback。你可以先用polygraphy对比一下onnx和trt的输出,定位到具体哪层开始偏的。工业检测这种场景如果延迟不敏感,固定batch=8再补个batch=1的engine做兜底其实更省心。
动态batch这块有个坑挺多人踩的,就是你得先用polygraphy或者trtexec的--verbose看看哪些层被切到CPU了,工业检测里常见的grid_sample、roi_align这些TRT对动态shape支持就是不行。我建议你先跑个固定batch=1的engine,拿PyTorch的输出对齐一下,确认精度没问题再上动态,不然你都不知道是量化误差还是算子回退导致的。另外min设成1、opt设成4、max设成8这种profile,有时候TRT会给不同batch选不同的kernel,精度波动挺大的,可以试试把opt直接设成max。实在不行就固定batch=8,前面用padding凑,工业场景延迟要求没那么极限的话这样最省心。
试试显式指定dynamic shape并锁死optimization profile,回退多半是某些插件层不支持。
固定batch最省心,动态shape回退CPU基本无解,除非换ONNX再转。
固定batch省事但浪费,工业检测batch经常是1,动态shape回退CPU确实会导致结果对不上,建议先用polygraphy查下哪些层不支持。
固定batch到8再补个batch=1的engine其实挺常见的,工业检测里延迟没那么敏感的话完全够用。你那结果对不上八成是某个插件或op在动态shape下走了fallback,可以开verbose log看哪些层被拆了。另外记得检查下PyTorch那边是不是有随机性没关掉,比如dropout或者数据预处理。实在不行就老老实实固定batch,别跟动态shape死磕,踩坑时间够你写好几个版本了。
我之前也遇到过类似问题,后来换了方案。
动态shape对不上的问题我也踩过,大概率是某些插件或算子走了CPU回退,你可以开verbose日志看哪些层被切了。工业检测这种场景batch不固定,固定batch省事但灵活性差,建议先把onnx导出时shape设成dynamic axes,再用polygraphy跑一遍对比输出定位到具体层。trtexec那个报错是因为你用的explicit batch模式,必须配合profile的min/opt/max一起设,光给-1不够。实在搞不定就按1和8各build一个engine轮着用,糙但稳。