目录
- 前言
- 1. 正确导出ONNX
- 总结
前言
杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。
本次课程学习 tensorRT 基础-正确导出 onnx 的介绍,使得 onnx 问题尽量少
课程大纲可看下面的思维导图
1. 正确导出ONNX
关于如何正确导出 onnx,主要有以下几点说明:(from 杜老师)
1. 对于任何用到 shape、size 返回值的参数时,例如 tensor.view(tensor.size(0), -1) 这类操作,避免直接使用 tensor.size 的返回值,而是加上 int 转换,tensor.view(int(tensor.size(0)), -1),断开追踪
2. 对于 nn.Unsample 或 nn.functional.interpolate 函数,使用 scale_factor 指定倍率,而不是使用 size 参数指定大小
3. 对于 reshape、view 操作时,-1 的指定请放到 batch 维度。其它维度可以计算出来即可。batch 维度禁止指定为大于 -1 的明确数字
4. torch.onnx.export 指定 dynamic_axes 参数,并且只指定 batch 维度,禁止其它动态
5. 使用 opset_version=11,不要低于11
6. 避免使用 inplace 操作,例如 y[…, 0:2] = y[…, 0:2] * 2 - 0.5
7. 尽量少的出现 5 个维度,例如 ShuffleNet Module,可以考虑合并 wh 避免出现 5 维
8. 尽量把后处理部分在 onnx 模型中实现,降低后处理复杂度(比如说计算 anchor 这类操作放到 onnx,让我们只需要关注简单的 decode 部分)
9. 掌握了这些,就可以保证后面各种情况的顺利了
这样做法的必要性体现在,简化过程的复杂度,去掉 gather、shape 类的节点,很多时候,部分不这么改看似也是可以,但是需求复杂后,依旧存在各类问题。按照说的这么修改,基本总能成。做了这些,就不需要使用 onnx-simplifer 了。
下面测试了 view 操作时加上 int 转换,且 -1 放在 batch 维度导出的 onnx 差别:
值得注意的是,博主在测试时发现加不加上 int 转换似乎都不会生成 Gather、Unsqueeze 节点,不过依稀记得在 yolov5 导出 onnx 的时候 view 等操作加上了 int 转换后确实减少了很多不必要的节点。
总结
本节课程简要说明了导出 onnx 的一些注意事项,尽量使得生成 engine 的时候问题少,不过目前来看,当导出的 onnx 生成 engine 失败时,博主会先考虑先直接 simplifer,如果能解决最好,解决不了才去分析具体导出的 onnx 可能存在的问题。