ultralytics 8.1.28__py3-none-any.whl → 8.3.62__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. tests/__init__.py +22 -0
  2. tests/conftest.py +83 -0
  3. tests/test_cli.py +122 -0
  4. tests/test_cuda.py +155 -0
  5. tests/test_engine.py +131 -0
  6. tests/test_exports.py +216 -0
  7. tests/test_integrations.py +150 -0
  8. tests/test_python.py +615 -0
  9. tests/test_solutions.py +94 -0
  10. ultralytics/__init__.py +11 -8
  11. ultralytics/cfg/__init__.py +569 -131
  12. ultralytics/cfg/datasets/Argoverse.yaml +2 -1
  13. ultralytics/cfg/datasets/DOTAv1.5.yaml +3 -2
  14. ultralytics/cfg/datasets/DOTAv1.yaml +3 -2
  15. ultralytics/cfg/datasets/GlobalWheat2020.yaml +3 -2
  16. ultralytics/cfg/datasets/ImageNet.yaml +2 -1
  17. ultralytics/cfg/datasets/Objects365.yaml +5 -4
  18. ultralytics/cfg/datasets/SKU-110K.yaml +2 -1
  19. ultralytics/cfg/datasets/VOC.yaml +3 -2
  20. ultralytics/cfg/datasets/VisDrone.yaml +6 -5
  21. ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
  22. ultralytics/cfg/datasets/brain-tumor.yaml +23 -0
  23. ultralytics/cfg/datasets/carparts-seg.yaml +3 -2
  24. ultralytics/cfg/datasets/coco-pose.yaml +7 -6
  25. ultralytics/cfg/datasets/coco.yaml +3 -2
  26. ultralytics/cfg/datasets/coco128-seg.yaml +4 -3
  27. ultralytics/cfg/datasets/coco128.yaml +4 -3
  28. ultralytics/cfg/datasets/coco8-pose.yaml +3 -2
  29. ultralytics/cfg/datasets/coco8-seg.yaml +3 -2
  30. ultralytics/cfg/datasets/coco8.yaml +3 -2
  31. ultralytics/cfg/datasets/crack-seg.yaml +3 -2
  32. ultralytics/cfg/datasets/dog-pose.yaml +24 -0
  33. ultralytics/cfg/datasets/dota8.yaml +3 -2
  34. ultralytics/cfg/datasets/hand-keypoints.yaml +26 -0
  35. ultralytics/cfg/datasets/lvis.yaml +1236 -0
  36. ultralytics/cfg/datasets/medical-pills.yaml +22 -0
  37. ultralytics/cfg/datasets/open-images-v7.yaml +2 -1
  38. ultralytics/cfg/datasets/package-seg.yaml +5 -4
  39. ultralytics/cfg/datasets/signature.yaml +21 -0
  40. ultralytics/cfg/datasets/tiger-pose.yaml +3 -2
  41. ultralytics/cfg/datasets/xView.yaml +2 -1
  42. ultralytics/cfg/default.yaml +14 -11
  43. ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +24 -0
  44. ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
  45. ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
  46. ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
  47. ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
  48. ultralytics/cfg/models/11/yolo11.yaml +50 -0
  49. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +5 -2
  50. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +5 -2
  51. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +5 -2
  52. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +5 -2
  53. ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
  54. ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
  55. ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
  56. ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
  57. ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
  58. ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
  59. ultralytics/cfg/models/v3/yolov3-spp.yaml +5 -2
  60. ultralytics/cfg/models/v3/yolov3-tiny.yaml +5 -2
  61. ultralytics/cfg/models/v3/yolov3.yaml +5 -2
  62. ultralytics/cfg/models/v5/yolov5-p6.yaml +5 -2
  63. ultralytics/cfg/models/v5/yolov5.yaml +5 -2
  64. ultralytics/cfg/models/v6/yolov6.yaml +5 -2
  65. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +5 -2
  66. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +5 -2
  67. ultralytics/cfg/models/v8/yolov8-cls.yaml +5 -2
  68. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +6 -2
  69. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +6 -2
  70. ultralytics/cfg/models/v8/yolov8-ghost.yaml +5 -2
  71. ultralytics/cfg/models/v8/yolov8-obb.yaml +5 -2
  72. ultralytics/cfg/models/v8/yolov8-p2.yaml +5 -2
  73. ultralytics/cfg/models/v8/yolov8-p6.yaml +10 -7
  74. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +5 -2
  75. ultralytics/cfg/models/v8/yolov8-pose.yaml +5 -2
  76. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +5 -2
  77. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +5 -2
  78. ultralytics/cfg/models/v8/yolov8-seg.yaml +5 -2
  79. ultralytics/cfg/models/v8/yolov8-world.yaml +5 -2
  80. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +5 -2
  81. ultralytics/cfg/models/v8/yolov8.yaml +5 -2
  82. ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
  83. ultralytics/cfg/models/v9/yolov9c.yaml +30 -25
  84. ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
  85. ultralytics/cfg/models/v9/yolov9e.yaml +46 -42
  86. ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
  87. ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
  88. ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
  89. ultralytics/cfg/solutions/default.yaml +24 -0
  90. ultralytics/cfg/trackers/botsort.yaml +8 -5
  91. ultralytics/cfg/trackers/bytetrack.yaml +8 -5
  92. ultralytics/data/__init__.py +14 -3
  93. ultralytics/data/annotator.py +37 -15
  94. ultralytics/data/augment.py +1783 -289
  95. ultralytics/data/base.py +62 -27
  96. ultralytics/data/build.py +36 -8
  97. ultralytics/data/converter.py +196 -36
  98. ultralytics/data/dataset.py +233 -94
  99. ultralytics/data/loaders.py +199 -96
  100. ultralytics/data/split_dota.py +39 -29
  101. ultralytics/data/utils.py +110 -40
  102. ultralytics/engine/__init__.py +1 -1
  103. ultralytics/engine/exporter.py +569 -242
  104. ultralytics/engine/model.py +604 -252
  105. ultralytics/engine/predictor.py +22 -11
  106. ultralytics/engine/results.py +1228 -218
  107. ultralytics/engine/trainer.py +190 -129
  108. ultralytics/engine/tuner.py +18 -18
  109. ultralytics/engine/validator.py +18 -15
  110. ultralytics/hub/__init__.py +31 -13
  111. ultralytics/hub/auth.py +11 -7
  112. ultralytics/hub/google/__init__.py +159 -0
  113. ultralytics/hub/session.py +128 -94
  114. ultralytics/hub/utils.py +20 -21
  115. ultralytics/models/__init__.py +4 -2
  116. ultralytics/models/fastsam/__init__.py +2 -3
  117. ultralytics/models/fastsam/model.py +26 -4
  118. ultralytics/models/fastsam/predict.py +127 -63
  119. ultralytics/models/fastsam/utils.py +1 -44
  120. ultralytics/models/fastsam/val.py +1 -1
  121. ultralytics/models/nas/__init__.py +1 -1
  122. ultralytics/models/nas/model.py +21 -10
  123. ultralytics/models/nas/predict.py +3 -6
  124. ultralytics/models/nas/val.py +4 -4
  125. ultralytics/models/rtdetr/__init__.py +1 -1
  126. ultralytics/models/rtdetr/model.py +1 -1
  127. ultralytics/models/rtdetr/predict.py +6 -8
  128. ultralytics/models/rtdetr/train.py +6 -2
  129. ultralytics/models/rtdetr/val.py +3 -3
  130. ultralytics/models/sam/__init__.py +3 -3
  131. ultralytics/models/sam/amg.py +29 -23
  132. ultralytics/models/sam/build.py +211 -13
  133. ultralytics/models/sam/model.py +91 -30
  134. ultralytics/models/sam/modules/__init__.py +1 -1
  135. ultralytics/models/sam/modules/blocks.py +1129 -0
  136. ultralytics/models/sam/modules/decoders.py +381 -53
  137. ultralytics/models/sam/modules/encoders.py +515 -324
  138. ultralytics/models/sam/modules/memory_attention.py +237 -0
  139. ultralytics/models/sam/modules/sam.py +969 -21
  140. ultralytics/models/sam/modules/tiny_encoder.py +425 -154
  141. ultralytics/models/sam/modules/transformer.py +159 -60
  142. ultralytics/models/sam/modules/utils.py +293 -0
  143. ultralytics/models/sam/predict.py +1263 -132
  144. ultralytics/models/utils/__init__.py +1 -1
  145. ultralytics/models/utils/loss.py +36 -24
  146. ultralytics/models/utils/ops.py +3 -7
  147. ultralytics/models/yolo/__init__.py +3 -3
  148. ultralytics/models/yolo/classify/__init__.py +1 -1
  149. ultralytics/models/yolo/classify/predict.py +7 -8
  150. ultralytics/models/yolo/classify/train.py +17 -22
  151. ultralytics/models/yolo/classify/val.py +8 -4
  152. ultralytics/models/yolo/detect/__init__.py +1 -1
  153. ultralytics/models/yolo/detect/predict.py +3 -5
  154. ultralytics/models/yolo/detect/train.py +11 -4
  155. ultralytics/models/yolo/detect/val.py +90 -52
  156. ultralytics/models/yolo/model.py +14 -9
  157. ultralytics/models/yolo/obb/__init__.py +1 -1
  158. ultralytics/models/yolo/obb/predict.py +2 -2
  159. ultralytics/models/yolo/obb/train.py +5 -3
  160. ultralytics/models/yolo/obb/val.py +41 -23
  161. ultralytics/models/yolo/pose/__init__.py +1 -1
  162. ultralytics/models/yolo/pose/predict.py +3 -5
  163. ultralytics/models/yolo/pose/train.py +2 -2
  164. ultralytics/models/yolo/pose/val.py +51 -17
  165. ultralytics/models/yolo/segment/__init__.py +1 -1
  166. ultralytics/models/yolo/segment/predict.py +3 -5
  167. ultralytics/models/yolo/segment/train.py +2 -2
  168. ultralytics/models/yolo/segment/val.py +60 -19
  169. ultralytics/models/yolo/world/__init__.py +5 -0
  170. ultralytics/models/yolo/world/train.py +92 -0
  171. ultralytics/models/yolo/world/train_world.py +109 -0
  172. ultralytics/nn/__init__.py +1 -1
  173. ultralytics/nn/autobackend.py +228 -93
  174. ultralytics/nn/modules/__init__.py +39 -14
  175. ultralytics/nn/modules/activation.py +21 -0
  176. ultralytics/nn/modules/block.py +527 -67
  177. ultralytics/nn/modules/conv.py +24 -7
  178. ultralytics/nn/modules/head.py +177 -34
  179. ultralytics/nn/modules/transformer.py +6 -5
  180. ultralytics/nn/modules/utils.py +1 -2
  181. ultralytics/nn/tasks.py +225 -77
  182. ultralytics/solutions/__init__.py +30 -1
  183. ultralytics/solutions/ai_gym.py +96 -143
  184. ultralytics/solutions/analytics.py +247 -0
  185. ultralytics/solutions/distance_calculation.py +78 -135
  186. ultralytics/solutions/heatmap.py +93 -247
  187. ultralytics/solutions/object_counter.py +184 -259
  188. ultralytics/solutions/parking_management.py +246 -0
  189. ultralytics/solutions/queue_management.py +112 -0
  190. ultralytics/solutions/region_counter.py +116 -0
  191. ultralytics/solutions/security_alarm.py +144 -0
  192. ultralytics/solutions/solutions.py +178 -0
  193. ultralytics/solutions/speed_estimation.py +86 -174
  194. ultralytics/solutions/streamlit_inference.py +190 -0
  195. ultralytics/solutions/trackzone.py +68 -0
  196. ultralytics/trackers/__init__.py +1 -1
  197. ultralytics/trackers/basetrack.py +32 -13
  198. ultralytics/trackers/bot_sort.py +61 -28
  199. ultralytics/trackers/byte_tracker.py +83 -51
  200. ultralytics/trackers/track.py +21 -6
  201. ultralytics/trackers/utils/__init__.py +1 -1
  202. ultralytics/trackers/utils/gmc.py +62 -48
  203. ultralytics/trackers/utils/kalman_filter.py +166 -35
  204. ultralytics/trackers/utils/matching.py +40 -21
  205. ultralytics/utils/__init__.py +511 -239
  206. ultralytics/utils/autobatch.py +40 -22
  207. ultralytics/utils/benchmarks.py +266 -85
  208. ultralytics/utils/callbacks/__init__.py +1 -1
  209. ultralytics/utils/callbacks/base.py +1 -3
  210. ultralytics/utils/callbacks/clearml.py +7 -6
  211. ultralytics/utils/callbacks/comet.py +39 -17
  212. ultralytics/utils/callbacks/dvc.py +1 -1
  213. ultralytics/utils/callbacks/hub.py +16 -16
  214. ultralytics/utils/callbacks/mlflow.py +28 -24
  215. ultralytics/utils/callbacks/neptune.py +6 -2
  216. ultralytics/utils/callbacks/raytune.py +3 -4
  217. ultralytics/utils/callbacks/tensorboard.py +18 -18
  218. ultralytics/utils/callbacks/wb.py +27 -20
  219. ultralytics/utils/checks.py +160 -100
  220. ultralytics/utils/dist.py +2 -1
  221. ultralytics/utils/downloads.py +44 -37
  222. ultralytics/utils/errors.py +1 -1
  223. ultralytics/utils/files.py +72 -38
  224. ultralytics/utils/instance.py +41 -19
  225. ultralytics/utils/loss.py +84 -56
  226. ultralytics/utils/metrics.py +61 -56
  227. ultralytics/utils/ops.py +94 -89
  228. ultralytics/utils/patches.py +30 -14
  229. ultralytics/utils/plotting.py +600 -269
  230. ultralytics/utils/tal.py +67 -26
  231. ultralytics/utils/torch_utils.py +302 -102
  232. ultralytics/utils/triton.py +2 -1
  233. ultralytics/utils/tuner.py +21 -12
  234. ultralytics-8.3.62.dist-info/METADATA +370 -0
  235. ultralytics-8.3.62.dist-info/RECORD +241 -0
  236. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/WHEEL +1 -1
  237. ultralytics/data/explorer/__init__.py +0 -5
  238. ultralytics/data/explorer/explorer.py +0 -472
  239. ultralytics/data/explorer/gui/__init__.py +0 -1
  240. ultralytics/data/explorer/gui/dash.py +0 -268
  241. ultralytics/data/explorer/utils.py +0 -166
  242. ultralytics/models/fastsam/prompt.py +0 -357
  243. ultralytics-8.1.28.dist-info/METADATA +0 -373
  244. ultralytics-8.1.28.dist-info/RECORD +0 -197
  245. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/LICENSE +0 -0
  246. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/entry_points.txt +0 -0
  247. {ultralytics-8.1.28.dist-info → ultralytics-8.3.62.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,6 @@
1
- # Ultralytics YOLO 🚀, AGPL-3.0 license
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
3
  import ast
4
- import contextlib
5
4
  import json
6
5
  import platform
7
6
  import zipfile
@@ -14,7 +13,7 @@ import torch
14
13
  import torch.nn as nn
15
14
  from PIL import Image
16
15
 
17
- from ultralytics.utils import ARM64, LINUX, LOGGER, ROOT, yaml_load
16
+ from ultralytics.utils import ARM64, IS_JETSON, IS_RASPBERRYPI, LINUX, LOGGER, ROOT, yaml_load
18
17
  from ultralytics.utils.checks import check_requirements, check_suffix, check_version, check_yaml
19
18
  from ultralytics.utils.downloads import attempt_download_asset, is_url
20
19
 
@@ -45,8 +44,10 @@ def check_class_names(names):
45
44
  def default_class_names(data=None):
46
45
  """Applies default class names to an input YAML file or returns numerical class names."""
47
46
  if data:
48
- with contextlib.suppress(Exception):
47
+ try:
49
48
  return yaml_load(check_yaml(data))["names"]
49
+ except Exception:
50
+ pass
50
51
  return {i: f"class{i}" for i in range(999)} # return default if above errors
51
52
 
52
53
 
@@ -58,21 +59,22 @@ class AutoBackend(nn.Module):
58
59
  range of formats, each with specific naming conventions as outlined below:
59
60
 
60
61
  Supported Formats and Naming Conventions:
61
- | Format | File Suffix |
62
- |-----------------------|------------------|
63
- | PyTorch | *.pt |
64
- | TorchScript | *.torchscript |
65
- | ONNX Runtime | *.onnx |
66
- | ONNX OpenCV DNN | *.onnx (dnn=True)|
67
- | OpenVINO | *openvino_model/ |
68
- | CoreML | *.mlpackage |
69
- | TensorRT | *.engine |
70
- | TensorFlow SavedModel | *_saved_model |
71
- | TensorFlow GraphDef | *.pb |
72
- | TensorFlow Lite | *.tflite |
73
- | TensorFlow Edge TPU | *_edgetpu.tflite |
74
- | PaddlePaddle | *_paddle_model |
75
- | NCNN | *_ncnn_model |
62
+ | Format | File Suffix |
63
+ |-----------------------|-------------------|
64
+ | PyTorch | *.pt |
65
+ | TorchScript | *.torchscript |
66
+ | ONNX Runtime | *.onnx |
67
+ | ONNX OpenCV DNN | *.onnx (dnn=True) |
68
+ | OpenVINO | *openvino_model/ |
69
+ | CoreML | *.mlpackage |
70
+ | TensorRT | *.engine |
71
+ | TensorFlow SavedModel | *_saved_model/ |
72
+ | TensorFlow GraphDef | *.pb |
73
+ | TensorFlow Lite | *.tflite |
74
+ | TensorFlow Edge TPU | *_edgetpu.tflite |
75
+ | PaddlePaddle | *_paddle_model/ |
76
+ | MNN | *.mnn |
77
+ | NCNN | *_ncnn_model/ |
76
78
 
77
79
  This class offers dynamic backend switching capabilities based on the input model format, making it easier to deploy
78
80
  models across various platforms.
@@ -81,7 +83,7 @@ class AutoBackend(nn.Module):
81
83
  @torch.no_grad()
82
84
  def __init__(
83
85
  self,
84
- weights="yolov8n.pt",
86
+ weights="yolo11n.pt",
85
87
  device=torch.device("cpu"),
86
88
  dnn=False,
87
89
  data=None,
@@ -94,7 +96,7 @@ class AutoBackend(nn.Module):
94
96
  Initialize the AutoBackend for inference.
95
97
 
96
98
  Args:
97
- weights (str): Path to the model weights file. Defaults to 'yolov8n.pt'.
99
+ weights (str | torch.nn.Module): Path to the model weights file or a module instance. Defaults to 'yolo11n.pt'.
98
100
  device (torch.device): Device to run the model on. Defaults to CPU.
99
101
  dnn (bool): Use OpenCV DNN module for ONNX inference. Defaults to False.
100
102
  data (str | Path | optional): Path to the additional data.yaml file containing class names. Optional.
@@ -119,17 +121,19 @@ class AutoBackend(nn.Module):
119
121
  edgetpu,
120
122
  tfjs,
121
123
  paddle,
124
+ mnn,
122
125
  ncnn,
126
+ imx,
123
127
  triton,
124
128
  ) = self._model_type(w)
125
129
  fp16 &= pt or jit or onnx or xml or engine or nn_module or triton # FP16
126
130
  nhwc = coreml or saved_model or pb or tflite or edgetpu # BHWC formats (vs torch BCWH)
127
131
  stride = 32 # default stride
128
- model, metadata = None, None
132
+ model, metadata, task = None, None, None
129
133
 
130
134
  # Set device
131
135
  cuda = torch.cuda.is_available() and device.type != "cpu" # use CUDA
132
- if cuda and not any([nn_module, pt, jit, engine, onnx]): # GPU dataloader formats
136
+ if cuda and not any([nn_module, pt, jit, engine, onnx, paddle]): # GPU dataloader formats
133
137
  device = torch.device("cpu")
134
138
  cuda = False
135
139
 
@@ -140,7 +144,8 @@ class AutoBackend(nn.Module):
140
144
  # In-memory PyTorch model
141
145
  if nn_module:
142
146
  model = weights.to(device)
143
- model = model.fuse(verbose=verbose) if fuse else model
147
+ if fuse:
148
+ model = model.fuse(verbose=verbose)
144
149
  if hasattr(model, "kpt_shape"):
145
150
  kpt_shape = model.kpt_shape # pose-only
146
151
  stride = max(int(model.stride.max()), 32) # model stride
@@ -178,16 +183,56 @@ class AutoBackend(nn.Module):
178
183
  check_requirements("opencv-python>=4.5.4")
179
184
  net = cv2.dnn.readNetFromONNX(w)
180
185
 
181
- # ONNX Runtime
182
- elif onnx:
186
+ # ONNX Runtime and IMX
187
+ elif onnx or imx:
183
188
  LOGGER.info(f"Loading {w} for ONNX Runtime inference...")
184
189
  check_requirements(("onnx", "onnxruntime-gpu" if cuda else "onnxruntime"))
190
+ if IS_RASPBERRYPI or IS_JETSON:
191
+ # Fix 'numpy.linalg._umath_linalg' has no attribute '_ilp64' for TF SavedModel on RPi and Jetson
192
+ check_requirements("numpy==1.23.5")
185
193
  import onnxruntime
186
194
 
187
- providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] if cuda else ["CPUExecutionProvider"]
188
- session = onnxruntime.InferenceSession(w, providers=providers)
195
+ providers = ["CPUExecutionProvider"]
196
+ if cuda and "CUDAExecutionProvider" in onnxruntime.get_available_providers():
197
+ providers.insert(0, "CUDAExecutionProvider")
198
+ elif cuda: # Only log warning if CUDA was requested but unavailable
199
+ LOGGER.warning("WARNING ⚠️ Failed to start ONNX Runtime with CUDA. Using CPU...")
200
+ device = torch.device("cpu")
201
+ cuda = False
202
+ LOGGER.info(f"Using ONNX Runtime {providers[0]}")
203
+ if onnx:
204
+ session = onnxruntime.InferenceSession(w, providers=providers)
205
+ else:
206
+ check_requirements(
207
+ ["model-compression-toolkit==2.1.1", "sony-custom-layers[torch]==0.2.0", "onnxruntime-extensions"]
208
+ )
209
+ w = next(Path(w).glob("*.onnx"))
210
+ LOGGER.info(f"Loading {w} for ONNX IMX inference...")
211
+ import mct_quantizers as mctq
212
+ from sony_custom_layers.pytorch.object_detection import nms_ort # noqa
213
+
214
+ session = onnxruntime.InferenceSession(
215
+ w, mctq.get_ort_session_options(), providers=["CPUExecutionProvider"]
216
+ )
217
+ task = "detect"
218
+
189
219
  output_names = [x.name for x in session.get_outputs()]
