Skip to content

Commit

Permalink
[Feature]: Add onnx2pplnn tool (open-mmlab#296)
Browse files Browse the repository at this point in the history
* Add onnx2pplnn tool

* format

* typo

* update opt-shapes and wrapper

* Update opt-shape

* Update comment

* lint
  • Loading branch information
SingleZombie committed Dec 16, 2021
1 parent f807346 commit de6fc14
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 5 deletions.
23 changes: 23 additions & 0 deletions docs/useful_tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,29 @@ def multiclass_nms(*args, **kwargs):
"""Wrapper function for `_multiclass_nms`."""
```

## onnx2pplnn

This tool helps to convert an `ONNX` model to an `PPLNN` model.

### Usage

```bash
python tools/onnx2pplnn.py \
${ONNX_PATH} \
${OUTPUT_PATH} \
--device cuda:0 \
--opt-shapes [224,224] \
--log-level INFO
```

### Description of all arguments

- `onnx_path`: The path of the `ONNX` model to convert.
- `output_path`: The converted `PPLNN` algorithm path in json format.
- `device`: The device of the model during conversion.
- `opt-shapes`: Optimal shapes for PPLNN optimization. The shape of each tensor should be wrap with "[]" or "()" and the shapes of tensors should be separated by ",".
- `--log-level`: To set log level which in `'CRITICAL', 'FATAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'`. If not specified, it will be set to `INFO`.

## onnx2tensorrt

This tool can be used to convert ONNX to TensorRT engine.
Expand Down
4 changes: 2 additions & 2 deletions mmdeploy/backend/pplnn/onnx2pplnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def onnx2pplnn(algo_file: str,
Args:
algo_file (str): File path to save PPLNN optimization algorithm.
onnx_model (str): Input onnx model.
device (str): A string specifying cuda device, defaults to 'cuda:0'.
input_shapes (Sequence[Sequence[int]] | None): shapes for PPLNN
device (str): A string specifying device, defaults to 'cuda:0'.
input_shapes (Sequence[Sequence[int]] | None): Shapes for PPLNN
optimization, default to None.
Examples:
Expand Down
3 changes: 0 additions & 3 deletions mmdeploy/backend/pplnn/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,3 @@ def __pplnn_execute(self):
status = self.runtime.Run()
assert status == pplcommon.RC_SUCCESS, 'Run() failed: ' + \
pplcommon.GetRetCodeStr(status)
status = self.runtime.Sync()
assert status == pplcommon.RC_SUCCESS, 'Sync() failed: ' + \
pplcommon.GetRetCodeStr(status)
68 changes: 68 additions & 0 deletions tools/onnx2pplnn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import collections
import logging

from mmdeploy.apis.pplnn import onnx2pplnn


def parse_args():
parser = argparse.ArgumentParser(description='Convert ONNX to PPLNN.')
parser.add_argument('onnx_path', help='ONNX model path')
parser.add_argument(
'output_path', help='output PPLNN algorithm path in json format')
parser.add_argument(
'--device',
help='`the device of model during conversion',
default='cuda:0')
parser.add_argument(
'--opt-shapes',
help='`Optical shapes for PPLNN optimization. The shapes must be able'
'to be evaluated by python, e,g., `[1, 3, 224, 224]`',
default='[1, 3, 224, 224]')
parser.add_argument(
'--log-level',
help='set log level',
default='INFO',
choices=list(logging._nameToLevel.keys()))
args = parser.parse_args()

return args


def main():
args = parse_args()
logging.basicConfig(
format='%(asctime)s,%(name)s %(levelname)-8s'
' [%(filename)s:%(lineno)d] %(message)s',
datefmt='%Y-%m-%d:%H:%M:%S')
logger = logging.getLogger()
logger.setLevel(args.log_level)

onnx_path = args.onnx_path
output_path = args.output_path
device = args.device

input_shapes = eval(args.opt_shapes)
assert isinstance(
input_shapes, collections.Sequence), \
'The opt-shape must be a sequence.'
assert isinstance(input_shapes[0], int) or (isinstance(
input_shapes[0], collections.Sequence)), \
'The opt-shape must be a sequence of int or a sequence of sequence.'
if isinstance(input_shapes[0], int):
input_shapes = [input_shapes]

logging.info(f'onnx2ppl: \n\tonnx_path: {onnx_path} '
f'\n\toutput_path: {output_path}'
f'\n\topt_shapes: {input_shapes}')
try:
onnx2pplnn(output_path, onnx_path, device, input_shapes)
logging.info('onnx2tpplnn success.')
except Exception as e:
logging.error(e)
logging.error('onnx2tpplnn failed.')


if __name__ == '__main__':
main()

0 comments on commit de6fc14

Please sign in to comment.