1.常见的和ONNX Simplifier相似的网络优化工具
| 工具 | 是否原生 PT | 优化方式 | 输出格式 | 对标 onnxsim 程度 |
|---|---|---|---|---|
| TorchScript+MobileOptimizer | ✅原生 | 静态图离线优化 | .pt(TorchScript) | ⭐⭐⭐⭐⭐ 官方平替 |
| Torch-FX | ✅原生 | 手动图改写 | .pth/.pt(权重) | ⭐⭐⭐⭐ |
| onnxsim+onnx2tf | ❌中转 ONNX | 成熟图精简 | .pt/pt2 | ⭐⭐⭐⭐⭐ 复用最强优化 |
| onnxoptimizer | ❌中转 ONNX | 细粒度自定义优化 | 中转 onnx 再转 pt | ⭐⭐⭐⭐⭐ |
| torch.compile | ✅原生 | 运行时即时优化 | 无法离线存优化 pt | ⭐⭐⭐ |
2.各工具的优化内容
2.1 ONNX Simplifier
1.适用场景
ONNX Simplifier 本质是ONNX 计算图语法级轻量化工具,核心做几类优化:
- 消除冗余节点:恒等映射、未使用的中间张量、多余 Reshape/Unsqueeze/Squeeze、连续 Conv+BN 融合、Dropout 去除、冗余 Cast 类型转换;
- 常量折叠:把编译期就能算完的常量运算提前固化为权重,减少运行时计算;
- 算子合并:连续的矩阵乘 + 加、多段拼接、冗余分支裁剪;
- 清理导出残留:PyTorch/TensorFlow 导出时自动插入的训练用算子、控制流占位节点。
适合:CNN、ResNet、YOLO、Transformer 视觉模型、常规检测 / 分割 / 分类、简单 LSTM 等静态拓扑、无动态控制流的模型
2.不能优化 / 极易失败的几类模型
1. 带动态控制流的模型(最常见不支持场景)
ONNX Simplifier 对If、Loop、Scan等控制流算子支持很差:
- 循环推理的 RNN、GRU、LSTM 动态循环版本;
- 带条件分支的模型(根据输入阈值选择不同分支);
- 动态循环解码的大模型(如 RNN 语音识别、Seq2Seq 文本生成、GPT 类自回归解码); 这类模型要么简化直接报错,要么只能做局部优化,无法全局裁剪冗余。
2. 包含自定义算子(Custom Op)的模型
- PyTorch/TensorRT 自定义算子、算子插件、CUDA 扩展算子;
- 第三方库实现的算子(如 MMDetection、TorchVision 自定义 RoI、Deformable Conv、可变形卷积、NMS 自定义实现); Simplifier 只能识别官方 ONNX 标准算子,遇到未知自定义算子会跳过该子图,只能优化其余部分,无法整体优化,严重时直接简化失败。
3. 动态输入形状强依赖的复杂模型
模型大量使用动态维度运算、动态 Reshape、动态 Gather、动态切片:
- 输入不固定尺寸的 NLP 模型、变长文本编码模型;
- 动态目标数量的检测模型(动态 NMS、动态后处理); 很多常量折叠需要固定维度推导,动态维度下无法判定张量形状,冗余节点无法识别,优化效果极弱甚至无效。
4. 非标准导出、带训练节点的复杂图
- 保留梯度、BatchNorm 训练模式、随机算子(RandomNormal、Dropout 训练模式未关闭);
- 混合精度导出、大量精度转换分支、多输出冗余绑定; 部分节点无法判定是否冗余,只能小幅度清理。
5. 稀疏张量、量化模型、低精度压缩模型
- INT8/FP16 量化后的 ONNX 模型:大量量化反量化算子、定点约束,冗余节点很少,Simplifier 优化收益极低,强行简化还可能破坏量化对齐,导致推理精度暴跌;
- 稀疏权重模型、结构化剪枝后的定制图:拓扑经过修改,常量折叠容易出错。
6. 部分特殊大模型
大尺寸 Transformer、ViT、LLM 类模型:
- 多头注意力、大量循环式矩阵运算、动态序列长度;
- 存在大量重复结构但属于必要计算,几乎无可冗余节点可删; 简化后模型体积、推理速度提升微乎其微,仅能清理少量导出冗余。
3.推荐优化链路(逐级优化)
- 框架内先做推理模式固化(
model.eval(),关闭 dropout、BN 训练模式)再导出 ONNX; - 使用 ONNX Simplifier 做计算图冗余清理、常量折叠;
- 再用
onnxoptimizer做算子融合、常量优化补充; - 量化场景使用 ONNX Runtime / TensorRT 做运行时算子融合 + 精度优化;
- 带控制流 / 自定义算子的模型,需要手动重构推理图,不能依赖自动简化。