190
220
  metadata = session.get_modelmeta().custom_metadata_map
221
+ dynamic = isinstance(session.get_outputs()[0].shape[0], str)
222
+ if not dynamic:
223
+ io = session.io_binding()
224
+ bindings = []
225
+ for output in session.get_outputs():
226
+ y_tensor = torch.empty(output.shape, dtype=torch.float16 if fp16 else torch.float32).to(device)
227
+ io.bind_output(
228
+ name=output.name,
229
+ device_type=device.type,
230
+ device_id=device.index if cuda else 0,
231
+ element_type=np.float16 if fp16 else np.float32,
232
+ shape=tuple(y_tensor.shape),
233
+ buffer_ptr=y_tensor.data_ptr(),
234
+ )
235
+ bindings.append(y_tensor)
191
236
 
192
237
  # OpenVINO
193
238
  elif xml:
@@ -202,13 +247,10 @@ class AutoBackend(nn.Module):
202
247
  ov_model = core.read_model(model=str(w), weights=w.with_suffix(".bin"))
203
248
  if ov_model.get_parameters()[0].get_layout().empty:
204
249
  ov_model.get_parameters()[0].set_layout(ov.Layout("NCHW"))
205
- batch_dim = ov.get_batch(ov_model)
206
- if batch_dim.is_static:
207
- batch_size = batch_dim.get_length()
208
250
 
