2021-12-03 15:12:40 +08:00
## ONNX Runtime Deployment
2020-12-23 11:03:55 +08:00
2022-03-01 15:07:07 +08:00
### <span style="color:red">DeprecationWarning</span>
ONNX support will be deprecated in the future.
Welcome to use the unified model deployment toolbox MMDeploy: https://github.com/open-mmlab/mmdeploy
2021-09-24 16:57:20 +08:00
### Introduction of ONNX Runtime
2020-12-23 11:03:55 +08:00
**ONNX Runtime** is a cross-platform inferencing and training accelerator compatible with many popular ML/DNN frameworks. Check its [github ](https://github.com/microsoft/onnxruntime ) for more information.
2021-09-24 16:57:20 +08:00
### Introduction of ONNX
2020-12-23 11:03:55 +08:00
**ONNX** stands for **Open Neural Network Exchange** , which acts as *Intermediate Representation(IR)* for ML/DNN models from many frameworks. Check its [github ](https://github.com/onnx/onnx ) for more information.
2021-09-24 16:57:20 +08:00
### Why include custom operators for ONNX Runtime in MMCV
2020-12-23 11:03:55 +08:00
- To verify the correctness of exported ONNX models in ONNX Runtime.
- To ease the deployment of ONNX models with custom operators from `mmcv.ops` in ONNX Runtime.
2021-09-24 16:57:20 +08:00
### List of operators for ONNX Runtime supported in MMCV
2020-12-23 11:03:55 +08:00
2021-12-03 15:12:40 +08:00
| Operator | CPU | GPU | MMCV Releases |
2022-05-16 20:47:56 +08:00
| :----------------------------------------------------- | :-: | :-: | :-----------: |
2021-12-03 15:12:40 +08:00
| [SoftNMS ](onnxruntime_custom_ops.md#softnms ) | Y | N | 1.2.3 |
| [RoIAlign ](onnxruntime_custom_ops.md#roialign ) | Y | N | 1.2.5 |
| [NMS ](onnxruntime_custom_ops.md#nms ) | Y | N | 1.2.7 |
| [grid_sampler ](onnxruntime_custom_ops.md#grid_sampler ) | Y | N | 1.3.1 |
| [CornerPool ](onnxruntime_custom_ops.md#cornerpool ) | Y | N | 1.3.4 |
| [cummax ](onnxruntime_custom_ops.md#cummax ) | Y | N | 1.3.4 |
| [cummin ](onnxruntime_custom_ops.md#cummin ) | Y | N | 1.3.4 |
2020-12-23 11:03:55 +08:00
2021-09-24 16:57:20 +08:00
### How to build custom operators for ONNX Runtime
2020-12-23 11:03:55 +08:00
2021-08-23 23:31:23 +08:00
*Please be noted that only **onnxruntime>=1.8.1** of CPU version on Linux platform is tested by now.*
2020-12-23 11:03:55 +08:00
2021-09-24 16:57:20 +08:00
#### Prerequisite
2020-12-23 11:03:55 +08:00
- Clone repository
```bash
git clone https://github.com/open-mmlab/mmcv.git
```
2021-08-23 23:31:23 +08:00
- Download `onnxruntime-linux` from ONNX Runtime [releases ](https://github.com/microsoft/onnxruntime/releases/tag/v1.8.1 ), extract it, expose `ONNXRUNTIME_DIR` and finally add the lib path to `LD_LIBRARY_PATH` as below:
2020-12-23 11:03:55 +08:00
```bash
2021-08-23 23:31:23 +08:00
wget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-1.8.1.tgz
2020-12-23 11:03:55 +08:00
2021-08-23 23:31:23 +08:00
tar -zxvf onnxruntime-linux-x64-1.8.1.tgz
cd onnxruntime-linux-x64-1.8.1
2020-12-23 11:03:55 +08:00
export ONNXRUNTIME_DIR=$(pwd)
export LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH
```
2021-09-24 16:57:20 +08:00
#### Build on Linux
2020-12-23 11:03:55 +08:00
```bash
2021-09-24 16:57:20 +08:00
cd mmcv ## to MMCV root directory
2021-08-23 23:31:23 +08:00
MMCV_WITH_OPS=1 MMCV_WITH_ORT=1 python setup.py develop
2020-12-23 11:03:55 +08:00
```
2021-09-24 16:57:20 +08:00
### How to do inference using exported ONNX models with custom operators in ONNX Runtime in python
2020-12-23 11:03:55 +08:00
Install ONNX Runtime with `pip`
```bash
2021-08-23 23:31:23 +08:00
pip install onnxruntime==1.8.1
2020-12-23 11:03:55 +08:00
```
Inference Demo
```python
import os
import numpy as np
import onnxruntime as ort
from mmcv.ops import get_onnxruntime_op_path
ort_custom_op_path = get_onnxruntime_op_path()
assert os.path.exists(ort_custom_op_path)
session_options = ort.SessionOptions()
session_options.register_custom_ops_library(ort_custom_op_path)
2021-09-24 16:57:20 +08:00
## exported ONNX model with custom operators
2020-12-23 11:03:55 +08:00
onnx_file = 'sample.onnx'
input_data = np.random.randn(1, 3, 224, 224).astype(np.float32)
sess = ort.InferenceSession(onnx_file, session_options)
onnx_results = sess.run(None, {'input' : input_data})
```
2021-09-24 16:57:20 +08:00
### How to add a new custom operator for ONNX Runtime in MMCV
2020-12-23 11:03:55 +08:00
2021-09-24 16:57:20 +08:00
#### Reminder
2020-12-23 11:03:55 +08:00
2021-12-03 15:12:40 +08:00
- *Please note that this feature is experimental and may change in the future. Strongly suggest users always try with the latest master branch.*
2020-12-23 11:03:55 +08:00
- The custom operator is not included in [supported operator list ](https://github.com/microsoft/onnxruntime/blob/master/docs/OperatorKernels.md ) in ONNX Runtime.
2022-05-16 20:47:56 +08:00
2020-12-23 11:03:55 +08:00
- The custom operator should be able to be exported to ONNX.
2021-09-24 16:57:20 +08:00
#### Main procedures
2020-12-23 11:03:55 +08:00
Take custom operator `soft_nms` for example.
1. Add header `soft_nms.h` to ONNX Runtime include directory `mmcv/ops/csrc/onnxruntime/`
2022-05-16 20:47:56 +08:00
2020-12-23 11:03:55 +08:00
2. Add source `soft_nms.cpp` to ONNX Runtime source directory `mmcv/ops/csrc/onnxruntime/cpu/`
2022-05-16 20:47:56 +08:00
2021-08-23 23:31:23 +08:00
3. Register `soft_nms` operator in [onnxruntime_register.cpp ](../../mmcv/ops/csrc/onnxruntime/cpu/onnxruntime_register.cpp )
2020-12-23 11:03:55 +08:00
2022-05-16 20:47:56 +08:00
```c++
#include "soft_nms.h"
2020-12-23 11:03:55 +08:00
2022-05-16 20:47:56 +08:00
SoftNmsOp c_SoftNmsOp;
2020-12-23 11:03:55 +08:00
2022-05-16 20:47:56 +08:00
if (auto status = ortApi->CustomOpDomain_Add(domain, & c_SoftNmsOp)) {
return status;
}
```
2020-12-23 11:03:55 +08:00
4. Add unit test into `tests/test_ops/test_onnx.py`
2021-08-23 23:31:23 +08:00
Check [here ](../../tests/test_ops/test_onnx.py ) for examples.
2020-12-23 11:03:55 +08:00
**Finally, welcome to send us PR of adding custom operators for ONNX Runtime in MMCV.** :nerd_face:
2021-09-24 16:57:20 +08:00
### Known Issues
2020-12-23 11:03:55 +08:00
2021-05-10 21:33:27 +08:00
- "RuntimeError: tuple appears in op that does not forward tuples, unsupported kind: `prim::PythonOp` ."
2022-05-16 20:47:56 +08:00
1. Note generally `cummax` or `cummin` is exportable to ONNX as long as the torch version >= 1.5.0, since `torch.cummax` is only supported with torch >= 1.5.0. But when `cummax` or `cummin` serves as an intermediate component whose outputs is used as inputs for another modules, it's expected that torch version must be >= 1.7.0. Otherwise the above error might arise, when running exported ONNX model with onnxruntime.
2. Solution: update the torch version to 1.7.0 or higher.
2020-12-23 11:03:55 +08:00
2021-09-24 16:57:20 +08:00
### References
2020-12-23 11:03:55 +08:00
- [How to export Pytorch model with custom op to ONNX and run it in ONNX Runtime ](https://github.com/onnx/tutorials/blob/master/PyTorchCustomOperator/README.md )
- [How to add a custom operator/kernel in ONNX Runtime ](https://github.com/microsoft/onnxruntime/blob/master/docs/AddingCustomOp.md )