1 简介
最近在浏览 Paddle2ONNX 的 Issues 时,我发现有用户需要让 Paddle2ONNX 支持导出的 ONNX 模型根据opset版本自适应 ONNX IR 版本,于是我动手添加了这个功能。
2 什么是ONNX IR
ONNX (Open Neural Network Exchange) IR (Intermediate Representation) Version 的作用是定义和描述 ONNX 模型文件的结构和格式。该参数主要在以下方面发挥作用:
- 兼容性管理
- 模型文件解析
- 演进管理
显然,对于 Runtime 来说,指定 ONNX IR 是提升程序鲁棒性的方式之一,因此一般会对 ONNX IR 有所要求。
3 代码实现
由于 ONNX Opset 和 ONNX IR 是强绑定的,具体关系如下表:
ONNX version | IR version | Opset version ai.onnx | Opset version ai.onnx.ml | Opset version ai.onnx.training |
---|---|---|---|---|
1.0 | 3 | 1 | 1 | - |
1.1 | 3 | 5 | 1 | - |
1.1.2 | 3 | 6 | 1 | - |
1.2 | 3 | 7 | 1 | - |
1.3 | 3 | 8 | 1 | - |
1.4.1 | 4 | 9 | 1 | - |
1.5.0 | 5 | 10 | 1 | - |
1.6.0 | 6 | 11 | 2 | - |
1.7.0 | 7 | 12 | 2 | 1 |
1.8.0 | 7 | 13 | 2 | 1 |
1.8.1 | 7 | 13 | 2 | 1 |
1.9.0 | 7 | 14 | 2 | 1 |
1.10.0 | 8 | 15 | 2 | 1 |
1.10.1 | 8 | 15 | 2 | 1 |
1.10.2 | 8 | 15 | 2 | 1 |
1.11.0 | 8 | 16 | 3 | 1 |
1.12.0 | 8 | 17 | 3 | 1 |
1.13.0 | 8 | 18 | 3 | 1 |
1.13.1 | 8 | 18 | 3 | 1 |
1.14.0 | 9 | 19 | 3 | 1 |
1.14.1 | 9 | 19 | 3 | 1 |
1.15.0 | 9 | 20 | 4 | 1 |
1.16.0 | 10 | 21 | 5 | 1 |
如果你需要更详细的介绍,请前往 ONNX Versioning
在Paddle2ONNX中,控制 opset 版本的是 OnnxHelper 类,因此我们考虑先能够从该类中获取到当前 opset 对应的 IR ,我们可以添加如下函数实现这个功能:
cpp
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);
}
当然,也可以通过 std::map 实现这个功能
然后我们需要获取到当前 IR 版本,并给 onnx 模型指定他,可以在 exporter.cc 中添加如下代码:
cpp
auto ir_version = _helper.GetIRVersion();
auto model = std::make_shared<ONNX_NAMESPACE::ModelProto>();
model->set_ir_version(ir_version);