209
251
  # OpenVINO inference modes are 'LATENCY', 'THROUGHPUT' (not recommended), or 'CUMULATIVE_THROUGHPUT'
210
252
  inference_mode = "CUMULATIVE_THROUGHPUT" if batch > 1 else "LATENCY"
211
- LOGGER.info(f"Using OpenVINO {inference_mode} mode for batch-size={batch_size} inference...")
253
+ LOGGER.info(f"Using OpenVINO {inference_mode} mode for batch={batch} inference...")
212
254
  ov_compiled_model = core.compile_model(
213
255
  ov_model,
214
256
  device_name="AUTO", # AUTO selects best available device, do not modify
@@ -224,35 +266,63 @@ class AutoBackend(nn.Module):
224
266
  import tensorrt as trt # noqa https://developer.nvidia.com/nvidia-tensorrt-download
225
267
  except ImportError:
226
268
  if LINUX:
227
- check_requirements("nvidia-tensorrt", cmds="-U --index-url https://pypi.ngc.nvidia.com")
269
+ check_requirements("tensorrt>7.0.0,!=10.1.0")
228
270
  import tensorrt as trt # noqa
229
- check_version(trt.__version__, "7.0.0", hard=True) # require tensorrt>=7.0.0
271
+ check_version(trt.__version__, ">=7.0.0", hard=True)
272
+ check_version(trt.__version__, "!=10.1.0", msg="https://github.com/ultralytics/ultralytics/pull/14239")
230
273
  if device.type == "cpu":
231
274
  device = torch.device("cuda:0")
232
275
  Binding = namedtuple("Binding", ("name", "dtype", "shape", "data", "ptr"))
233
276
  logger = trt.Logger(trt.Logger.INFO)
234
277
  # Read file
235
278
  with open(w, "rb") as f, trt.Runtime(logger) as runtime:
236
- meta_len = int.from_bytes(f.read(4), byteorder="little") # read metadata length
237
- metadata = json.loads(f.read(meta_len).decode("utf-8")) # read metadata
279
+ try:
280
+ meta_len = int.from_bytes(f.read(4), byteorder="little") # read metadata length
281
+ metadata = json.loads(f.read(meta_len).decode("utf-8")) # read metadata
282
+ except UnicodeDecodeError:
283
+ f.seek(0) # engine file may lack embedded Ultralytics metadata
238
284
  model = runtime.deserialize_cuda_engine(f.read()) # read engine
239
- context = model.create_execution_context()
285
+
286
+ # Model context
287
+ try:
288
+ context = model.create_execution_context()
289
+ except Exception as e: # model is None
290
+ LOGGER.error(f"ERROR: TensorRT model exported with a different version than {trt.__version__}\n")
291
+ raise e
292
+
240
293
  bindings = OrderedDict()
241
294
  output_names = []
242
295
  fp16 = False # default updated below
243
296
  dynamic = False
244
- for i in range(model.num_bindings):
245
- name = model.get_binding_name(i)
246
- dtype = trt.nptype(model.get_binding_dtype(i))
247
- if model.binding_is_input(i):
248
- if -1 in tuple(model.get_binding_shape(i)): # dynamic
249
- dynamic = True
250
- context.set_binding_shape(i, tuple(model.get_profile_shape(0, i)[2]))
251
- if dtype == np.float16:
252
- fp16 = True
253
- else: # output
254
- output_names.append(name)
255
- shape = tuple(context.get_binding_shape(i))
297
+ is_trt10 = not hasattr(model, "num_bindings")
298
+ num = range(model.num_io_tensors) if is_trt10 else range(model.num_bindings)
299
+ for i in num:
300
+ if is_trt10:
301
+ name = model.get_tensor_name(i)
302
+ dtype = trt.nptype(model.get_tensor_dtype(name))
303
+ is_input = model.get_tensor_mode(name) == trt.TensorIOMode.INPUT
304
+ if is_input:
305
+ if -1 in tuple(model.get_tensor_shape(name)):
306
+ dynamic = True
307
+ context.set_input_shape(name, tuple(model.get_tensor_profile_shape(name, 0)[1]))
308
+ if dtype == np.float16:
309
+ fp16 = True
310
+ else:
311
+ output_names.append(name)
312
+ shape = tuple(context.get_tensor_shape(name))
313
+ else: # TensorRT < 10.0
314
+ name = model.get_binding_name(i)
315
+ dtype = trt.nptype(model.get_binding_dtype(i))
316
+ is_input = model.binding_is_input(i)
317
+ if model.binding_is_input(i):
318
+ if -1 in tuple(model.get_binding_shape(i)): # dynamic
319
+ dynamic = True
320
+ context.set_binding_shape(i, tuple(model.get_profile_shape(0, i)[1]))
321
+ if dtype == np.float16:
322
+ fp16 = True
323
+ else:
324
+ output_names.append(name)
325
+ shape = tuple(context.get_binding_shape(i))
256
326
  im = torch.from_numpy(np.empty(shape, dtype=dtype)).to(device)
257
327
  bindings[name] = Binding(name, dtype, shape, im, int(im.data_ptr()))
258
328
  binding_addrs = OrderedDict((n, d.ptr) for n, d in bindings.items())
@@ -292,6 +362,10 @@ class AutoBackend(nn.Module):
292
362
  with open(w, "rb") as f:
293
363
  gd.ParseFromString(f.read())
294
364
  frozen_func = wrap_frozen_graph(gd, inputs="x:0", outputs=gd_outputs(gd))
365
+ try: # find metadata in SavedModel alongside GraphDef
366
+ metadata = next(Path(w).resolve().parent.rglob(f"{Path(w).stem}_saved_model*/metadata.yaml"))
367
+ except StopIteration:
368
+ pass
295
369
 
296
370
  # TFLite or TFLite Edge TPU
297
371
  elif tflite or edgetpu: # https://www.tensorflow.org/lite/guide/python#install_tensorflow_lite_for_python
@@ -302,11 +376,16 @@ class AutoBackend(nn.Module):
302
376
 
303
377
  Interpreter, load_delegate = tf.lite.Interpreter, tf.lite.experimental.load_delegate
304
378
  if edgetpu: # TF Edge TPU https://coral.ai/software/#edgetpu-runtime
305
- LOGGER.info(f"Loading {w} for TensorFlow Lite Edge TPU inference...")
379
+ device = device[3:] if str(device).startswith("tpu") else ":0"
380
+ LOGGER.info(f"Loading {w} on device {device[1:]} for TensorFlow Lite Edge TPU inference...")
306
381
  delegate = {"Linux": "libedgetpu.so.1", "Darwin": "libedgetpu.1.dylib", "Windows": "edgetpu.dll"}[
307
382
  platform.system()
308
383
  ]
309
- interpreter = Interpreter(model_path=w, experimental_delegates=[load_delegate(delegate)])
384
+ interpreter = Interpreter(
385
+ model_path=w,
386
+ experimental_delegates=[load_delegate(delegate, options={"device": device})],
387
+ )
388
+ device = "cpu" # Required, otherwise PyTorch will try to use the wrong device
310
389
  else: # TFLite
311
390
  LOGGER.info(f"Loading {w} for TensorFlow Lite inference...")
312
391
  interpreter = Interpreter(model_path=w) # load TFLite model
@@ -314,10 +393,12 @@ class AutoBackend(nn.Module):
314
393
  input_details = interpreter.get_input_details() # inputs
315
394
  output_details = interpreter.get_output_details() # outputs
316
395
  # Load metadata
317
- with contextlib.suppress(zipfile.BadZipFile):
396
+ try:
318
397
  with zipfile.ZipFile(w, "r") as model:
319
398
  meta_file = model.namelist()[0]
320
399
  metadata = ast.literal_eval(model.read(meta_file).decode("utf-8"))
400
+ except zipfile.BadZipFile:
401
+ pass
321
402
 
322
403
  # TF.js
323
404
  elif tfjs:
@@ -340,6 +421,23 @@ class AutoBackend(nn.Module):
340
421
  output_names = predictor.get_output_names()
341
422
  metadata = w.parents[1] / "metadata.yaml"
342
423
 
424
+ # MNN
425
+ elif mnn:
426
+ LOGGER.info(f"Loading {w} for MNN inference...")
427
+ check_requirements("MNN") # requires MNN
428
+ import os
429
+
430
+ import MNN
431
+
432
+ config = {"precision": "low", "backend": "CPU", "numThread": (os.cpu_count() + 1) // 2}
433
+ rt = MNN.nn.create_runtime_manager((config,))
434
+ net = MNN.nn.load_module_from_file(w, [], [], runtime_manager=rt, rearrange=True)
435
+
436
+ def torch_to_mnn(x):
437
+ return MNN.expr.const(x.data_ptr(), x.shape)
438
+
439
+ metadata = json.loads(net.get_info()["bizCode"])
440
+
343
441
  # NCNN
344
442
  elif ncnn:
345
443
  LOGGER.info(f"Loading {w} for NCNN inference...")
@@ -361,24 +459,25 @@ class AutoBackend(nn.Module):
361
459
  from ultralytics.utils.triton import TritonRemoteModel
362
460
 
363
461
  model = TritonRemoteModel(w)
462
+ metadata = model.metadata
364
463
 
365
464
  # Any other format (unsupported)
366
465
  else:
367
466
  from ultralytics.engine.exporter import export_formats
368
467
 
369
468
  raise TypeError(
370
- f"model='{w}' is not a supported model format. "
371
- f"See https://docs.ultralytics.com/modes/predict for help.\n\n{export_formats()}"
469
+ f"model='{w}' is not a supported model format. Ultralytics supports: {export_formats()['Format']}\n"
470
+ f"See https://docs.ultralytics.com/modes/predict for help."
372
471
  )
373
472
 
374
473
  # Load external metadata YAML
375
474
  if isinstance(metadata, (str, Path)) and Path(metadata).exists():
376
475
  metadata = yaml_load(metadata)
377
- if metadata:
476
+ if metadata and isinstance(metadata, dict):
378
477
  for k, v in metadata.items():
379
- if k in ("stride", "batch"):
478
+ if k in {"stride", "batch"}:
380
479
  metadata[k] = int(v)
381
- elif k in ("imgsz", "names", "kpt_shape") and isinstance(v, str):
480
+ elif k in {"imgsz", "names", "kpt_shape"} and isinstance(v, str):
382
481
  metadata[k] = eval(v)
383
482
  stride = metadata["stride"]
384
483
  task = metadata["task"]
@@ -435,9 +534,26 @@ class AutoBackend(nn.Module):
435
534
  y = self.net.forward()
436
535
 
437
536
  # ONNX Runtime
438
- elif self.onnx:
439
- im = im.cpu().numpy() # torch to numpy
440
- y = self.session.run(self.output_names, {self.session.get_inputs()[0].name: im})
537
+ elif self.onnx or self.imx:
538
+ if self.dynamic:
539
+ im = im.cpu().numpy() # torch to numpy
540
+ y = self.session.run(self.output_names, {self.session.get_inputs()[0].name: im})
541
+ else:
542
+ if not self.cuda:
543
+ im = im.cpu()
544
+ self.io.bind_input(
545
+ name="images",
546
+ device_type=im.device.type,
547
+ device_id=im.device.index if im.device.type == "cuda" else 0,
548
+ element_type=np.float16 if self.fp16 else np.float32,
549
+ shape=tuple(im.shape),
550
+ buffer_ptr=im.data_ptr(),
551
+ )
552
+ self.session.run_with_iobinding(self.io)
553
+ y = self.bindings
554
+ if self.imx:
555
+ # boxes, conf, cls
556
+ y = np.concatenate([y[0], y[1][:, :, None], y[2][:, :, None]], axis=-1)
441
557
 
442
558
  # OpenVINO
443
559
  elif self.xml:
@@ -466,12 +582,19 @@ class AutoBackend(nn.Module):
466
582
  # TensorRT
467
583
  elif self.engine:
468
584
  if self.dynamic and im.shape != self.bindings["images"].shape:
469
- i = self.model.get_binding_index("images")
470
- self.context.set_binding_shape(i, im.shape) # reshape if dynamic
471
- self.bindings["images"] = self.bindings["images"]._replace(shape=im.shape)
472
- for name in self.output_names:
473
- i = self.model.get_binding_index(name)
474
- self.bindings[name].data.resize_(tuple(self.context.get_binding_shape(i)))
585
+ if self.is_trt10:
586
+ self.context.set_input_shape("images", im.shape)
587
+ self.bindings["images"] = self.bindings["images"]._replace(shape=im.shape)
588
+ for name in self.output_names:
589
+ self.bindings[name].data.resize_(tuple(self.context.get_tensor_shape(name)))
590
+ else:
591
+ i = self.model.get_binding_index("images")
592
+ self.context.set_binding_shape(i, im.shape)
593
+ self.bindings["images"] = self.bindings["images"]._replace(shape=im.shape)
594
+ for name in self.output_names:
595
+ i = self.model.get_binding_index(name)
596
+ self.bindings[name].data.resize_(tuple(self.context.get_binding_shape(i)))
597
+
475
598
  s = self.bindings["images"].shape
476
599
  assert im.shape == s, f"input size {im.shape} {'>' if self.dynamic else 'not equal to'} max model size {s}"
477
600
  self.binding_addrs["images"] = int(im.data_ptr())
@@ -494,10 +617,9 @@ class AutoBackend(nn.Module):
494
617
  # box = xywh2xyxy(y['coordinates'] * [[w, h, w, h]]) # xyxy pixels
495
618
  # conf, cls = y['confidence'].max(1), y['confidence'].argmax(1).astype(np.float32)
496
619
  # y = np.concatenate((box, conf.reshape(-1, 1), cls.reshape(-1, 1)), 1)
497
- elif len(y) == 1: # classification model
498
- y = list(y.values())
499
- elif len(y) == 2: # segmentation model
500
- y = list(reversed(y.values())) # reversed for segmentation models (pred, proto)
620
+ y = list(y.values())
621
+ if len(y) == 2 and len(y[1].shape) != 4: # segmentation model
622
+ y = list(reversed(y)) # reversed for segmentation models (pred, proto)
501
623
 
502
624
  # PaddlePaddle
503
625
  elif self.paddle:
@@ -506,17 +628,19 @@ class AutoBackend(nn.Module):
506
628
  self.predictor.run()
507
629
  y = [self.predictor.get_output_handle(x).copy_to_cpu() for x in self.output_names]
508
630
 
631
+ # MNN
632
+ elif self.mnn:
633
+ input_var = self.torch_to_mnn(im)
634
+ output_var = self.net.onForward([input_var])
635
+ y = [x.read() for x in output_var]
636
+
509
637
  # NCNN
510
638
  elif self.ncnn:
511
639
  mat_in = self.pyncnn.Mat(im[0].cpu().numpy())
512
- ex = self.net.create_extractor()
513
- input_names, output_names = self.net.input_names(), self.net.output_names()
514
- ex.input(input_names[0], mat_in)
515
- y = []
516
- for output_name in output_names:
517
- mat_out = self.pyncnn.Mat()
518
- ex.extract(output_name, mat_out)
519
- y.append(np.array(mat_out)[None])
640
+ with self.net.create_extractor() as ex:
641
+ ex.input(self.net.input_names()[0], mat_in)
642
+ # WARNING: 'output_names' sorted as a temporary fix for https://github.com/pnnx/pnnx/issues/130
643
+ y = [np.array(ex.extract(x)[1])[None] for x in sorted(self.net.output_names())]
520
644
 
521
645
  # NVIDIA Triton Inference Server
522
646
  elif self.triton:
@@ -532,14 +656,10 @@ class AutoBackend(nn.Module):
532
656
  y = [y]
533
657
  elif self.pb: # GraphDef
534
658
  y = self.frozen_func(x=self.tf.constant(im))
535
- if len(y) == 2 and len(self.names) == 999: # segments and names not defined
536
- ip, ib = (0, 1) if len(y[0].shape) == 4 else (1, 0) # index of protos, boxes
537
- nc = y[ib].shape[1] - y[ip].shape[3] - 4 # y = (1, 160, 160, 32), (1, 116, 8400)
538
- self.names = {i: f"class{i}" for i in range(nc)}
539
659
  else: # Lite or Edge TPU
540
660
  details = self.input_details[0]
541
- integer = details["dtype"] in (np.int8, np.int16) # is TFLite quantized int8 or int16 model
542
- if integer:
661
+ is_int = details["dtype"] in {np.int8, np.int16} # is TFLite quantized int8 or int16 model
662
+ if is_int:
543
663
  scale, zero_point = details["quantization"]
544
664
  im = (im / scale + zero_point).astype(details["dtype"]) # de-scale
545
665
  self.interpreter.set_tensor(details["index"], im)
@@ -547,25 +667,38 @@ class AutoBackend(nn.Module):
547
667
  y = []
548
668
  for output in self.output_details:
549
669
  x = self.interpreter.get_tensor(output["index"])
550
- if integer:
670
+ if is_int:
551
671
  scale, zero_point = output["quantization"]
552
672
  x = (x.astype(np.float32) - zero_point) * scale # re-scale
553
- if x.ndim > 2: # if task is not classification
673
+ if x.ndim == 3: # if task is not classification, excluding masks (ndim=4) as well
554
674
  # Denormalize xywh by image size. See https://github.com/ultralytics/ultralytics/pull/1695
555
675
  # xywh are normalized in TFLite/EdgeTPU to mitigate quantization error of integer models
556
- x[:, [0, 2]] *= w
557
- x[:, [1, 3]] *= h
676
+ if x.shape[-1] == 6: # end-to-end model
677
+ x[:, :, [0, 2]] *= w
678
+ x[:, :, [1, 3]] *= h
679
+ else:
680
+ x[:, [0, 2]] *= w
681
+ x[:, [1, 3]] *= h
682
+ if self.task == "pose":
683
+ x[:, 5::3] *= w
684
+ x[:, 6::3] *= h
558
685
  y.append(x)
559
686
  # TF segment fixes: export is reversed vs ONNX export and protos are transposed
560
687
  if len(y) == 2: # segment with (det, proto) output order reversed
561
688
  if len(y[1].shape) != 4:
562
689
  y = list(reversed(y)) # should be y = (1, 116, 8400), (1, 160, 160, 32)
563
- y[1] = np.transpose(y[1], (0, 3, 1, 2)) # should be y = (1, 116, 8400), (1, 32, 160, 160)
690
+ if y[1].shape[-1] == 6: # end-to-end model
691
+ y = [y[1]]
692
+ else:
693
+ y[1] = np.transpose(y[1], (0, 3, 1, 2)) # should be y = (1, 116, 8400), (1, 32, 160, 160)
564
694
  y = [x if isinstance(x, np.ndarray) else x.numpy() for x in y]
565
695
 
566
696
  # for x in y:
567
697
  # print(type(x), len(x)) if isinstance(x, (list, tuple)) else print(type(x), x.shape) # debug shapes
568
698
  if isinstance(y, (list, tuple)):
699
+ if len(self.names) == 999 and (self.task == "segment" or len(y) == 2): # segments and names not defined
700
+ nc = y[0].shape[1] - y[1].shape[1] - 4 # y = (1, 32, 160, 160), (1, 116, 8400)
701
+ self.names = {i: f"class{i}" for i in range(nc)}
569
702
  return self.from_numpy(y[0]) if len(y) == 1 else [self.from_numpy(x) for x in y]
570
703
  else:
571
704
  return self.from_numpy(y)
@@ -589,6 +722,8 @@ class AutoBackend(nn.Module):
589
722
  Args:
590
723
  imgsz (tuple): The shape of the dummy input tensor in the format (batch_size, channels, height, width)
591
724
  """
725
+ import torchvision # noqa (import here so torchvision import time not recorded in postprocess time)
726
+
592
727
  warmup_types = self.pt, self.jit, self.onnx, self.engine, self.saved_model, self.pb, self.triton, self.nn_module
593
728
  if any(warmup_types) and (self.device.type != "cpu" or self.triton):
594
729
  im = torch.empty(*imgsz, dtype=torch.half if self.fp16 else torch.float, device=self.device) # input
@@ -598,8 +733,8 @@ class AutoBackend(nn.Module):
598
733
  @staticmethod
599
734
  def _model_type(p="path/to/model.pt"):
600
735
  """
601
- This function takes a path to a model file and returns the model type. Possibles types are pt, jit, onnx, xml,
602
- engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, ncnn or paddle.
736
+ Takes a path to a model file and returns the model type. Possibles types are pt, jit, onnx, xml, engine, coreml,
737
+ saved_model, pb, tflite, edgetpu, tfjs, ncnn or paddle.
603
738
 
604
739
  Args:
605
740
  p: path to the model file. Defaults to path/to/model.pt
@@ -610,8 +745,8 @@ class AutoBackend(nn.Module):
610
745
  """
611
746
  from ultralytics.engine.exporter import export_formats
612
747
 
613
- sf = list(export_formats().Suffix) # export suffixes
614
- if not is_url(p, check=False) and not isinstance(p, str):
748
+ sf = export_formats()["Suffix"] # export suffixes
749
+ if not is_url(p) and not isinstance(p, str):
615
750
  check_suffix(p, sf) # checks
616
751
  name = Path(p).name
617
752
  types = [s in name for s in sf]