onnxruntime_op.md 5.4 KB
Newer Older
RunningLeon's avatar
RunningLeon committed
1
## ONNX Runtime Deployment
2

3
4
5
6
7
### <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

8
### Introduction of ONNX Runtime
9
10
11

**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.

12
### Introduction of ONNX
13
14
15

**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.

16
### Why include custom operators for ONNX Runtime in MMCV
17
18
19
20

- 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.

21
### List of operators for ONNX Runtime supported in MMCV
22

RunningLeon's avatar
RunningLeon committed
23
| Operator                                               | CPU | GPU | MMCV Releases |
24
| :----------------------------------------------------- | :-: | :-: | :-----------: |
RunningLeon's avatar
RunningLeon committed
25
26
27
28
29
30
31
| [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     |
32

33
### How to build custom operators for ONNX Runtime
34

35
*Please be noted that only **onnxruntime>=1.8.1** of CPU version on Linux platform is tested by now.*
36

37
#### Prerequisite
38
39
40
41
42
43
44

- Clone repository

```bash
git clone https://github.com/open-mmlab/mmcv.git
```

45
- 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:
46
47

```bash
48
wget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-1.8.1.tgz
49

50
51
tar -zxvf onnxruntime-linux-x64-1.8.1.tgz
cd onnxruntime-linux-x64-1.8.1
52
53
54
55
export ONNXRUNTIME_DIR=$(pwd)
export LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH
```

56
#### Build on Linux
57
58

```bash
59
cd mmcv ## to MMCV root directory
60
MMCV_WITH_OPS=1 MMCV_WITH_ORT=1 python setup.py develop
61
62
```

63
### How to do inference using exported ONNX models with custom operators in ONNX Runtime in python
64
65
66
67

Install ONNX Runtime with `pip`

```bash
68
pip install onnxruntime==1.8.1
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
```

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)
85
## exported ONNX model with custom operators
86
87
88
89
90
91
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})
```

92
### How to add a new custom operator for ONNX Runtime in MMCV
93

94
#### Reminder
95

RunningLeon's avatar
RunningLeon committed
96
97
- *Please note that this feature is experimental and may change in the future. Strongly suggest users always try with the latest master branch.*

98
- The custom operator is not included in [supported operator list](https://github.com/microsoft/onnxruntime/blob/master/docs/OperatorKernels.md) in ONNX Runtime.
99

100
101
- The custom operator should be able to be exported to ONNX.

102
#### Main procedures
103
104
105
106

Take custom operator `soft_nms` for example.

1. Add header `soft_nms.h` to ONNX Runtime include directory `mmcv/ops/csrc/onnxruntime/`
107

108
2. Add source `soft_nms.cpp` to ONNX Runtime source directory `mmcv/ops/csrc/onnxruntime/cpu/`
109

110
3. Register `soft_nms` operator in [onnxruntime_register.cpp](../../../mmcv/ops/csrc/onnxruntime/cpu/onnxruntime_register.cpp)
111

112
113
   ```c++
   #include "soft_nms.h"
114

115
   SoftNmsOp c_SoftNmsOp;
116

117
118
119
120
   if (auto status = ortApi->CustomOpDomain_Add(domain, &c_SoftNmsOp)) {
   return status;
   }
   ```
121
122

4. Add unit test into `tests/test_ops/test_onnx.py`
123
   Check [here](../../tests/test_ops/test_onnx.py) for examples.
124
125
126

**Finally, welcome to send us PR of adding custom operators for ONNX Runtime in MMCV.** :nerd_face:

127
### Known Issues
128

129
- "RuntimeError: tuple appears in op that does not forward tuples, unsupported kind: `prim::PythonOp`."
130
131
  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.
132

133
### References
134
135

- [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)
136
- [How to add a custom operator/kernel in ONNX Runtime](https://onnxruntime.ai/docs/reference/operators/add-custom-op.html)