Skip to content

Commit

Permalink
expose get_all_supported_ops in python
Browse files Browse the repository at this point in the history
Signed-off-by: Zhang Jun <[email protected]>
  • Loading branch information
jzhang533 committed Aug 30, 2024
1 parent 07acbcb commit e58d22d
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 21 deletions.
21 changes: 15 additions & 6 deletions docs/zh/Paddle2ONNX_Development_Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
## 1 Paddle2ONNX 简介

### 1.1 什么是 ONNX

ONNX(Open Neural Network Exchange)是一个开放的深度学习模型交换格式,旨在使不同深度学习框架之间的模型转换和互操作变得更加容易。它由微软和Facebook联合开发,于2017年宣布发布。ONNX的主要目标是使深度学习模型在不同框架之间更容易地移植和部署。通过 ONNX 格式,Paddle 模型可以使用 ONNXRuntime、RKNNRuntime 和 TensorRT 等推理框架进行推理。
ONNX(Open Neural Network Exchange)是一个开放的深度学习模型交换格式,旨在使不同深度学习框架之间的模型转换和互操作变得更加容易。它由微软和 Facebook 联合开发, 于201 7年宣布发布。ONNX 的主要目标是使深度学习模型在不同框架之间更容易地移植和部署。通过 ONNX 格式,Paddle 模型可以使用 ONNXRuntime、RKNNRuntime 和 TensorRT 等推理框架进行推理。。

### 1.2 什么是 Paddle2ONNX

Expand Down Expand Up @@ -53,11 +52,21 @@ Paddle2ONNX 开发的主要步骤为:
通过 Netron 的可视化,可以看到, **ATTRIBUTES** 中的参数 **axis****shifts** 与核心文档中的输入参数一一对应。


