Skip to content

Commit ba1c0db

Browse files
authored
RKNN conversion tool (#2024)
1 parent fce54d1 commit ba1c0db

File tree

4 files changed

+712
-0
lines changed

4 files changed

+712
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Notebook
2+
3+
In the first cell of the RKNN conversion notebook, the installation script uses a structured list of dictionaries to define the download URLs and filenames for required scripts. Each dictionary includes a `url` (a permalink to a specific commit) and the corresponding `filename`.
4+
5+
Please ensure that all URLs in this array use permalinks—that is, links pointing to a specific commit hash rather than a branch name (e.g., main). This guarantees that the correct version of each script is always fetched, and prevents unexpected changes if the repository is updated in the future.
6+
7+
You typically won’t need to update these permalinks unless one of the referenced scripts is modified. In that case, update the commit hash in the URLs accordingly.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import argparse
2+
import os.path
3+
import subprocess
4+
import sys
5+
6+
# This will work for all models that don't use anchors (e.g. all YOLO models except YOLOv5/v7)
7+
# This includes YOLOv5u
8+
yolo_non_anchor_repo = "https://github.com/airockchip/ultralytics_yolo11"
9+
10+
# For original YOLOv5 models
11+
yolov5_repo = "https://github.com/airockchip/yolov5"
12+
13+
valid_yolo_versions = ["yolov5", "yolov8", "yolov11"]
14+
comma_sep_yolo_versions = ", ".join(valid_yolo_versions)
15+
16+
ultralytics_folder_name_yolov5 = "airockchip_yolo_pkg_yolov5"
17+
ultralytics_default_folder_name = "airockchip_yolo_pkg"
18+
19+
20+
bad_model_msg = """
21+
This is usually due to passing in the wrong model version.
22+
Please make sure you have the right model version and try again.
23+
"""
24+
25+
26+
# idk how else to make Google Colab display this nicely
27+
class IncorrectModelError(Exception):
28+
def __init__(self, message):
29+
self.message = message
30+
super().__init__(self.message)
31+
32+
33+
def print_bad_model_msg(cause):
34+
print(f"{cause}{bad_model_msg}")
35+
36+
37+
def check_git_installed():
38+
try:
39+
subprocess.run(["git", "--version"]).check_returncode()
40+
except:
41+
print("Git is not installed or not found in your PATH.")
42+
print("Please install Git from https://git-scm.com/downloads and try again.")
43+
sys.exit(1)
44+
45+
46+
def check_or_clone_rockchip_repo(repo_url, repo_name=ultralytics_default_folder_name):
47+
if os.path.exists(repo_name):
48+
print(
49+
f'Existing Rockchip repo "{repo_name}" detected, skipping installation...'
50+
)
51+
else:
52+
print(f'Cloning Rockchip repo to "{repo_name}"')
53+
try:
54+
subprocess.run(["git", "clone", repo_url, repo_name]).check_returncode()
55+
except subprocess.CalledProcessError as e:
56+
print("Failed to clone Rockchip repo, see error output below")
57+
print(e.output)
58+
sys.exit(1)
59+
60+
61+
def run_pip_install_or_else_exit(args):
62+
print("Running pip install...")
63+
64+
try:
65+
subprocess.run(["pip", "install"] + args).check_returncode()
66+
except subprocess.CalledProcessError as e:
67+
print("Pip install rockchip repo failed, see error output")
68+
print(e.output)
69+
sys.exit(1)
70+
71+
72+
def run_onnx_conversion_yolov5(model_path):
73+
check_or_clone_rockchip_repo(yolov5_repo, ultralytics_folder_name_yolov5)
74+
run_pip_install_or_else_exit(
75+
[
76+
"-r",
77+
os.path.join(ultralytics_folder_name_yolov5, "requirements.txt"),
78+
"torch<2.6.0",
79+
"onnx",
80+
]
81+
)
82+
83+
model_abspath = os.path.abspath(model_path)
84+
85+
try:
86+
subprocess.run(
87+
[
88+
"python",
89+
f"{ultralytics_folder_name_yolov5}/export.py",
90+
"--weights",
91+
model_abspath,
92+
"--rknpu",
93+
"--include",
94+
"onnx",
95+
],
96+
capture_output=True,
97+
text=True,
98+
).check_returncode()
99+
except subprocess.CalledProcessError as e:
100+
print("Failed to run YOLOv5 export, see output below")
101+
output_string = (e.stdout or "") + (e.stderr or "")
102+
print(output_string)
103+
104+
if "ModuleNotFoundError" in output_string and "ultralytics" in output_string:
105+
print_bad_model_msg(
106+
"It seems the YOLOv5 repo could not find an ultralytics installation."
107+
)
108+
elif (
109+
"AttributeError" in output_string
110+
and "_register_detect_seperate" in output_string
111+
):
112+
print_bad_model_msg("It seems that you received a model attribute error.")
113+
114+
sys.exit(1)
115+
116+
117+
def run_onnx_conversion_no_anchor(model_path):
118+
check_or_clone_rockchip_repo(yolo_non_anchor_repo)
119+
run_pip_install_or_else_exit(["-e", ultralytics_default_folder_name, "onnx"])
120+
121+
sys.path.insert(0, os.path.abspath(ultralytics_default_folder_name))
122+
model_abs_path = os.path.abspath(model_path)
123+
124+
from ultralytics import YOLO
125+
126+
try:
127+
model = YOLO(model_abs_path)
128+
model.export(format="rknn")
129+
except TypeError as e:
130+
if "originally trained" in str(e):
131+
print_bad_model_msg(
132+
"Ultralytics has detected that this model is a YOLOv5 model."
133+
)
134+
else:
135+
print(e)
136+
137+
sys.exit(1)
138+
139+
140+
if __name__ == "__main__":
141+
parser = argparse.ArgumentParser(
142+
description="Generate valid ONNX file for yolo model"
143+
)
144+
145+
parser.add_argument(
146+
"-m",
147+
"--model_path",
148+
required=True,
149+
help=(f"Path to YOLO model"),
150+
)
151+
152+
parser.add_argument(
153+
"-v",
154+
"--version",
155+
required=True,
156+
choices=valid_yolo_versions,
157+
help=(f"Model version, must be one of: {comma_sep_yolo_versions}"),
158+
)
159+
160+
args = parser.parse_args()
161+
162+
check_git_installed()
163+
164+
try:
165+
if args.version.lower() == "yolov5":
166+
run_onnx_conversion_yolov5(args.model_path)
167+
else:
168+
run_onnx_conversion_no_anchor(args.model_path)
169+
170+
print(
171+
"Model export finished. Please use the generated ONNX file to convert to RKNN."
172+
)
173+
except SystemExit:
174+
print("Model export failed. Please see output above.")

0 commit comments

Comments
 (0)