vision
image-detection
mathmanu commited on
Commit
91aec4c
·
verified ·
1 Parent(s): 949294c

Add rtmdet model files

Browse files
README.md ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ tags:
4
+ - vision
5
+ - image-detection
6
+ datasets:
7
+ - COCO
8
+ ---
9
+
10
+ <div align="center">
11
+
12
+ # RTMDet for TI EdgeAI
13
+
14
+ ### Real-Time Object Detector with a CSPNeXt Backbone
15
+
16
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue?style=for-the-badge)](https://opensource.org/licenses/Apache-2.0)
17
+ [![Framework](https://img.shields.io/badge/Framework-ONNX-orange?style=for-the-badge)](https://onnx.ai/)
18
+ [![Task](https://img.shields.io/badge/Task-Object%20Detection-green?style=for-the-badge)](https://github.com/TexasInstruments/edgeai)
19
+ [![Dataset](https://img.shields.io/badge/Dataset-COCO-blueviolet?style=for-the-badge)](https://cocodataset.org/)
20
+
21
+ </div>
22
+
23
+ ---
24
+
25
+ ## Overview
26
+
27
+ **RTMDet** is a high-performance real-time object detector from OpenMMLab with a CSPNeXt backbone and an efficient anchor-free detection head. It achieves excellent accuracy-speed trade-offs across five model sizes (tiny, s, m, l, x), making it suitable for a wide range of deployment scenarios from resource-constrained edge devices to high-throughput server deployments.
28
+
29
+ This RTMDet model is optimized for **Texas Instruments MPU (Microprocessor Unit) devices**, enabling high-performance computer vision applications at the edge. Whether you're building industrial automation systems, smart cameras, robotics, or IoT vision solutions, this model provides production-ready object detection with minimal setup.
30
+
31
+ ---
32
+
33
+ ## Model Variants
34
+
35
+ | Model | Input Size | mAP[.5:.95]% | Validated Devices | Config |
36
+ |-------|-----------|--------------|--------------------|--------|
37
+ | `rtmdet_tiny` | 640x640 | 40.9 | TDA4VH | [rtmdet_tiny_config.yaml](rtmdet_tiny_config.yaml) |
38
+ | `rtmdet_s` | 640x640 | 44.5 | TDA4VH | [rtmdet_s_config.yaml](rtmdet_s_config.yaml) |
39
+ | `rtmdet_m` | 640x640 | 49.3 | TDA4VH | [rtmdet_m_config.yaml](rtmdet_m_config.yaml) |
40
+ | `rtmdet_l` | 640x640 | 51.4 | TDA4VH | [rtmdet_l_config.yaml](rtmdet_l_config.yaml) |
41
+ | `rtmdet_x` | 640x640 | 52.8 | TDA4VH | [rtmdet_x_config.yaml](rtmdet_x_config.yaml) |
42
+
43
+ **Recommended for edge deployment:** `rtmdet_tiny` (smallest, best accuracy/compute trade-off)
44
+
45
+ ---
46
+
47
+ ## Quick Start
48
+
49
+ ### Prerequisites
50
+
51
+ ```bash
52
+ pip install onnx>=1.22.0
53
+ pip install onnxruntime>=1.23.2
54
+ pip install onnxsim # For model simplification
55
+ ```
56
+
57
+ ### Export the Model
58
+
59
+ ```bash
60
+ # Export all variants (default)
61
+ python prepare_model.py
62
+
63
+ # Export specific variants
64
+ python prepare_model.py --models tiny
65
+ python prepare_model.py --models tiny s m
66
+
67
+ # Export without ONNX simplification
68
+ python prepare_model.py --models tiny --no-simplify
69
+
70
+ # Force regeneration of .link files
71
+ python prepare_model.py --generate-links
72
+ ```
73
+
74
+ The script automatically:
75
+ - Installs `mmcv-lite` and `mmdet` (and other required dependencies)
76
+ - Downloads the PyTorch checkpoint referenced by each variant's `.onnx.link` file from OpenMMLab
77
+ - Downloads the matching mmdetection config files (pinned to tag `v3.3.0`)
78
+ - Builds the model with `mmdet.apis.init_detector` and wraps it to emit decoded `boxes` (xyxy) and per-class sigmoid `scores` (NMS is left for on-device post-processing)
79
+ - Exports to ONNX (opset 13), fixes the batch dimension to 1, and re-runs shape inference
80
+ - Optionally simplifies the model using `onnx-simplifier`
81
+
82
+ ### Compile and Infer uing edgeai-tidlrunner
83
+
84
+ > **Note:** Run the commands below from inside the `tidlrunner` directory (the cloned [edgeai-tidlrunner](https://github.com/TexasInstruments/edgeai-tidlrunner) repository), with `--config_path` pointing to this model's config file.
85
+
86
+ **Compile using edgeai-tidlrunner - on PC**
87
+
88
+ ```bash
89
+ cd /path/to/edgeai-tidlrunner
90
+ tidlrunner-cli compile --target_device J784S4 \
91
+ --config_path /path/to/rtmdet_tiny_config.yaml
92
+ ```
93
+
94
+ **Run Inference Benchmark - on device**
95
+
96
+ ```bash
97
+ cd /path/to/edgeai-tidlrunner
98
+ tidlrunner-cli infer --target_device J784S4 \
99
+ --config_path /path/to/rtmdet_tiny_config.yaml
100
+ ```
101
+
102
+ ### Compile and Infer using edgeai-tidl-tools (Advanced):
103
+
104
+ Follow the instructions at https://github.com/TexasInstruments/edgeai-tidl-tools
105
+
106
+ ### Deploy using edgeai-tidl-tools:
107
+
108
+ Deplyment can be done using **[edgeai-tidl-tools](https://github.com/TexasInstruments/edgeai-tidl-tools)**. For ONNX models, onnxruntime-tidl with TIDL acceleration can be used. Consult the documentation of edgeai-tidl-tools for more details.
109
+
110
+ ---
111
+
112
+ ## Citation
113
+
114
+ If you use RTMDet in your research, please cite:
115
+
116
+ ```bibtex
117
+ @article{lyu2022rtmdet,
118
+ title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},
119
+ author={Lyu, Chengqi and Zhang, Wenwei and Huang, Haian and Zhou, Yue and Wang, Yudong and Liu, Yanyi and Zhang, Shilong and Chen, Kai},
120
+ journal={arXiv preprint arXiv:2212.07784},
121
+ year={2022}
122
+ }
123
+ ```
124
+
125
+ ---
126
+
127
+ ## 🔗 Resources
128
+
129
+ | Resource | Link |
130
+ |----------|------|
131
+ | **Paper** | [arXiv:2212.07784](https://arxiv.org/abs/2212.07784) |
132
+ | **Source Code** | [open-mmlab/mmdetection (rtmdet configs)](https://github.com/open-mmlab/mmdetection/tree/main/configs/rtmdet) |
133
+ | **edgeai-tidl-tools** | [GitHub](https://github.com/TexasInstruments/edgeai-tidl-tools) |
134
+ | **edgeai-tidlrunner** | [GitHub](https://github.com/TexasInstruments/edgeai-tidlrunner) |
135
+ | **EdgeAI SDK** | [Documentation](https://github.com/TexasInstruments/edgeai/blob/main/edgeai-mpu/readme_sdk.md) |
136
+ | **EdgeAI Ecosystem** | [GitHub](https://github.com/TexasInstruments/edgeai) |
137
+
138
+ ---
139
+
140
+ ## Related Models
141
+
142
+ <table>
143
+ <tr>
144
+ <td align="center">
145
+
146
+ **YOLOX**
147
+ Anchor-free CNN detector
148
+ Similar single-stage design
149
+
150
+ </td>
151
+ <td align="center">
152
+
153
+ **YOLOv8**
154
+ CNN-based real-time detector
155
+ Comparable accuracy/speed range
156
+
157
+ </td>
158
+ <td align="center">
159
+
160
+ **YOLO11**
161
+ Latest Ultralytics YOLO
162
+ Improved efficiency
163
+
164
+ </td>
165
+ <td align="center">
166
+
167
+ **RT-DETRv2**
168
+ Real-time transformer detector
169
+ NMS-free alternative
170
+
171
+ </td>
172
+ </tr>
173
+ </table>
174
+
175
+ ---
176
+
177
+ <div align="center">
178
+
179
+ **Maintained by:** Texas Instruments EdgeAI Team
180
+ **Last Updated:** August 2026
181
+
182
+ </div>
prepare_model.py ADDED
@@ -0,0 +1,722 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script to download RTMDet models (from .link files) and convert them to ONNX.
4
+ Also capable of generating .link files for multiple variants.
5
+ Includes ONNX shape inference, simplification, and batch size fixing (like YOLOX script).
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import subprocess
11
+ import re
12
+ import importlib
13
+
14
+
15
+ def pip_install(packages: list[str], label: str = "") -> None:
16
+ """
17
+ Run pip install for the given list of package specs.
18
+ Prints captured output only on failure so the user can diagnose.
19
+
20
+ Args:
21
+ packages : List of pip install specs (e.g. ['mmcv-lite<2.2.0', 'torch']).
22
+ label : Human-readable description for log messages.
23
+ """
24
+ tag = f"[{label}]" if label else "[DEP]"
25
+ print(f"{tag} Installing: {', '.join(packages)} …")
26
+ result = subprocess.run(
27
+ [sys.executable, "-m", "pip", "install", *packages],
28
+ stdout=subprocess.PIPE,
29
+ stderr=subprocess.STDOUT,
30
+ text=True,
31
+ )
32
+ if result.returncode != 0:
33
+ print(f"{tag} ERROR: pip install failed (exit code {result.returncode}).")
34
+ print(f"{tag} --- pip output ---")
35
+ print(result.stdout)
36
+ print(f"{tag} --- end pip output ---")
37
+ sys.exit(1)
38
+ print(f"{tag} Done.\n")
39
+
40
+
41
+ def ensure_mmcv() -> None:
42
+ """
43
+ Ensure mmcv-lite<2.2.0 is installed.
44
+ mmdet requires mmcv>=2.0.0rc4,<2.2.0. We use mmcv-lite (pure-Python wheel,
45
+ no C++ compilation) which satisfies this requirement.
46
+
47
+ If an incompatible version (>=2.2.0) is already installed, it is removed first.
48
+ This must be called BEFORE mmdet is installed so mmdet doesn't pull in 2.2.0.
49
+ """
50
+ try:
51
+ import mmcv
52
+ version = mmcv.__version__
53
+ major, minor = map(int, version.split('.')[:2])
54
+ if major > 2 or (major == 2 and minor >= 2):
55
+ print(f"[DEP] mmcv {version} is incompatible (need <2.2.0) – removing …")
56
+ subprocess.run(
57
+ [sys.executable, "-m", "pip", "uninstall", "-y", "mmcv", "mmcv-lite", "mmcv-full"],
58
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
59
+ )
60
+ raise ImportError # fall through to install
61
+ print(f"[DEP] ✔ mmcv {version} is compatible.")
62
+ except ImportError:
63
+ pip_install(["mmcv-lite<2.2.0"], label="DEP")
64
+
65
+
66
+ def check_dependencies(packages: dict[str, str]) -> None:
67
+ """
68
+ Check that every package in *packages* can be imported.
69
+ Any package that is missing is installed automatically via pip.
70
+
71
+ Args:
72
+ packages : Mapping of { import_name: pip_install_name }.
73
+ """
74
+ missing: list[str] = []
75
+
76
+ for import_name, pip_name in packages.items():
77
+ try:
78
+ importlib.import_module(import_name)
79
+ print(f"[DEP] ✔ {import_name} is already installed.")
80
+ except ImportError:
81
+ print(f"[DEP] ✘ {import_name} not found – will install '{pip_name}'.")
82
+ missing.append(pip_name)
83
+
84
+ if not missing:
85
+ print("[DEP] All dependencies satisfied.\n")
86
+ return
87
+
88
+ pip_install(missing)
89
+
90
+
91
+ def download_file(url: str, save_path: str, label: str = "file") -> bool:
92
+ """
93
+ Download a single file from *url* to *save_path*.
94
+
95
+ Returns True on success, False on failure (does NOT call sys.exit so the
96
+ caller can decide whether to fall back to an alternative).
97
+
98
+ Args:
99
+ url : HTTP/HTTPS URL of the file to download.
100
+ save_path : Destination path (directories are created automatically).
101
+ label : Human-readable name used in log messages.
102
+ """
103
+ # Create the destination directory if it does not already exist
104
+ os.makedirs(os.path.dirname(save_path) or ".", exist_ok=True)
105
+
106
+ # Skip download if the file already exists
107
+ if os.path.exists(save_path):
108
+ print(f"[INFO] {label} already exists at: {save_path}")
109
+ return True
110
+
111
+ print(f"[INFO] Downloading {label} …")
112
+ print(f" URL : {url}")
113
+ print(f" Dest : {save_path}")
114
+ print()
115
+
116
+ try:
117
+ import requests
118
+ from tqdm import tqdm
119
+ resp = requests.get(url, stream=True)
120
+ resp.raise_for_status()
121
+ total = int(resp.headers.get('content-length', 0))
122
+ with open(save_path, 'wb') as file, tqdm(
123
+ desc=save_path,
124
+ total=total,
125
+ unit='iB',
126
+ unit_scale=True,
127
+ unit_divisor=1024,
128
+ ) as bar:
129
+ for data in resp.iter_content(chunk_size=1024):
130
+ size = len(data)
131
+ file.write(data)
132
+ bar.update(size)
133
+ print(f"[SUCCESS] {label} saved to: {save_path}\n")
134
+ return True
135
+ except Exception as exc:
136
+ # Remove any partial file so it is not mistaken for a complete download
137
+ if os.path.exists(save_path):
138
+ os.remove(save_path)
139
+ print(f"\n[WARN] Could not download {label}: {exc}")
140
+ return False
141
+
142
+
143
+ # mmdetection GitHub tag from which configs are downloaded
144
+ _MMDET_TAG = "v3.3.0"
145
+ _GITHUB_BASE = f"https://raw.githubusercontent.com/open-mmlab/mmdetection/{_MMDET_TAG}/configs"
146
+
147
+ # All config files required to load any RTMDet variant, with their relative
148
+ # paths inside a local "configs/" directory mirroring the GitHub layout.
149
+ _CONFIG_FILES = {
150
+ "rtmdet/rtmdet_l_8xb32-300e_coco.py": f"{_GITHUB_BASE}/rtmdet/rtmdet_l_8xb32-300e_coco.py",
151
+ "rtmdet/rtmdet_m_8xb32-300e_coco.py": f"{_GITHUB_BASE}/rtmdet/rtmdet_m_8xb32-300e_coco.py",
152
+ "rtmdet/rtmdet_s_8xb32-300e_coco.py": f"{_GITHUB_BASE}/rtmdet/rtmdet_s_8xb32-300e_coco.py",
153
+ "rtmdet/rtmdet_tiny_8xb32-300e_coco.py": f"{_GITHUB_BASE}/rtmdet/rtmdet_tiny_8xb32-300e_coco.py",
154
+ "rtmdet/rtmdet_x_8xb32-300e_coco.py": f"{_GITHUB_BASE}/rtmdet/rtmdet_x_8xb32-300e_coco.py",
155
+ "rtmdet/rtmdet_tta.py": f"{_GITHUB_BASE}/rtmdet/rtmdet_tta.py",
156
+ "_base_/default_runtime.py": f"{_GITHUB_BASE}/_base_/default_runtime.py",
157
+ "_base_/schedules/schedule_1x.py": f"{_GITHUB_BASE}/_base_/schedules/schedule_1x.py",
158
+ "_base_/datasets/coco_detection.py": f"{_GITHUB_BASE}/_base_/datasets/coco_detection.py",
159
+ }
160
+
161
+ # Config path (relative to configs/) for each variant
162
+ _VARIANT_CONFIG = {
163
+ "tiny": "rtmdet/rtmdet_tiny_8xb32-300e_coco.py",
164
+ "s": "rtmdet/rtmdet_s_8xb32-300e_coco.py",
165
+ "m": "rtmdet/rtmdet_m_8xb32-300e_coco.py",
166
+ "l": "rtmdet/rtmdet_l_8xb32-300e_coco.py",
167
+ "x": "rtmdet/rtmdet_x_8xb32-300e_coco.py",
168
+ }
169
+
170
+ CONFIGS_DIR = "configs"
171
+
172
+
173
+ def setup_configs() -> None:
174
+ """
175
+ Download all mmdetection config files needed to load RTMDet variants.
176
+
177
+ Files are stored under ./configs/ mirroring the GitHub layout so that
178
+ _base_ relative-path references resolve correctly:
179
+ configs/
180
+ _base_/
181
+ default_runtime.py
182
+ schedules/schedule_1x.py
183
+ datasets/coco_detection.py
184
+ rtmdet/
185
+ rtmdet_l_8xb32-300e_coco.py ← _base_ = ../_base_/...
186
+ rtmdet_s_8xb32-300e_coco.py ← _base_ = ./rtmdet_l...
187
+ rtmdet_m_8xb32-300e_coco.py
188
+ rtmdet_tiny_8xb32-300e_coco.py
189
+ rtmdet_tta.py
190
+ """
191
+ print("[CONFIG] Downloading mmdetection config files …")
192
+ for rel_path, url in _CONFIG_FILES.items():
193
+ dest = os.path.join(CONFIGS_DIR, rel_path)
194
+ download_file(url, dest, label=rel_path)
195
+ print("[CONFIG] All config files ready.\n")
196
+
197
+
198
+ def get_config_path(variant: str) -> str:
199
+ """Return the local filesystem path to the config file for *variant*."""
200
+ rel = _VARIANT_CONFIG[variant]
201
+ return os.path.join(CONFIGS_DIR, rel)
202
+
203
+
204
+ def get_input_shape_from_config(config_path: str) -> tuple[int, int]:
205
+ """
206
+ Extract input shape from config file.
207
+ Looks for img_scale or similar parameters.
208
+ Returns (height, width) to match PyTorch NCHW convention.
209
+ Defaults to (640, 640) if not found.
210
+ """
211
+ try:
212
+ with open(config_path, 'r') as f:
213
+ content = f.read()
214
+
215
+ # Look for common patterns - most configs specify (width, height)
216
+ patterns = [
217
+ r'img_scale\s*=\s*\((\d+),\s*(\d+)\)',
218
+ r'width\s*=\s*(\d+).*?height\s*=\s*(\d+)',
219
+ r'input_size\s*=\s*\((\d+),\s*(\d+)\)',
220
+ r'img_scale\s*=\s*\[(\d+),\s*(\d+)\]',
221
+ ]
222
+
223
+ for pattern in patterns:
224
+ match = re.search(pattern, content)
225
+ if match:
226
+ first, second = map(int, match.groups())
227
+ # Most configs use (width, height), convert to (height, width) for PyTorch
228
+ return (second, first)
229
+ except Exception as e:
230
+ print(f"Warning: Could not read config file {config_path}: {e}")
231
+
232
+ # Default input shape for RTMDet (height, width)
233
+ return (640, 640)
234
+
235
+
236
+ def fix_onnx_batch_size(onnx_path: str, batch_size: int = 1) -> None:
237
+ """
238
+ Post-process an ONNX model to hard-code the batch dimension to *batch_size*.
239
+
240
+ Some exporters (including torch.onnx.export) may leave the first dimension
241
+ of inputs/outputs as a symbolic string (e.g. 'batch') even when
242
+ dynamic_axes is not specified. This function:
243
+
244
+ 1. Loads the ONNX protobuf from *onnx_path*.
245
+ 2. Iterates over every input and output in the graph.
246
+ 3. Replaces the first dimension with the integer *batch_size*.
247
+ 4. Re-runs ONNX shape inference so downstream tools see correct shapes.
248
+ 5. Overwrites *onnx_path* with the fixed model.
249
+
250
+ Args:
251
+ onnx_path : Path to the ONNX file to fix (modified in-place).
252
+ batch_size : Integer value to set for the batch dimension (default 1).
253
+ """
254
+ import onnx # noqa: PLC0415
255
+ import onnx.shape_inference # noqa: PLC0415
256
+
257
+ print(f"[POST] Fixing batch dimension to {batch_size} in: {onnx_path}")
258
+
259
+ # Load the model from disk
260
+ model_proto = onnx.load(onnx_path)
261
+ graph = model_proto.graph
262
+
263
+ # ── Fix inputs ─────────────────���───────────────────────────────────────
264
+ for tensor in graph.input:
265
+ shape = tensor.type.tensor_type.shape
266
+ if shape.dim:
267
+ dim = shape.dim[0]
268
+ # Clear any symbolic name (e.g. "batch") and set the integer value
269
+ dim.ClearField("dim_param")
270
+ dim.dim_value = batch_size
271
+
272
+ # ── Fix outputs ────────────────────────────────────────────────────────
273
+ for tensor in graph.output:
274
+ shape = tensor.type.tensor_type.shape
275
+ if shape.dim:
276
+ dim = shape.dim[0]
277
+ dim.ClearField("dim_param")
278
+ dim.dim_value = batch_size
279
+
280
+ # Re-run shape inference so the rest of the graph reflects the fixed shape
281
+ model_proto = onnx.shape_inference.infer_shapes(model_proto)
282
+
283
+ # Overwrite the original file with the fixed model
284
+ onnx.save(model_proto, onnx_path)
285
+ print(f"[POST] Batch dimension fixed → shape now starts with {batch_size}.\n")
286
+
287
+
288
+ def _stub_mmcv_ext() -> None:
289
+ """
290
+ Stub out mmcv._ext so mmdet can be imported when only mmcv-lite is installed.
291
+
292
+ mmcv-lite is the pure-Python variant of mmcv and does not ship the compiled
293
+ C++ extension (_ext). mmdet's import chain pulls in mmcv.ops, which eagerly
294
+ loads _ext even though the ops themselves are not needed for a forward-pass /
295
+ ONNX export. Installing the full mmcv requires nvcc, which may not be
296
+ present.
297
+
298
+ The stub raises a clear RuntimeError only if one of the missing ops is
299
+ *actually called* at runtime, so normal ONNX tracing is unaffected.
300
+ """
301
+ import sys, types
302
+
303
+ if 'mmcv._ext' in sys.modules:
304
+ return # already present (real or stubbed)
305
+
306
+ import importlib.machinery
307
+
308
+ def _make_stub_op(name):
309
+ def _op(*a, **kw):
310
+ raise RuntimeError(
311
+ f"mmcv._ext.{name} was called but mmcv-lite is installed "
312
+ "(no C++ extensions). Install full mmcv if this op is required."
313
+ )
314
+ _op.__name__ = name
315
+ return _op
316
+
317
+ # Build the stub module with a valid (non-None) __spec__ so that
318
+ # pkgutil.find_loader('mmcv._ext') succeeds and returns None (loader=None),
319
+ # causing mmengine.mmcv_full_available() to correctly return False.
320
+ stub = types.ModuleType('mmcv._ext')
321
+ stub.__file__ = '<mmcv._ext stub>'
322
+ stub.__package__ = 'mmcv'
323
+ stub.__path__ = []
324
+ stub.__loader__ = None
325
+ stub.__spec__ = importlib.machinery.ModuleSpec(
326
+ 'mmcv._ext', loader=None, origin='<mmcv._ext stub>'
327
+ )
328
+
329
+ stub.__class__ = type(
330
+ '_StubExtModule',
331
+ (types.ModuleType,),
332
+ {'__getattr__': lambda self, name: _make_stub_op(name)},
333
+ )
334
+ sys.modules['mmcv._ext'] = stub
335
+
336
+
337
+ def convert_to_onnx(pth_path: str, config_path: str, onnx_path: str, input_shape: tuple[int, int] = (640, 640), simplify: bool = False) -> bool:
338
+ """
339
+ Convert PyTorch model to ONNX using MMDetection tools.
340
+ Includes shape inference, batch size fixing, and optional simplification.
341
+
342
+ Args:
343
+ input_shape: (height, width) tuple for input dimensions
344
+ """
345
+ # Stub mmcv._ext before importing mmdet so the import chain succeeds
346
+ # even when only mmcv-lite (no compiled C++ extensions) is installed.
347
+ _stub_mmcv_ext()
348
+
349
+ try:
350
+ from mmdet.apis import init_detector
351
+ import torch
352
+ except ImportError as e:
353
+ print(f"Error importing MMDetection: {e}")
354
+ print("Please ensure mmdet and mmcv are installed.")
355
+ return False
356
+
357
+ # PyTorch >=2.6 defaults torch.load to weights_only=True, which blocks
358
+ # several legacy objects (HistoryBuffer, numpy arrays) embedded in mmengine
359
+ # checkpoints. We patch torch.load to use weights_only=False for the
360
+ # duration of init_detector. The checkpoint is from a trusted source
361
+ # (download.openmmlab.com), so this is safe.
362
+ import warnings
363
+ import io
364
+ import contextlib
365
+
366
+ _orig_torch_load = torch.load
367
+ torch.load = lambda *a, **kw: _orig_torch_load(*a, **{**kw, 'weights_only': False})
368
+
369
+ # Suppress two known harmless messages from init_detector:
370
+ # 1. FutureWarning: torch.cuda.amp.autocast deprecated — issued via
371
+ # typing_extensions @deprecated on __init__, needs a persistent filter
372
+ # (not catch_warnings) because stacklevel points into mmdet modules.
373
+ # 2. "Loads checkpoint / unexpected key" — MMLogger writes to stdout;
374
+ # redirect_stdout captures it cleanly.
375
+ warnings.filterwarnings('ignore', category=FutureWarning)
376
+
377
+ try:
378
+ _captured = io.StringIO()
379
+ with contextlib.redirect_stdout(_captured):
380
+ model = init_detector(config_path, pth_path, device='cpu')
381
+ model.eval()
382
+
383
+ # Create dummy input - PyTorch uses (B, C, H, W) format
384
+ height, width = input_shape
385
+ dummy_input = torch.randn(1, 3, height, width)
386
+
387
+ # Build an export wrapper that includes the full post-processing decode:
388
+ # 1. Backbone + neck + head (mode='tensor' — raw logits + ltrb distances)
389
+ # 2. Sigmoid on cls scores
390
+ # 3. distance2bbox decode using pre-computed anchor center points (priors)
391
+ #
392
+ # NMS is intentionally omitted — it requires dynamic output shapes that are
393
+ # not supported in ONNX without custom ops, and is best run on-device after
394
+ # inference.
395
+ #
396
+ # Output:
397
+ # boxes : (1, N, 4) xyxy pixel coordinates (unclipped)
398
+ # scores : (1, N, C) per-class sigmoid probabilities
399
+ # where N = sum(H_i * W_i) over FPN levels = 8400 for a 640×640 input.
400
+ class _RTMDetDecodeWrapper(torch.nn.Module):
401
+ def __init__(self, m, input_h: int, input_w: int):
402
+ super().__init__()
403
+ self.m = m
404
+ # Pre-compute anchor center points for all FPN levels.
405
+ # Strides come from the prior generator; default RTMDet uses [8, 16, 32].
406
+ strides = [s[0] for s in m.bbox_head.prior_generator.strides]
407
+ priors_list = []
408
+ for stride in strides:
409
+ feat_h = input_h // stride
410
+ feat_w = input_w // stride
411
+ shift_x = (torch.arange(feat_w, dtype=torch.float32) + 0.5) * stride
412
+ shift_y = (torch.arange(feat_h, dtype=torch.float32) + 0.5) * stride
413
+ yy, xx = torch.meshgrid(shift_y, shift_x, indexing='ij')
414
+ priors_list.append(
415
+ torch.stack([xx.reshape(-1), yy.reshape(-1)], dim=-1)
416
+ )
417
+ # priors: (N_total, 2) — constant for a fixed input size
418
+ self.register_buffer('priors', torch.cat(priors_list, dim=0))
419
+
420
+ def forward(self, img):
421
+ feats = self.m.extract_feat(img)
422
+ cls_scores, bbox_preds = self.m.bbox_head(feats)
423
+
424
+ all_scores, all_dists = [], []
425
+ for cls_score, bbox_pred in zip(cls_scores, bbox_preds):
426
+ B = cls_score.shape[0]
427
+ # (B, C, H, W) -> (B, H*W, C)
428
+ all_scores.append(
429
+ cls_score.permute(0, 2, 3, 1).reshape(B, -1, cls_score.shape[1])
430
+ )
431
+ # (B, 4, H, W) -> (B, H*W, 4)
432
+ all_dists.append(
433
+ bbox_pred.permute(0, 2, 3, 1).reshape(B, -1, 4)
434
+ )
435
+
436
+ scores = torch.cat(all_scores, dim=1).sigmoid() # (B, N, C)
437
+ dists = torch.cat(all_dists, dim=1) # (B, N, 4)
438
+
439
+ # distance2bbox: (cx - dl, cy - dt, cx + dr, cy + db)
440
+ priors = self.priors.unsqueeze(0) # (1, N, 2)
441
+ x1 = priors[..., 0] - dists[..., 0]
442
+ y1 = priors[..., 1] - dists[..., 1]
443
+ x2 = priors[..., 0] + dists[..., 2]
444
+ y2 = priors[..., 1] + dists[..., 3]
445
+ boxes = torch.stack([x1, y1, x2, y2], dim=-1) # (B, N, 4)
446
+
447
+ return boxes, scores
448
+
449
+ export_model = _RTMDetDecodeWrapper(model, height, width)
450
+ export_model.eval()
451
+
452
+ # Dry run to confirm output shapes.
453
+ with torch.no_grad():
454
+ boxes_out, scores_out = export_model(dummy_input)
455
+ print(f"[CONV] boxes : {list(boxes_out.shape)}") # (1, 8400, 4)
456
+ print(f"[CONV] scores: {list(scores_out.shape)}") # (1, 8400, 80)
457
+
458
+ # Export to ONNX — two named outputs: boxes (xyxy) and scores (per-class sigmoid)
459
+ torch.onnx.export(
460
+ export_model,
461
+ dummy_input,
462
+ onnx_path,
463
+ export_params=True,
464
+ opset_version=13,
465
+ do_constant_folding=True,
466
+ input_names=['input'],
467
+ output_names=['boxes', 'scores'],
468
+ )
469
+ print(f"[CONV] Raw ONNX written to: {onnx_path}")
470
+
471
+ # Fix batch size to 1 (explicitly)
472
+ fix_onnx_batch_size(onnx_path, batch_size=1)
473
+
474
+ # Run shape inference
475
+ try:
476
+ import onnx
477
+ import onnx.shape_inference
478
+ print("[POST] Running ONNX shape inference …")
479
+ model_proto = onnx.load(onnx_path)
480
+ model_proto = onnx.shape_inference.infer_shapes(model_proto)
481
+ onnx.save(model_proto, onnx_path)
482
+ print("[POST] Shape inference complete – model saved.\n")
483
+ except ImportError:
484
+ print("[POST] WARNING: 'onnx' package not found – skipping shape inference.\n")
485
+ except Exception as exc:
486
+ print(f"[POST] WARNING: shape inference failed ({exc}) – model unchanged.\n")
487
+
488
+ # Optional ONNX simplification
489
+ if simplify:
490
+ try:
491
+ import onnx
492
+ import onnxsim
493
+ print("[SIMPLIFY] Simplifying model …")
494
+ model = onnx.load(onnx_path)
495
+ model_simplified, check = onnxsim.simplify(
496
+ model,
497
+ check_n=3,
498
+ perform_optimization=True,
499
+ skip_fuse_bn=False,
500
+ )
501
+ if not check:
502
+ print("[SIMPLIFY] Warning: Simplification validation failed")
503
+ else:
504
+ print("[SIMPLIFY] Simplification successful and validated")
505
+ onnx.save(model_simplified, onnx_path)
506
+ print(f"[SIMPLIFY] Simplified model saved to: {onnx_path}\n")
507
+ except ImportError:
508
+ print("[SIMPLIFY] WARNING: 'onnx-simplifier' package not found – skipping simplification.\n")
509
+ except Exception as exc:
510
+ print(f"[SIMPLIFY] WARNING: simplification failed ({exc}) – using original model.\n")
511
+
512
+ print(f"[SUCCESS] ONNX model saved to: {onnx_path}")
513
+ return True
514
+ except Exception as e:
515
+ print(f"Error during ONNX conversion: {e}")
516
+ return False
517
+ finally:
518
+ torch.load = _orig_torch_load # always restore, even on exception
519
+
520
+
521
+ def process_link_file(link_file_path: str, simplify: bool = False) -> bool:
522
+ """
523
+ Process a single .link file: download PTH and convert to ONNX.
524
+
525
+ Expected .link format (single line):
526
+ <pth_url> -o <onnx_filename>
527
+ """
528
+ with open(link_file_path, 'r') as f:
529
+ lines = [line.strip() for line in f.readlines() if line.strip()]
530
+
531
+ if not lines:
532
+ print(f"Warning: {link_file_path} is empty.")
533
+ return False
534
+
535
+ parts = lines[0].split()
536
+ if len(parts) < 3 or parts[-2] != '-o':
537
+ print(f"Warning: Unexpected format in {link_file_path}: {lines[0]}")
538
+ return False
539
+
540
+ pth_url = parts[0]
541
+ onnx_filename = parts[-1]
542
+
543
+ # Derive variant from filename: "rtmdet_tiny.onnx" → "tiny"
544
+ model_name = os.path.splitext(onnx_filename)[0] # rtmdet_tiny
545
+ variant = model_name.split('_')[1] # tiny
546
+ pth_filename = model_name + '.pth'
547
+
548
+ if variant not in _VARIANT_CONFIG:
549
+ print(f"[WARN] Cannot determine variant from filename '{onnx_filename}'. Skipping.")
550
+ return False
551
+
552
+ # Download checkpoint
553
+ if not os.path.exists(pth_filename):
554
+ if not download_file(pth_url, pth_filename, label=f"RTMDet-{variant} checkpoint"):
555
+ print(f"Failed to download checkpoint. Skipping conversion.")
556
+ return False
557
+ else:
558
+ print(f"[INFO] Checkpoint already exists: {pth_filename}")
559
+
560
+ # Resolve config path (downloaded by setup_configs)
561
+ config_path = get_config_path(variant)
562
+ if not os.path.exists(config_path):
563
+ print(f"[ERROR] Config not found: {config_path}. Run setup_configs() first.")
564
+ return False
565
+
566
+ input_shape = get_input_shape_from_config(config_path)
567
+ print(f"[INFO] Input shape: {input_shape}")
568
+
569
+ success = convert_to_onnx(pth_filename, config_path, onnx_filename, input_shape, simplify=simplify)
570
+ if success:
571
+ print(f"[SUCCESS] Conversion complete: {onnx_filename}")
572
+ else:
573
+ print(f"[ERROR] Conversion failed for {onnx_filename}")
574
+
575
+ return success
576
+
577
+
578
+ def generate_link_files(variants=None, force=False):
579
+ """
580
+ Generate .link files for RTMDet variants with correct model URLs.
581
+
582
+ Args:
583
+ variants: List of variant names. If None, uses default list.
584
+ force: If True, overwrite existing .link files.
585
+ """
586
+ if variants is None:
587
+ variants = ['tiny', 's', 'm', 'l']
588
+
589
+ base_url = "https://download.openmmlab.com/mmdetection/v3.0/rtmdet"
590
+
591
+ # Actual model URLs with correct hashes (verified from OpenMMLab)
592
+ # Format: variant -> (model_dir, checkpoint_filename)
593
+ model_info = {
594
+ 'tiny': ('rtmdet_tiny_8xb32-300e_coco', 'rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth'),
595
+ 's': ('rtmdet_s_8xb32-300e_coco', 'rtmdet_s_8xb32-300e_coco_20220905_161602-387a891e.pth'),
596
+ 'm': ('rtmdet_m_8xb32-300e_coco', 'rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth'),
597
+ 'l': ('rtmdet_l_8xb32-300e_coco', 'rtmdet_l_8xb32-300e_coco_20220719_112030-5a0be7c4.pth'),
598
+ 'x': ('rtmdet_x_8xb32-300e_coco', 'rtmdet_x_8xb32-300e_coco_20220715_230555-cc79b9ae.pth'),
599
+ }
600
+
601
+ for variant in variants:
602
+ if variant not in model_info:
603
+ print(f"[WARN] Unknown variant '{variant}' - skipping")
604
+ continue
605
+
606
+ model_dir, pth_filename = model_info[variant]
607
+ pth_url = f"{base_url}/{model_dir}/{pth_filename}"
608
+ onnx_filename = f"rtmdet_{variant}.onnx"
609
+ link_content = f"{pth_url} -o {onnx_filename}\n"
610
+
611
+ link_file = f"rtmdet_{variant}.onnx.link"
612
+
613
+ # Skip if file exists and force=False
614
+ if os.path.exists(link_file) and not force:
615
+ print(f"[INFO] {link_file} already exists (use --generate-links to regenerate)")
616
+ continue
617
+
618
+ with open(link_file, 'w') as f:
619
+ f.write(link_content)
620
+ print(f"[INFO] Generated {link_file}")
621
+
622
+
623
+ KNOWN_VARIANTS = ['tiny', 's', 'm', 'l', 'x']
624
+
625
+
626
+ def main():
627
+ """Main function."""
628
+ import argparse
629
+ parser = argparse.ArgumentParser(
630
+ description="Download RTMDet models and convert them to ONNX.",
631
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
632
+ epilog=(
633
+ "Examples:\n"
634
+ " %(prog)s # download all models\n"
635
+ " %(prog)s --models tiny s # download only tiny and s\n"
636
+ " %(prog)s --models l --simplify\n"
637
+ ),
638
+ )
639
+ parser.add_argument(
640
+ "--models",
641
+ nargs="+",
642
+ metavar="MODEL",
643
+ choices=KNOWN_VARIANTS,
644
+ default=None,
645
+ help=(
646
+ f"One or more model variants to download and convert. "
647
+ f"Choices: {KNOWN_VARIANTS}. "
648
+ f"Defaults to all variants if omitted."
649
+ ),
650
+ )
651
+ parser.add_argument(
652
+ "--simplify",
653
+ action="store_true",
654
+ default=True,
655
+ help="Simplify the ONNX model using onnx-simplifier after conversion.",
656
+ )
657
+ parser.add_argument(
658
+ "--no-simplify",
659
+ dest="simplify",
660
+ action="store_false",
661
+ help="Do not simplify the ONNX model.",
662
+ )
663
+ parser.add_argument(
664
+ "--generate-links",
665
+ action="store_true",
666
+ help="Force regeneration of .link files even if they already exist.",
667
+ )
668
+ args = parser.parse_args()
669
+
670
+ variants = args.models if args.models else KNOWN_VARIANTS
671
+ print(f"Models selected: {variants}\n")
672
+
673
+ print("Checking dependencies...")
674
+
675
+ # Stub mmcv._ext early so that importing mmdet during the dependency check
676
+ # does not fail with "No module named 'mmcv._ext'" when mmcv-lite is installed.
677
+ _stub_mmcv_ext()
678
+
679
+ # mmcv must be installed before mmdet to prevent mmdet pulling in mmcv>=2.2.0
680
+ ensure_mmcv()
681
+
682
+ check_dependencies({
683
+ 'torch': 'torch',
684
+ 'mmdet': 'mmdet',
685
+ 'requests': 'requests',
686
+ 'tqdm': 'tqdm',
687
+ 'onnx': 'onnx',
688
+ 'onnxsim': 'onnxsim',
689
+ 'onnxscript': 'onnxscript',
690
+ })
691
+
692
+ # Generate link files only for the selected models
693
+ print("\nSetting up link files for selected models...")
694
+ generate_link_files(variants, force=args.generate_links)
695
+
696
+ # Download all mmdetection config files (shared across all variants)
697
+ setup_configs()
698
+
699
+ # Process link files for the selected models only
700
+ print("\nProcessing .link files...")
701
+ link_files = sorted([
702
+ f"rtmdet_{v}.onnx.link"
703
+ for v in variants
704
+ if os.path.exists(f"rtmdet_{v}.onnx.link")
705
+ ])
706
+ if not link_files:
707
+ print("No .link files found.")
708
+ return
709
+
710
+ for link_file in link_files:
711
+ print(f"\n{'='*60}")
712
+ print(f"Processing {link_file}")
713
+ print('='*60)
714
+ process_link_file(link_file, simplify=args.simplify)
715
+
716
+ print("\n" + "="*60)
717
+ print(f"Done! Converted {len(link_files)} model(s): {', '.join(v for v in variants)}")
718
+ print("="*60)
719
+
720
+
721
+ if __name__ == "__main__":
722
+ main()
rtmdet_l.onnx.link ADDED
@@ -0,0 +1 @@
 
 
1
+ https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_l_8xb32-300e_coco/rtmdet_l_8xb32-300e_coco_20220719_112030-5a0be7c4.pth -o rtmdet_l.onnx
rtmdet_l_config.yaml ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_type: detection
2
+ dataloader:
3
+ name: coco_detection_dataloader
4
+ path: ./data/datasets/coco
5
+ preprocess:
6
+ resize: 640
7
+ crop: 640
8
+ data_layout: NCHW
9
+ reverse_channels: false
10
+ backend: cv2
11
+ interpolation: null
12
+ resize_with_pad:
13
+ - true
14
+ - corner
15
+ name: image_preprocess
16
+ pad_color:
17
+ - 114
18
+ - 114
19
+ - 114
20
+ session:
21
+ session_name: onnxrt
22
+ target_device: null
23
+ input_optimization: false
24
+ input_data_layout: NCHW
25
+ input_mean:
26
+ - 103.53
27
+ - 116.28
28
+ - 123.675
29
+ input_scale:
30
+ - 0.017429
31
+ - 0.017507
32
+ - 0.017125
33
+ model_path: rtmdet_l.onnx
34
+ model_id: od-mh8023
35
+ input_details: null
36
+ output_details: null
37
+ num_inputs: 1
38
+ postprocess:
39
+ reshape_list: null
40
+ formatter:
41
+ name: DetectionXYWH2XYXYCenterXY
42
+ resize_with_pad:
43
+ - true
44
+ - corner
45
+ normalized_detections: false
46
+ shuffle_indices: null
47
+ squeeze_axis: null
48
+ ignore_index: null
49
+ model_output_type: combined
50
+ concat_details:
51
+ axis: 2
52
+ end_index: 2
53
+ logits_bbox_to_bbox_ls:
54
+ score_fn: null
55
+ bbox_index: [0,4]
56
+ scores_index: [4,-1]
57
+ keypoint: false
58
+ object6dpose: false
59
+ name: detection_postprocess
60
+ metric:
61
+ label_offset_pred:
62
+ 0: 1
63
+ 1: 2
64
+ 2: 3
65
+ 3: 4
66
+ 4: 5
67
+ 5: 6
68
+ 6: 7
69
+ 7: 8
70
+ 8: 9
71
+ 9: 10
72
+ 10: 11
73
+ 11: 13
74
+ 12: 14
75
+ 13: 15
76
+ 14: 16
77
+ 15: 17
78
+ 16: 18
79
+ 17: 19
80
+ 18: 20
81
+ 19: 21
82
+ 20: 22
83
+ 21: 23
84
+ 22: 24
85
+ 23: 25
86
+ 24: 27
87
+ 25: 28
88
+ 26: 31
89
+ 27: 32
90
+ 28: 33
91
+ 29: 34
92
+ 30: 35
93
+ 31: 36
94
+ 32: 37
95
+ 33: 38
96
+ 34: 39
97
+ 35: 40
98
+ 36: 41
99
+ 37: 42
100
+ 38: 43
101
+ 39: 44
102
+ 40: 46
103
+ 41: 47
104
+ 42: 48
105
+ 43: 49
106
+ 44: 50
107
+ 45: 51
108
+ 46: 52
109
+ 47: 53
110
+ 48: 54
111
+ 49: 55
112
+ 50: 56
113
+ 51: 57
114
+ 52: 58
115
+ 53: 59
116
+ 54: 60
117
+ 55: 61
118
+ 56: 62
119
+ 57: 63
120
+ 58: 64
121
+ 59: 65
122
+ 60: 67
123
+ 61: 70
124
+ 62: 72
125
+ 63: 73
126
+ 64: 74
127
+ 65: 75
128
+ 66: 76
129
+ 67: 77
130
+ 68: 78
131
+ 69: 79
132
+ 70: 80
133
+ 71: 81
134
+ 72: 82
135
+ 73: 84
136
+ 74: 85
137
+ 75: 86
138
+ 76: 87
139
+ 77: 88
140
+ 78: 89
141
+ 79: 90
142
+ 80: 91
143
+ model_info:
144
+ metric_reference:
145
+ accuracy_ap[.5:.95]%: 51.4
146
+ compact_name: rtmdet-l
147
+ shortlisted: true
148
+ recommended: false
rtmdet_m.onnx.link ADDED
@@ -0,0 +1 @@
 
 
1
+ https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth -o rtmdet_m.onnx
rtmdet_m_config.yaml ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_type: detection
2
+ dataloader:
3
+ name: coco_detection_dataloader
4
+ path: ./data/datasets/coco
5
+ preprocess:
6
+ resize: 640
7
+ crop: 640
8
+ data_layout: NCHW
9
+ reverse_channels: false
10
+ backend: cv2
11
+ interpolation: null
12
+ resize_with_pad:
13
+ - true
14
+ - corner
15
+ name: image_preprocess
16
+ pad_color:
17
+ - 114
18
+ - 114
19
+ - 114
20
+ session:
21
+ session_name: onnxrt
22
+ target_device: null
23
+ input_optimization: false
24
+ input_data_layout: NCHW
25
+ input_mean:
26
+ - 103.53
27
+ - 116.28
28
+ - 123.675
29
+ input_scale:
30
+ - 0.017429
31
+ - 0.017507
32
+ - 0.017125
33
+ model_path: rtmdet_m.onnx
34
+ model_id: od-mh8022
35
+ input_details: null
36
+ output_details: null
37
+ num_inputs: 1
38
+ postprocess:
39
+ reshape_list: null
40
+ formatter:
41
+ name: DetectionXYWH2XYXYCenterXY
42
+ resize_with_pad:
43
+ - true
44
+ - corner
45
+ normalized_detections: false
46
+ shuffle_indices: null
47
+ squeeze_axis: null
48
+ ignore_index: null
49
+ model_output_type: combined
50
+ concat_details:
51
+ axis: 2
52
+ end_index: 2
53
+ logits_bbox_to_bbox_ls:
54
+ score_fn: null
55
+ bbox_index: [0,4]
56
+ scores_index: [4,-1]
57
+ keypoint: false
58
+ object6dpose: false
59
+ name: detection_postprocess
60
+ metric:
61
+ label_offset_pred:
62
+ 0: 1
63
+ 1: 2
64
+ 2: 3
65
+ 3: 4
66
+ 4: 5
67
+ 5: 6
68
+ 6: 7
69
+ 7: 8
70
+ 8: 9
71
+ 9: 10
72
+ 10: 11
73
+ 11: 13
74
+ 12: 14
75
+ 13: 15
76
+ 14: 16
77
+ 15: 17
78
+ 16: 18
79
+ 17: 19
80
+ 18: 20
81
+ 19: 21
82
+ 20: 22
83
+ 21: 23
84
+ 22: 24
85
+ 23: 25
86
+ 24: 27
87
+ 25: 28
88
+ 26: 31
89
+ 27: 32
90
+ 28: 33
91
+ 29: 34
92
+ 30: 35
93
+ 31: 36
94
+ 32: 37
95
+ 33: 38
96
+ 34: 39
97
+ 35: 40
98
+ 36: 41
99
+ 37: 42
100
+ 38: 43
101
+ 39: 44
102
+ 40: 46
103
+ 41: 47
104
+ 42: 48
105
+ 43: 49
106
+ 44: 50
107
+ 45: 51
108
+ 46: 52
109
+ 47: 53
110
+ 48: 54
111
+ 49: 55
112
+ 50: 56
113
+ 51: 57
114
+ 52: 58
115
+ 53: 59
116
+ 54: 60
117
+ 55: 61
118
+ 56: 62
119
+ 57: 63
120
+ 58: 64
121
+ 59: 65
122
+ 60: 67
123
+ 61: 70
124
+ 62: 72
125
+ 63: 73
126
+ 64: 74
127
+ 65: 75
128
+ 66: 76
129
+ 67: 77
130
+ 68: 78
131
+ 69: 79
132
+ 70: 80
133
+ 71: 81
134
+ 72: 82
135
+ 73: 84
136
+ 74: 85
137
+ 75: 86
138
+ 76: 87
139
+ 77: 88
140
+ 78: 89
141
+ 79: 90
142
+ 80: 91
143
+ model_info:
144
+ metric_reference:
145
+ accuracy_ap[.5:.95]%: 49.3
146
+ compact_name: rtmdet-m
147
+ shortlisted: true
148
+ recommended: false
rtmdet_s.onnx.link ADDED
@@ -0,0 +1 @@
 
 
1
+ https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_s_8xb32-300e_coco/rtmdet_s_8xb32-300e_coco_20220905_161602-387a891e.pth -o rtmdet_s.onnx
rtmdet_s_config.yaml ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_type: detection
2
+ dataloader:
3
+ name: coco_detection_dataloader
4
+ path: ./data/datasets/coco
5
+ preprocess:
6
+ resize: 640
7
+ crop: 640
8
+ data_layout: NCHW
9
+ reverse_channels: false
10
+ backend: cv2
11
+ interpolation: null
12
+ resize_with_pad:
13
+ - true
14
+ - corner
15
+ name: image_preprocess
16
+ pad_color:
17
+ - 114
18
+ - 114
19
+ - 114
20
+ session:
21
+ session_name: onnxrt
22
+ target_device: null
23
+ input_optimization: false
24
+ input_data_layout: NCHW
25
+ input_mean:
26
+ - 103.53
27
+ - 116.28
28
+ - 123.675
29
+ input_scale:
30
+ - 0.017429
31
+ - 0.017507
32
+ - 0.017125
33
+ model_path: rtmdet_s.onnx
34
+ model_id: od-mh8021
35
+ input_details: null
36
+ output_details: null
37
+ num_inputs: 1
38
+ postprocess:
39
+ reshape_list: null
40
+ formatter:
41
+ name: DetectionXYWH2XYXYCenterXY
42
+ resize_with_pad:
43
+ - true
44
+ - corner
45
+ normalized_detections: false
46
+ shuffle_indices: null
47
+ squeeze_axis: null
48
+ ignore_index: null
49
+ model_output_type: combined
50
+ concat_details:
51
+ axis: 2
52
+ end_index: 2
53
+ logits_bbox_to_bbox_ls:
54
+ score_fn: null
55
+ bbox_index: [0,4]
56
+ scores_index: [4,-1]
57
+ keypoint: false
58
+ object6dpose: false
59
+ name: detection_postprocess
60
+ metric:
61
+ label_offset_pred:
62
+ 0: 1
63
+ 1: 2
64
+ 2: 3
65
+ 3: 4
66
+ 4: 5
67
+ 5: 6
68
+ 6: 7
69
+ 7: 8
70
+ 8: 9
71
+ 9: 10
72
+ 10: 11
73
+ 11: 13
74
+ 12: 14
75
+ 13: 15
76
+ 14: 16
77
+ 15: 17
78
+ 16: 18
79
+ 17: 19
80
+ 18: 20
81
+ 19: 21
82
+ 20: 22
83
+ 21: 23
84
+ 22: 24
85
+ 23: 25
86
+ 24: 27
87
+ 25: 28
88
+ 26: 31
89
+ 27: 32
90
+ 28: 33
91
+ 29: 34
92
+ 30: 35
93
+ 31: 36
94
+ 32: 37
95
+ 33: 38
96
+ 34: 39
97
+ 35: 40
98
+ 36: 41
99
+ 37: 42
100
+ 38: 43
101
+ 39: 44
102
+ 40: 46
103
+ 41: 47
104
+ 42: 48
105
+ 43: 49
106
+ 44: 50
107
+ 45: 51
108
+ 46: 52
109
+ 47: 53
110
+ 48: 54
111
+ 49: 55
112
+ 50: 56
113
+ 51: 57
114
+ 52: 58
115
+ 53: 59
116
+ 54: 60
117
+ 55: 61
118
+ 56: 62
119
+ 57: 63
120
+ 58: 64
121
+ 59: 65
122
+ 60: 67
123
+ 61: 70
124
+ 62: 72
125
+ 63: 73
126
+ 64: 74
127
+ 65: 75
128
+ 66: 76
129
+ 67: 77
130
+ 68: 78
131
+ 69: 79
132
+ 70: 80
133
+ 71: 81
134
+ 72: 82
135
+ 73: 84
136
+ 74: 85
137
+ 75: 86
138
+ 76: 87
139
+ 77: 88
140
+ 78: 89
141
+ 79: 90
142
+ 80: 91
143
+ model_info:
144
+ metric_reference:
145
+ accuracy_ap[.5:.95]%: 44.5
146
+ compact_name: rtmdet-s
147
+ shortlisted: true
148
+ recommended: false
rtmdet_tiny.onnx.link ADDED
@@ -0,0 +1 @@
 
 
1
+ https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_tiny_8xb32-300e_coco/rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth -o rtmdet_tiny.onnx
rtmdet_tiny_config.yaml ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_type: detection
2
+ dataloader:
3
+ name: coco_detection_dataloader
4
+ path: ./data/datasets/coco
5
+ preprocess:
6
+ resize: 640
7
+ crop: 640
8
+ data_layout: NCHW
9
+ reverse_channels: false
10
+ backend: cv2
11
+ interpolation: null
12
+ resize_with_pad:
13
+ - true
14
+ - corner
15
+ name: image_preprocess
16
+ pad_color:
17
+ - 114
18
+ - 114
19
+ - 114
20
+ session:
21
+ session_name: onnxrt
22
+ target_device: null
23
+ input_optimization: false
24
+ input_data_layout: NCHW
25
+ input_mean:
26
+ - 103.53
27
+ - 116.28
28
+ - 123.675
29
+ input_scale:
30
+ - 0.017429
31
+ - 0.017507
32
+ - 0.017125
33
+ model_path: rtmdet_tiny.onnx
34
+ model_id: od-mh8020
35
+ input_details: null
36
+ output_details: null
37
+ num_inputs: 1
38
+ postprocess:
39
+ reshape_list: null
40
+ formatter:
41
+ name: DetectionXYWH2XYXYCenterXY
42
+ resize_with_pad:
43
+ - true
44
+ - corner
45
+ normalized_detections: false
46
+ shuffle_indices: null
47
+ squeeze_axis: null
48
+ ignore_index: null
49
+ model_output_type: combined
50
+ concat_details:
51
+ axis: 2
52
+ end_index: 2
53
+ logits_bbox_to_bbox_ls:
54
+ score_fn: null
55
+ bbox_index: [0,4]
56
+ scores_index: [4,-1]
57
+ keypoint: false
58
+ object6dpose: false
59
+ name: detection_postprocess
60
+ metric:
61
+ label_offset_pred:
62
+ 0: 1
63
+ 1: 2
64
+ 2: 3
65
+ 3: 4
66
+ 4: 5
67
+ 5: 6
68
+ 6: 7
69
+ 7: 8
70
+ 8: 9
71
+ 9: 10
72
+ 10: 11
73
+ 11: 13
74
+ 12: 14
75
+ 13: 15
76
+ 14: 16
77
+ 15: 17
78
+ 16: 18
79
+ 17: 19
80
+ 18: 20
81
+ 19: 21
82
+ 20: 22
83
+ 21: 23
84
+ 22: 24
85
+ 23: 25
86
+ 24: 27
87
+ 25: 28
88
+ 26: 31
89
+ 27: 32
90
+ 28: 33
91
+ 29: 34
92
+ 30: 35
93
+ 31: 36
94
+ 32: 37
95
+ 33: 38
96
+ 34: 39
97
+ 35: 40
98
+ 36: 41
99
+ 37: 42
100
+ 38: 43
101
+ 39: 44
102
+ 40: 46
103
+ 41: 47
104
+ 42: 48
105
+ 43: 49
106
+ 44: 50
107
+ 45: 51
108
+ 46: 52
109
+ 47: 53
110
+ 48: 54
111
+ 49: 55
112
+ 50: 56
113
+ 51: 57
114
+ 52: 58
115
+ 53: 59
116
+ 54: 60
117
+ 55: 61
118
+ 56: 62
119
+ 57: 63
120
+ 58: 64
121
+ 59: 65
122
+ 60: 67
123
+ 61: 70
124
+ 62: 72
125
+ 63: 73
126
+ 64: 74
127
+ 65: 75
128
+ 66: 76
129
+ 67: 77
130
+ 68: 78
131
+ 69: 79
132
+ 70: 80
133
+ 71: 81
134
+ 72: 82
135
+ 73: 84
136
+ 74: 85
137
+ 75: 86
138
+ 76: 87
139
+ 77: 88
140
+ 78: 89
141
+ 79: 90
142
+ 80: 91
143
+ model_info:
144
+ metric_reference:
145
+ accuracy_ap[.5:.95]%: 40.9
146
+ compact_name: rtmdet-tiny
147
+ shortlisted: true
148
+ recommended: true
rtmdet_x.onnx.link ADDED
@@ -0,0 +1 @@
 
 
1
+ https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_x_8xb32-300e_coco/rtmdet_x_8xb32-300e_coco_20220715_230555-cc79b9ae.pth -o rtmdet_x.onnx
rtmdet_x_config.yaml ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ task_type: detection
2
+ dataloader:
3
+ name: coco_detection_dataloader
4
+ path: ./data/datasets/coco
5
+ preprocess:
6
+ resize: 640
7
+ crop: 640
8
+ data_layout: NCHW
9
+ reverse_channels: false
10
+ backend: cv2
11
+ interpolation: null
12
+ resize_with_pad:
13
+ - true
14
+ - corner
15
+ name: image_preprocess
16
+ pad_color:
17
+ - 114
18
+ - 114
19
+ - 114
20
+ session:
21
+ session_name: onnxrt
22
+ target_device: null
23
+ input_optimization: false
24
+ input_data_layout: NCHW
25
+ input_mean:
26
+ - 103.53
27
+ - 116.28
28
+ - 123.675
29
+ input_scale:
30
+ - 0.017429
31
+ - 0.017507
32
+ - 0.017125
33
+ model_path: rtmdet_x.onnx
34
+ model_id: od-mh8024
35
+ input_details: null
36
+ output_details: null
37
+ num_inputs: 1
38
+ postprocess:
39
+ reshape_list: null
40
+ formatter:
41
+ name: DetectionXYWH2XYXYCenterXY
42
+ resize_with_pad:
43
+ - true
44
+ - corner
45
+ normalized_detections: false
46
+ shuffle_indices: null
47
+ squeeze_axis: null
48
+ ignore_index: null
49
+ model_output_type: combined
50
+ concat_details:
51
+ axis: 2
52
+ end_index: 2
53
+ logits_bbox_to_bbox_ls:
54
+ score_fn: null
55
+ bbox_index: [0,4]
56
+ scores_index: [4,-1]
57
+ keypoint: false
58
+ object6dpose: false
59
+ name: detection_postprocess
60
+ metric:
61
+ label_offset_pred:
62
+ 0: 1
63
+ 1: 2
64
+ 2: 3
65
+ 3: 4
66
+ 4: 5
67
+ 5: 6
68
+ 6: 7
69
+ 7: 8
70
+ 8: 9
71
+ 9: 10
72
+ 10: 11
73
+ 11: 13
74
+ 12: 14
75
+ 13: 15
76
+ 14: 16
77
+ 15: 17
78
+ 16: 18
79
+ 17: 19
80
+ 18: 20
81
+ 19: 21
82
+ 20: 22
83
+ 21: 23
84
+ 22: 24
85
+ 23: 25
86
+ 24: 27
87
+ 25: 28
88
+ 26: 31
89
+ 27: 32
90
+ 28: 33
91
+ 29: 34
92
+ 30: 35
93
+ 31: 36
94
+ 32: 37
95
+ 33: 38
96
+ 34: 39
97
+ 35: 40
98
+ 36: 41
99
+ 37: 42
100
+ 38: 43
101
+ 39: 44
102
+ 40: 46
103
+ 41: 47
104
+ 42: 48
105
+ 43: 49
106
+ 44: 50
107
+ 45: 51
108
+ 46: 52
109
+ 47: 53
110
+ 48: 54
111
+ 49: 55
112
+ 50: 56
113
+ 51: 57
114
+ 52: 58
115
+ 53: 59
116
+ 54: 60
117
+ 55: 61
118
+ 56: 62
119
+ 57: 63
120
+ 58: 64
121
+ 59: 65
122
+ 60: 67
123
+ 61: 70
124
+ 62: 72
125
+ 63: 73
126
+ 64: 74
127
+ 65: 75
128
+ 66: 76
129
+ 67: 77
130
+ 68: 78
131
+ 69: 79
132
+ 70: 80
133
+ 71: 81
134
+ 72: 82
135
+ 73: 84
136
+ 74: 85
137
+ 75: 86
138
+ 76: 87
139
+ 77: 88
140
+ 78: 89
141
+ 79: 90
142
+ 80: 91
143
+ model_info:
144
+ metric_reference:
145
+ accuracy_ap[.5:.95]%: 52.8
146
+ compact_name: rtmdet-x
147
+ shortlisted: true
148
+ recommended: false