> [!NOTE]
> 获取当前所有支持的 OP 列表的方法:
>
> ```python
> import paddle2onnx
> paddle2onnx.get_all_supported_operators()
> ```
### 3.3 查阅 ONNX API 文档
掌握 Paddle OP 的原理和使用方式后,查阅 [ONNX Operators Docs](https://onnx.ai/onnx/operators/index.html) 找到对应的实现,若 ONNX OP 和 Paddle OP 没有一对一的实现,则需要根据 Paddle OP 的原理使用多个 ONNX OP 组合实现。
当我们在 [ONNX Operators Docs](https://onnx.ai/onnx/operators/index.html) 中查找 roll 算子时,我们会发现 ONNX 并没有直接实现这个算子,因此我们需要把这个算子手动拆分为 ONNX 支持的形式。
这里我参考了 [torch 导出 roll 算子](https://github.com/pytorch/pytorch/blob/d39790340db916e128b2b637cd12f4616fddb87d/torch/onnx/symbolic_opset9.py#L3261),准备将roll算子用 **Slice****Concat** 来实现。
这里我参考了 [torch 导出 roll 算子](https://github.com/pytorch/pytorch/blob/d39790340db916e128b2b637cd12f4616fddb87d/torch/onnx/symbolic_opset9.py#L3261,准备将 roll 算子用 **Slice** 和 **Concat** 来实现。
### 3.4 在 Paddle2ONNX 中新建转换文件
Expand Down Expand Up @@ -94,7 +103,7 @@ class RollMapper : public Mapper {
```
> 注:
> * Paddle2ONNX 需要实现 Opset version 7~16,如果实现的 OP 不是从 Opset version 7 开始,或者由于 Paddle OP 中的某些属性导致无法导出为ONNX,则需要重写基类中的 GetMinOpsetVersion 函数,该函数返回 -1 表示该 OP 无法导出为 ONNX,否则表示导出该 OP 所需的最小 Opset version
> *Paddle2ONNX 需要实现 Opset version 716,如果实现的 OP 不是从 Opset version 7 开始,或者由于 Paddle OP 中的某些属性导致无法导出为 ONNX,则需要重写基类中的 GetMinOpsetVersion 函数,该函数返回 -1 表示该 OP 无法导出为 ONNX,否则表示导出该 OP 所需的最小 Opset versionn
> * OpsetX 函数表示 opset version 为 x 时的转换实现函数,如果定义了 Opset7 和 Opset10 两个转换方法,意味着用户指定转出 opset version 79 时,使用 Opset7 中的转换逻辑实现转换,用户指定 opset version 1016 时,使用 Opset10 中的转换逻辑实现转换
Expand Down Expand Up @@ -277,8 +286,8 @@ class Net(BaseNet):
> **op_names**`list of str`,需要检查的 OP 名,如:["conv2d"]表示要测试的 OP 为 conv2d。
> **test_data_shapes**`list of list`,测试数据的 shape,如:[[10, 32, 10, 10], [64, 32, 3, 3]]表示第一个输入的 shape 为 [10, 32, 10, 10],第二个输入的 shape 为 [64, 32, 3, 3]。
> **test_data_types**`list of list`,测试数据的数据类型,长度必须和 `test_data_shapes` 一致,如:[[“float32“, "float64"], ["int32", "int64"]]表示第一个输入支持的数据类型为 “float32“ 和 "float64",第二个输入支持的数据类型为 "int32""int64"
> **opset_version**:`list`,表示需要测试的 opset version,只需要设置支持的最小 opset version 便可,如 [9] 表示测试opset version为 916 的转换。
> **input_spec_shape**:`list of list`,为了支持动态shape而设置,如 [[-1, 3, -1, -1],[-1, 3, -1, -1]] 表示两个输入都为动态 shape,如果不需要测试动态 shape 的转换,请直接设置为 []。
> **opset_version**`list,表示需要测试的 opset version,只需要设置支持的最小 opset version 便可,如 [9] 表示测试 opset version 为 916 的转换
> **input_spec_shape**`list of list,为了支持动态 shape 而设置,如 [[-1, 3, -1, -1],[-1, 3, -1, -1]] 表示两个输入都为动态 shape,如果不需要测试动态 shape 的转换,请直接设置为 []
4. 其他所有的参数都可以放到 config 中,然后在 Net 中取出需要的数据,同时 config 中的数据在运行单测时也会实时打印出来便于调试。
5. 返回参数 `model` 是一个 Net() 对象或者 list of Net(),list of Net() 可以实现一个单测测试多个 OP 转换,具体可参考[`test_auto_scan_unary_ops.py`](https://github.com/PaddlePaddle/Paddle2ONNX/blob/develop/tests/test_auto_scan_unary_ops.py)
Expand Down
7 changes: 6 additions & 1 deletion paddle2onnx/cpp2py_export.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "paddle2onnx/converter.h"
#include "paddle2onnx/mapper/exporter.h"
#include "paddle2onnx/optimizer/paddle2onnx_optimizer.h"

#include "paddle2onnx/mapper/register_mapper.h"
namespace paddle2onnx {

typedef std::map<std::string, std::string> CustomOpInfo;
Expand Down Expand Up @@ -95,5 +95,10 @@ PYBIND11_MODULE(paddle2onnx_cpp2py_export, m) {
ONNX_NAMESPACE::optimization::Paddle2ONNXFP32ToFP16(fp32_model_path,
fp16_model_path);
});
m.def("get_all_supported_operators", []() {

auto operators = MapperHelper::Get()->GetAllOps();
return operators;
});
}
} // namespace paddle2onnx
16 changes: 4 additions & 12 deletions paddle2onnx/mapper/register_mapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,12 @@ class MapperHelper {
return helper;
}

int64_t GetAllOps(const std::string& file_path) {
std::ofstream outfile(file_path);
if (!outfile) {
std::cerr << "Failed to open file: " << file_path << std::endl;
return mappers.size();
}
std::vector<std::string> GetAllOps() {
std::vector<std::string> operators;
for (auto iter = mappers.begin(); iter != mappers.end(); iter++) {
outfile << iter->first << std::endl;
operators.push_back(iter->first);
}
outfile << "Total OPs: " << mappers.size() << std::endl;
std::cout << " [ * Paddle2ONNX * ] All Registered OPs saved in "
<< file_path << std::endl;
outfile.close();
return mappers.size();
return operators;
}

bool IsRegistered(const std::string& op_name) {
Expand Down
5 changes: 3 additions & 2 deletions paddle2onnx/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
from __future__ import absolute_import

import importlib
import collections
import time
import os
import sys
import paddle2onnx.paddle2onnx_cpp2py_export as c_p2o

def get_all_supported_operators():
return c_p2o.get_all_supported_operators()

def try_import(module_name):
"""Try importing a module, with an informative error message on failure."""
Expand Down

0 comments on commit e58d22d

Please sign in to comment.