1 简介
最近在浏览 Paddle2ONNX 的 Issues 时,我发现有用户需要让 Paddle2ONNX 支持导出的 ONNX 模型根据 Opset Version 自适应 IR Version 的功能。这个功能对于老的 Runtime 来说还是很重要的,于是我动手添加了这个功能,这里写一篇博客和大家分享下。
2 什么是 ONNX IR Version
ONNX IR 是开放神经网络交换标准中定义的一种数据流图表示形式。一般来说,一个 Opset Version 对应着一个 IR Version 版本。在实践中,选择正确的 IR Version 对于确保模型在不同平台和框架之间的兼容性和正确性至关重要。
3 代码实现
3.1 Opset Version 和 IR Version 的对应关系
从 ONNX 官方文档 Versioning 中我们可以知道,Opset Version 和 IR Version 是强绑定的,具体关系如下表:
ONNX version | IR version | Opset version ai.onnx |
---|---|---|
1.2 | 3 | 7 |
1.3 | 3 | 8 |
1.4.1 | 4 | 9 |
1.5.0 | 5 | 10 |
1.6.0 | 6 | 11 |
1.7.0 | 7 | 12 |
1.8.0 | 7 | 13 |
1.8.1 | 7 | 13 |
1.9.0 | 7 | 14 |
1.10.0 | 8 | 15 |
1.10.1 | 8 | 15 |
1.10.2 | 8 | 15 |
1.11.0 | 8 | 16 |
1.12.0 | 8 | 17 |
1.13.0 | 8 | 18 |
1.13.1 | 8 | 18 |
1.14.0 | 9 | 19 |
1.14.1 | 9 | 19 |
1.15.0 | 9 | 20 |
1.16.0 | 10 | 21 |
1.17.0 | 10 | 22 |
3.2 在 Paddle2ONNX 中添加代码
在Paddle2ONNX中,控制 Opset Version 版本的是 OnnxHelper 类。我们考虑从该类中获取到当前 Opset Version 并转换为对应的 IR Version,例如我们可以添加以下代码:
ONNX_NAMESPACE::Version OnnxHelper::GetIRVersion() const {
int ir_version = 0;
switch (opset_version) {
case 7:
case 8:
ir_version = 3;
break;
case 9:
ir_version = 4;
break;
case 10:
ir_version = 5;
break;
case 11:
ir_version = 6;
break;
case 12:
case 13:
case 14:
ir_version = 7;
break;
case 15:
case 16:
case 17:
case 18:
ir_version = 8;
break;
case 19:
case 20:
ir_version = 9;
break;
case 21:
ir_version = 10;
break;
default:
Assert(false, "Opset version must be 7-20");
}
return static_cast<ONNX_NAMESPACE::Version>(ir_version);
}
由 Opset Version 转换为 IR Version 后,我们需要将 IR Version 指定给 ONNX 模型,例如可以在 exporter.cc 中添加如下代码:
auto ir_version = _helper.GetIRVersion();
auto model = std::make_shared<ONNX_NAMESPACE::ModelProto>();
model->set_ir_version(ir_version);
4 参考资料
- [ONNX][Version] Update IR Version by Zheng-Bicheng · Pull Request #1261 · PaddlePaddle/Paddle2ONNX
- onnx/docs/Versioning.md at main · onnx/onnx