Skip to content

Commit 4da1401

Browse files
authored
Feature: rt-detrv2 onnx model can convert tensorrt (#588)
* chore: Add missing module requirements - scipy and pycocotools * chore: add module - onnx * fix: Disable assert statement - When checking data type, (self.bindings[n].data.dtype == blob[n].dtype) * chore: add module and check version - add onnxruntime, tensorrt - check version: torch, torchvision, faster-coco-eval * feat: export TensorRT in rt-detrv2 - build onnx to TensorRT * chore: typo * docs: add hint about export tensorrt in rtdetrv2-pytorch * feat: Add Dockerfile for building a Docker image - use command "docker compose up -d" * fix: del onnx2tensorrt method * revert: update package versions in requirements.txt
1 parent d977575 commit 4da1401

File tree

6 files changed

+123
-12
lines changed

6 files changed

+123
-12
lines changed

rtdetrv2_pytorch/Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# tensorrt:23.01-py3 (8.5.2.2)
2+
FROM nvcr.io/nvidia/tensorrt:23.01-py3
3+
4+
WORKDIR /workspace
5+
6+
COPY requirements.txt .
7+
8+
RUN pip install --upgrade pip && \
9+
pip install -r requirements.txt
10+
11+
CMD ["/bin/bash"]

rtdetrv2_pytorch/README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,13 @@ CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun --master_port=9909 --nproc_per_node=4 tool
120120
python tools/export_onnx.py -c path/to/config -r path/to/checkpoint --check
121121
```
122122

123-
<!-- <summary>5. Inference </summary> -->
123+
<!-- <summary>5. Export tensorrt </summary> -->
124+
5. Export tensorrt
125+
```shell
126+
python tools/export_trt.py -i path/to/onnxfile
127+
```
128+
129+
<!-- <summary>6. Inference </summary> -->
124130
5. Inference
125131

126132
Support torch, onnxruntime, tensorrt and openvino, see details in *references/deploy*
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: "3.9"
2+
3+
services:
4+
tensorrt-container:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
image: rtdetr-v2:23.01
9+
volumes:
10+
- ./:/workspace
11+
runtime: nvidia
12+
environment:
13+
- NVIDIA_VISIBLE_DEVICES=all
14+
stdin_open: true
15+
tty: true

rtdetrv2_pytorch/references/deploy/rtdetrv2_tensorrt.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88

99
import numpy as np
1010
from PIL import Image, ImageDraw
11+
import tensorrt as trt
1112

1213
import torch
1314
import torchvision.transforms as T
1415

15-
import tensorrt as trt
16+
1617

1718

1819
class TimeProfiler(contextlib.ContextDecorator):
@@ -124,10 +125,10 @@ def run_torch(self, blob):
124125
self.context.set_input_shape(n, blob[n].shape)
125126
self.bindings[n] = self.bindings[n]._replace(shape=blob[n].shape)
126127

127-
# TODO (lyuwenyu): check dtype,
128-
assert self.bindings[n].data.dtype == blob[n].dtype, '{} dtype mismatch'.format(n)
129-
# if self.bindings[n].data.dtype != blob[n].shape:
130-
# blob[n] = blob[n].to(self.bindings[n].data.dtype)
128+
# TODO (lyuwenyu): check dtype,
129+
# assert self.bindings[n].data.dtype == blob[n].dtype, '{} dtype mismatch'.format(n)
130+
if self.bindings[n].data.dtype != blob[n].shape:
131+
blob[n] = blob[n].to(self.bindings[n].data.dtype)
131132

132133
self.bindings_addr.update({n: blob[n].data_ptr() for n in self.input_names})
133134
self.context.execute_v2(list(self.bindings_addr.values()))
@@ -180,11 +181,6 @@ def speed(self, blob, n):
180181

181182
return self.time_profile.total / n
182183

183-
184-
@staticmethod
185-
def onnx2tensorrt():
186-
pass
187-
188184
def draw(images, labels, boxes, scores, thrh = 0.6):
189185
for i, im in enumerate(images):
190186
draw = ImageDraw.Draw(im)

rtdetrv2_pytorch/requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ PyYAML
55
tensorboard
66
scipy
77
pycocotools
8-
onnx
8+
onnx
9+
onnxruntime-gpu
10+
tensorrt==8.5.2.2
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import os
2+
import argparse
3+
import tensorrt as trt
4+
5+
def main(onnx_path, engine_path, max_batchsize, opt_batchsize, min_batchsize, use_fp16=True, verbose=False)->None:
6+
""" Convert ONNX model to TensorRT engine.
7+
Args:
8+
onnx_path (str): Path to the input ONNX model.
9+
engine_path (str): Path to save the output TensorRT engine.
10+
use_fp16 (bool): Whether to use FP16 precision.
11+
verbose (bool): Whether to enable verbose logging.
12+
"""
13+
logger = trt.Logger(trt.Logger.VERBOSE if verbose else trt.Logger.INFO)
14+
15+
builder = trt.Builder(logger)
16+
network_flags = 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
17+
network = builder.create_network(network_flags)
18+
19+
parser = trt.OnnxParser(network, logger)
20+
config = builder.create_builder_config()
21+
config.set_preview_feature(trt.PreviewFeature.FASTER_DYNAMIC_SHAPES_0805, True)
22+
23+
if not os.path.isfile(onnx_path):
24+
raise FileNotFoundError(f"ONNX file not found: {onnx_path}")
25+
26+
print(f"[INFO] Loading ONNX file from {onnx_path}")
27+
with open(onnx_path, "rb") as f:
28+
if not parser.parse(f.read()):
29+
for error in range(parser.num_errors):
30+
print(parser.get_error(error))
31+
raise RuntimeError("Failed to parse ONNX file")
32+
33+
config = builder.create_builder_config()
34+
config.set_preview_feature(trt.PreviewFeature.FASTER_DYNAMIC_SHAPES_0805, True)
35+
config.max_workspace_size = 1 << 30 # 1GB
36+
37+
if use_fp16:
38+
if builder.platform_has_fast_fp16:
39+
config.set_flag(trt.BuilderFlag.FP16)
40+
print("[INFO] FP16 optimization enabled.")
41+
else:
42+
print("[WARNING] FP16 not supported on this platform. Proceeding with FP32.")
43+
44+
profile = builder.create_optimization_profile()
45+
profile.set_shape("images", min=(min_batchsize, 3, 640, 640), opt=(opt_batchsize, 3, 640, 640), max=(max_batchsize, 3, 640, 640))
46+
profile.set_shape("orig_target_sizes", min=(1, 2), opt=(1, 2), max=(1, 2))
47+
config.add_optimization_profile(profile)
48+
49+
print("[INFO] Building TensorRT engine...")
50+
engine = builder.build_engine(network, config)
51+
52+
if engine is None:
53+
raise RuntimeError("Failed to build the engine.")
54+
55+
print(f"[INFO] Saving engine to {engine_path}")
56+
with open(engine_path, "wb") as f:
57+
f.write(engine.serialize())
58+
print("[INFO] Engine export complete.")
59+
60+
61+
if __name__ == "__main__":
62+
parser = argparse.ArgumentParser(description="Convert ONNX to TensorRT Engine")
63+
parser.add_argument("--onnx", "-i", type=str, required=True, help="Path to input ONNX model file")
64+
parser.add_argument("--saveEngine", "-o", type=str, default="model.engine", help="Path to output TensorRT engine file")
65+
parser.add_argument("--maxBatchSize", "-Mb", type=int, default=32, help="Maximum batch size for inference")
66+
parser.add_argument("--optBatchSize", "-ob", type=int, default=16, help="Optimal batch size for inference")
67+
parser.add_argument("--minBatchSize", "-mb", type=int, default=1, help="Minimum batch size for inference")
68+
parser.add_argument("--fp16", default=True, action="store_true", help="Enable FP16 precision mode")
69+
parser.add_argument("--verbose", action="store_true", help="Enable verbose logging")
70+
71+
args = parser.parse_args()
72+
73+
main(
74+
onnx_path=args.onnx,
75+
engine_path=args.saveEngine,
76+
max_batchsize=args.maxBatchSize,
77+
opt_batchsize=args.optBatchSize,
78+
min_batchsize=args.minBatchSize,
79+
use_fp16=args.fp16,
80+
verbose=args.verbose
81+
)

0 commit comments

Comments
 (0)