dgenerate-ultralytics-headless 8.3.196__py3-none-any.whl → 8.3.248__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 (243) hide show
  1. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/METADATA +33 -34
  2. dgenerate_ultralytics_headless-8.3.248.dist-info/RECORD +298 -0
  3. tests/__init__.py +5 -7
  4. tests/conftest.py +8 -15
  5. tests/test_cli.py +8 -10
  6. tests/test_cuda.py +9 -10
  7. tests/test_engine.py +29 -2
  8. tests/test_exports.py +69 -21
  9. tests/test_integrations.py +8 -11
  10. tests/test_python.py +109 -71
  11. tests/test_solutions.py +170 -159
  12. ultralytics/__init__.py +27 -9
  13. ultralytics/cfg/__init__.py +57 -64
  14. ultralytics/cfg/datasets/Argoverse.yaml +7 -6
  15. ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
  16. ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
  17. ultralytics/cfg/datasets/ImageNet.yaml +1 -1
  18. ultralytics/cfg/datasets/Objects365.yaml +19 -15
  19. ultralytics/cfg/datasets/SKU-110K.yaml +1 -1
  20. ultralytics/cfg/datasets/VOC.yaml +19 -21
  21. ultralytics/cfg/datasets/VisDrone.yaml +5 -5
  22. ultralytics/cfg/datasets/african-wildlife.yaml +1 -1
  23. ultralytics/cfg/datasets/coco-pose.yaml +24 -2
  24. ultralytics/cfg/datasets/coco.yaml +2 -2
  25. ultralytics/cfg/datasets/coco128-seg.yaml +1 -1
  26. ultralytics/cfg/datasets/coco8-pose.yaml +21 -0
  27. ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
  28. ultralytics/cfg/datasets/dog-pose.yaml +28 -0
  29. ultralytics/cfg/datasets/dota8-multispectral.yaml +1 -1
  30. ultralytics/cfg/datasets/dota8.yaml +2 -2
  31. ultralytics/cfg/datasets/hand-keypoints.yaml +26 -2
  32. ultralytics/cfg/datasets/kitti.yaml +27 -0
  33. ultralytics/cfg/datasets/lvis.yaml +7 -7
  34. ultralytics/cfg/datasets/open-images-v7.yaml +1 -1
  35. ultralytics/cfg/datasets/tiger-pose.yaml +16 -0
  36. ultralytics/cfg/datasets/xView.yaml +16 -16
  37. ultralytics/cfg/default.yaml +96 -94
  38. ultralytics/cfg/models/11/yolo11-pose.yaml +1 -1
  39. ultralytics/cfg/models/11/yoloe-11-seg.yaml +2 -2
  40. ultralytics/cfg/models/11/yoloe-11.yaml +2 -2
  41. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +1 -1
  42. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +1 -1
  43. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +1 -1
  44. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +1 -1
  45. ultralytics/cfg/models/v10/yolov10b.yaml +2 -2
  46. ultralytics/cfg/models/v10/yolov10l.yaml +2 -2
  47. ultralytics/cfg/models/v10/yolov10m.yaml +2 -2
  48. ultralytics/cfg/models/v10/yolov10n.yaml +2 -2
  49. ultralytics/cfg/models/v10/yolov10s.yaml +2 -2
  50. ultralytics/cfg/models/v10/yolov10x.yaml +2 -2
  51. ultralytics/cfg/models/v3/yolov3-tiny.yaml +1 -1
  52. ultralytics/cfg/models/v6/yolov6.yaml +1 -1
  53. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +9 -6
  54. ultralytics/cfg/models/v8/yoloe-v8.yaml +9 -6
  55. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +1 -1
  56. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +1 -1
  57. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +2 -2
  58. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +2 -2
  59. ultralytics/cfg/models/v8/yolov8-ghost.yaml +2 -2
  60. ultralytics/cfg/models/v8/yolov8-obb.yaml +1 -1
  61. ultralytics/cfg/models/v8/yolov8-p2.yaml +1 -1
  62. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +1 -1
  63. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +1 -1
  64. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +1 -1
  65. ultralytics/cfg/models/v8/yolov8-world.yaml +1 -1
  66. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +6 -6
  67. ultralytics/cfg/models/v9/yolov9s.yaml +1 -1
  68. ultralytics/cfg/trackers/botsort.yaml +16 -17
  69. ultralytics/cfg/trackers/bytetrack.yaml +9 -11
  70. ultralytics/data/__init__.py +4 -4
  71. ultralytics/data/annotator.py +3 -4
  72. ultralytics/data/augment.py +286 -476
  73. ultralytics/data/base.py +18 -26
  74. ultralytics/data/build.py +151 -26
  75. ultralytics/data/converter.py +38 -50
  76. ultralytics/data/dataset.py +47 -75
  77. ultralytics/data/loaders.py +42 -49
  78. ultralytics/data/split.py +5 -6
  79. ultralytics/data/split_dota.py +8 -15
  80. ultralytics/data/utils.py +41 -45
  81. ultralytics/engine/exporter.py +462 -462
  82. ultralytics/engine/model.py +150 -191
  83. ultralytics/engine/predictor.py +30 -40
  84. ultralytics/engine/results.py +177 -311
  85. ultralytics/engine/trainer.py +193 -120
  86. ultralytics/engine/tuner.py +77 -63
  87. ultralytics/engine/validator.py +39 -22
  88. ultralytics/hub/__init__.py +16 -19
  89. ultralytics/hub/auth.py +6 -12
  90. ultralytics/hub/google/__init__.py +7 -10
  91. ultralytics/hub/session.py +15 -25
  92. ultralytics/hub/utils.py +5 -8
  93. ultralytics/models/__init__.py +1 -1
  94. ultralytics/models/fastsam/__init__.py +1 -1
  95. ultralytics/models/fastsam/model.py +8 -10
  96. ultralytics/models/fastsam/predict.py +19 -30
  97. ultralytics/models/fastsam/utils.py +1 -2
  98. ultralytics/models/fastsam/val.py +5 -7
  99. ultralytics/models/nas/__init__.py +1 -1
  100. ultralytics/models/nas/model.py +5 -8
  101. ultralytics/models/nas/predict.py +7 -9
  102. ultralytics/models/nas/val.py +1 -2
  103. ultralytics/models/rtdetr/__init__.py +1 -1
  104. ultralytics/models/rtdetr/model.py +7 -8
  105. ultralytics/models/rtdetr/predict.py +15 -19
  106. ultralytics/models/rtdetr/train.py +10 -13
  107. ultralytics/models/rtdetr/val.py +21 -23
  108. ultralytics/models/sam/__init__.py +15 -2
  109. ultralytics/models/sam/amg.py +14 -20
  110. ultralytics/models/sam/build.py +26 -19
  111. ultralytics/models/sam/build_sam3.py +377 -0
  112. ultralytics/models/sam/model.py +29 -32
  113. ultralytics/models/sam/modules/blocks.py +83 -144
  114. ultralytics/models/sam/modules/decoders.py +22 -40
  115. ultralytics/models/sam/modules/encoders.py +44 -101
  116. ultralytics/models/sam/modules/memory_attention.py +16 -30
  117. ultralytics/models/sam/modules/sam.py +206 -79
  118. ultralytics/models/sam/modules/tiny_encoder.py +64 -83
  119. ultralytics/models/sam/modules/transformer.py +18 -28
  120. ultralytics/models/sam/modules/utils.py +174 -50
  121. ultralytics/models/sam/predict.py +2268 -366
  122. ultralytics/models/sam/sam3/__init__.py +3 -0
  123. ultralytics/models/sam/sam3/decoder.py +546 -0
  124. ultralytics/models/sam/sam3/encoder.py +529 -0
  125. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  126. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  127. ultralytics/models/sam/sam3/model_misc.py +199 -0
  128. ultralytics/models/sam/sam3/necks.py +129 -0
  129. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  130. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  131. ultralytics/models/sam/sam3/vitdet.py +547 -0
  132. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  133. ultralytics/models/utils/loss.py +14 -26
  134. ultralytics/models/utils/ops.py +13 -17
  135. ultralytics/models/yolo/__init__.py +1 -1
  136. ultralytics/models/yolo/classify/predict.py +9 -12
  137. ultralytics/models/yolo/classify/train.py +15 -41
  138. ultralytics/models/yolo/classify/val.py +34 -32
  139. ultralytics/models/yolo/detect/predict.py +8 -11
  140. ultralytics/models/yolo/detect/train.py +13 -32
  141. ultralytics/models/yolo/detect/val.py +75 -63
  142. ultralytics/models/yolo/model.py +37 -53
  143. ultralytics/models/yolo/obb/predict.py +5 -14
  144. ultralytics/models/yolo/obb/train.py +11 -14
  145. ultralytics/models/yolo/obb/val.py +42 -39
  146. ultralytics/models/yolo/pose/__init__.py +1 -1
  147. ultralytics/models/yolo/pose/predict.py +7 -22
  148. ultralytics/models/yolo/pose/train.py +10 -22
  149. ultralytics/models/yolo/pose/val.py +40 -59
  150. ultralytics/models/yolo/segment/predict.py +16 -20
  151. ultralytics/models/yolo/segment/train.py +3 -12
  152. ultralytics/models/yolo/segment/val.py +106 -56
  153. ultralytics/models/yolo/world/train.py +12 -16
  154. ultralytics/models/yolo/world/train_world.py +11 -34
  155. ultralytics/models/yolo/yoloe/__init__.py +7 -7
  156. ultralytics/models/yolo/yoloe/predict.py +16 -23
  157. ultralytics/models/yolo/yoloe/train.py +31 -56
  158. ultralytics/models/yolo/yoloe/train_seg.py +5 -10
  159. ultralytics/models/yolo/yoloe/val.py +16 -21
  160. ultralytics/nn/__init__.py +7 -7
  161. ultralytics/nn/autobackend.py +152 -80
  162. ultralytics/nn/modules/__init__.py +60 -60
  163. ultralytics/nn/modules/activation.py +4 -6
  164. ultralytics/nn/modules/block.py +133 -217
  165. ultralytics/nn/modules/conv.py +52 -97
  166. ultralytics/nn/modules/head.py +64 -116
  167. ultralytics/nn/modules/transformer.py +79 -89
  168. ultralytics/nn/modules/utils.py +16 -21
  169. ultralytics/nn/tasks.py +111 -156
  170. ultralytics/nn/text_model.py +40 -67
  171. ultralytics/solutions/__init__.py +12 -12
  172. ultralytics/solutions/ai_gym.py +11 -17
  173. ultralytics/solutions/analytics.py +15 -16
  174. ultralytics/solutions/config.py +5 -6
  175. ultralytics/solutions/distance_calculation.py +10 -13
  176. ultralytics/solutions/heatmap.py +7 -13
  177. ultralytics/solutions/instance_segmentation.py +5 -8
  178. ultralytics/solutions/object_blurrer.py +7 -10
  179. ultralytics/solutions/object_counter.py +12 -19
  180. ultralytics/solutions/object_cropper.py +8 -14
  181. ultralytics/solutions/parking_management.py +33 -31
  182. ultralytics/solutions/queue_management.py +10 -12
  183. ultralytics/solutions/region_counter.py +9 -12
  184. ultralytics/solutions/security_alarm.py +15 -20
  185. ultralytics/solutions/similarity_search.py +13 -17
  186. ultralytics/solutions/solutions.py +75 -74
  187. ultralytics/solutions/speed_estimation.py +7 -10
  188. ultralytics/solutions/streamlit_inference.py +4 -7
  189. ultralytics/solutions/templates/similarity-search.html +7 -18
  190. ultralytics/solutions/trackzone.py +7 -10
  191. ultralytics/solutions/vision_eye.py +5 -8
  192. ultralytics/trackers/__init__.py +1 -1
  193. ultralytics/trackers/basetrack.py +3 -5
  194. ultralytics/trackers/bot_sort.py +10 -27
  195. ultralytics/trackers/byte_tracker.py +14 -30
  196. ultralytics/trackers/track.py +3 -6
  197. ultralytics/trackers/utils/gmc.py +11 -22
  198. ultralytics/trackers/utils/kalman_filter.py +37 -48
  199. ultralytics/trackers/utils/matching.py +12 -15
  200. ultralytics/utils/__init__.py +116 -116
  201. ultralytics/utils/autobatch.py +2 -4
  202. ultralytics/utils/autodevice.py +17 -18
  203. ultralytics/utils/benchmarks.py +70 -70
  204. ultralytics/utils/callbacks/base.py +8 -10
  205. ultralytics/utils/callbacks/clearml.py +5 -13
  206. ultralytics/utils/callbacks/comet.py +32 -46
  207. ultralytics/utils/callbacks/dvc.py +13 -18
  208. ultralytics/utils/callbacks/mlflow.py +4 -5
  209. ultralytics/utils/callbacks/neptune.py +7 -15
  210. ultralytics/utils/callbacks/platform.py +314 -38
  211. ultralytics/utils/callbacks/raytune.py +3 -4
  212. ultralytics/utils/callbacks/tensorboard.py +23 -31
  213. ultralytics/utils/callbacks/wb.py +10 -13
  214. ultralytics/utils/checks.py +151 -87
  215. ultralytics/utils/cpu.py +3 -8
  216. ultralytics/utils/dist.py +19 -15
  217. ultralytics/utils/downloads.py +29 -41
  218. ultralytics/utils/errors.py +6 -14
  219. ultralytics/utils/events.py +2 -4
  220. ultralytics/utils/export/__init__.py +7 -0
  221. ultralytics/utils/{export.py → export/engine.py} +16 -16
  222. ultralytics/utils/export/imx.py +325 -0
  223. ultralytics/utils/export/tensorflow.py +231 -0
  224. ultralytics/utils/files.py +24 -28
  225. ultralytics/utils/git.py +9 -11
  226. ultralytics/utils/instance.py +30 -51
  227. ultralytics/utils/logger.py +212 -114
  228. ultralytics/utils/loss.py +15 -24
  229. ultralytics/utils/metrics.py +131 -160
  230. ultralytics/utils/nms.py +21 -30
  231. ultralytics/utils/ops.py +107 -165
  232. ultralytics/utils/patches.py +33 -21
  233. ultralytics/utils/plotting.py +122 -119
  234. ultralytics/utils/tal.py +28 -44
  235. ultralytics/utils/torch_utils.py +70 -187
  236. ultralytics/utils/tqdm.py +20 -20
  237. ultralytics/utils/triton.py +13 -19
  238. ultralytics/utils/tuner.py +17 -5
  239. dgenerate_ultralytics_headless-8.3.196.dist-info/RECORD +0 -281
  240. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/WHEEL +0 -0
  241. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/entry_points.txt +0 -0
  242. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/licenses/LICENSE +0 -0
  243. {dgenerate_ultralytics_headless-8.3.196.dist-info → dgenerate_ultralytics_headless-8.3.248.dist-info}/top_level.txt +0 -0
@@ -9,24 +9,23 @@ from ultralytics.utils.checks import check_requirements
9
9
 
10
10
 
11
11
  class GPUInfo:
12
- """
13
- Manages NVIDIA GPU information via pynvml with robust error handling.
12
+ """Manages NVIDIA GPU information via pynvml with robust error handling.
14
13
 
15
- Provides methods to query detailed GPU statistics (utilization, memory, temp, power) and select the most idle
16
- GPUs based on configurable criteria. It safely handles the absence or initialization failure of the pynvml
17
- library by logging warnings and disabling related features, preventing application crashes.
14
+ Provides methods to query detailed GPU statistics (utilization, memory, temp, power) and select the most idle GPUs
15
+ based on configurable criteria. It safely handles the absence or initialization failure of the pynvml library by
16
+ logging warnings and disabling related features, preventing application crashes.
18
17
 
19
18
  Includes fallback logic using `torch.cuda` for basic device counting if NVML is unavailable during GPU
20
19
  selection. Manages NVML initialization and shutdown internally.
21
20
 
22
21
  Attributes:
23
22
  pynvml (module | None): The `pynvml` module if successfully imported and initialized, otherwise `None`.
24
- nvml_available (bool): Indicates if `pynvml` is ready for use. True if import and `nvmlInit()` succeeded,
25
- False otherwise.
26
- gpu_stats (list[dict[str, Any]]): A list of dictionaries, each holding stats for one GPU. Populated on
27
- initialization and by `refresh_stats()`. Keys include: 'index', 'name', 'utilization' (%),
28
- 'memory_used' (MiB), 'memory_total' (MiB), 'memory_free' (MiB), 'temperature' (C), 'power_draw' (W),
29
- 'power_limit' (W or 'N/A'). Empty if NVML is unavailable or queries fail.
23
+ nvml_available (bool): Indicates if `pynvml` is ready for use. True if import and `nvmlInit()` succeeded, False
24
+ otherwise.
25
+ gpu_stats (list[dict[str, Any]]): A list of dictionaries, each holding stats for one GPU, populated on
26
+ initialization and by `refresh_stats()`. Keys include: 'index', 'name', 'utilization' (%), 'memory_used' (MiB),
27
+ 'memory_total' (MiB), 'memory_free' (MiB), 'temperature' (C), 'power_draw' (W), 'power_limit' (W or 'N/A').
28
+ Empty if NVML is unavailable or queries fail.
30
29
 
31
30
  Methods:
32
31
  refresh_stats: Refresh the internal gpu_stats list by querying NVML.
@@ -137,8 +136,7 @@ class GPUInfo:
137
136
  def select_idle_gpu(
138
137
  self, count: int = 1, min_memory_fraction: float = 0, min_util_fraction: float = 0
139
138
  ) -> list[int]:
140
- """
141
- Select the most idle GPUs based on utilization and free memory.
139
+ """Select the most idle GPUs based on utilization and free memory.
142
140
 
143
141
  Args:
144
142
  count (int): The number of idle GPUs to select.
@@ -154,9 +152,10 @@ class GPUInfo:
154
152
  """
155
153
  assert min_memory_fraction <= 1.0, f"min_memory_fraction must be <= 1.0, got {min_memory_fraction}"
156
154
  assert min_util_fraction <= 1.0, f"min_util_fraction must be <= 1.0, got {min_util_fraction}"
157
- LOGGER.info(
158
- f"Searching for {count} idle GPUs with free memory >= {min_memory_fraction * 100:.1f}% and free utilization >= {min_util_fraction * 100:.1f}%..."
155
+ criteria = (
156
+ f"free memory >= {min_memory_fraction * 100:.1f}% and free utilization >= {min_util_fraction * 100:.1f}%"
159
157
  )
158
+ LOGGER.info(f"Searching for {count} idle GPUs with {criteria}...")
160
159
 
161
160
  if count <= 0:
162
161
  return []
@@ -179,11 +178,11 @@ class GPUInfo:
179
178
  selected = [gpu["index"] for gpu in eligible_gpus[:count]]
180
179
 
181
180
  if selected:
181
+ if len(selected) < count:
182
+ LOGGER.warning(f"Requested {count} GPUs but only {len(selected)} met the idle criteria.")
182
183
  LOGGER.info(f"Selected idle CUDA devices {selected}")
183
184
  else:
184
- LOGGER.warning(
185
- f"No GPUs met criteria (Free Mem >= {min_memory_fraction * 100:.1f}% and Free Util >= {min_util_fraction * 100:.1f}%)."
186
- )
185
+ LOGGER.warning(f"No GPUs met criteria ({criteria}).")
187
186
 
188
187
  return selected
189
188
 
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
  """
3
- Benchmark a YOLO model formats for speed and accuracy.
3
+ Benchmark YOLO model formats for speed and accuracy.
4
4
 
5
5
  Usage:
6
6
  from ultralytics.utils.benchmarks import ProfileModels, benchmark
@@ -25,6 +25,7 @@ MNN | `mnn` | yolo11n.mnn
25
25
  NCNN | `ncnn` | yolo11n_ncnn_model/
26
26
  IMX | `imx` | yolo11n_imx_model/
27
27
  RKNN | `rknn` | yolo11n_rknn_model/
28
+ ExecuTorch | `executorch` | yolo11n_executorch_model/
28
29
  """
29
30
 
30
31
  from __future__ import annotations
@@ -43,7 +44,7 @@ import torch.cuda
43
44
  from ultralytics import YOLO, YOLOWorld
44
45
  from ultralytics.cfg import TASK2DATA, TASK2METRIC
45
46
  from ultralytics.engine.exporter import export_formats
46
- from ultralytics.utils import ARM64, ASSETS, IS_JETSON, LINUX, LOGGER, MACOS, TQDM, WEIGHTS_DIR, YAML
47
+ from ultralytics.utils import ARM64, ASSETS, ASSETS_URL, IS_JETSON, LINUX, LOGGER, MACOS, TQDM, WEIGHTS_DIR, YAML
47
48
  from ultralytics.utils.checks import IS_PYTHON_3_13, check_imgsz, check_requirements, check_yolo, is_rockchip
48
49
  from ultralytics.utils.downloads import safe_download
49
50
  from ultralytics.utils.files import file_size
@@ -62,8 +63,7 @@ def benchmark(
62
63
  format="",
63
64
  **kwargs,
64
65
  ):
65
- """
66
- Benchmark a YOLO model across different formats for speed and accuracy.
66
+ """Benchmark a YOLO model across different formats for speed and accuracy.
67
67
 
68
68
  Args:
69
69
  model (str | Path): Path to the model file or directory.
@@ -78,8 +78,8 @@ def benchmark(
78
78
  **kwargs (Any): Additional keyword arguments for exporter.
79
79
 
80
80
  Returns:
81
- (polars.DataFrame): A polars DataFrame with benchmark results for each format, including file size, metric,
82
- and inference time.
81
+ (polars.DataFrame): A Polars DataFrame with benchmark results for each format, including file size, metric, and
82
+ inference time.
83
83
 
84
84
  Examples:
85
85
  Benchmark a YOLO model with default settings:
@@ -144,13 +144,18 @@ def benchmark(
144
144
  if format == "imx":
145
145
  assert not is_end2end
146
146
  assert not isinstance(model, YOLOWorld), "YOLOWorldv2 IMX exports not supported"
147
- assert model.task == "detect", "IMX only supported for detection task"
148
- assert "C2f" in model.__str__(), "IMX only supported for YOLOv8" # TODO: enable for YOLO11
147
+ assert model.task in {"detect", "classify", "pose"}, (
148
+ "IMX export is only supported for detection, classification and pose estimation tasks"
149
+ )
150
+ assert "C2f" in model.__str__(), "IMX only supported for YOLOv8n and YOLO11n"
149
151
  if format == "rknn":
150
152
  assert not isinstance(model, YOLOWorld), "YOLOWorldv2 RKNN exports not supported yet"
151
153
  assert not is_end2end, "End-to-end models not supported by RKNN yet"
152
154
  assert LINUX, "RKNN only supported on Linux"
153
155
  assert not is_rockchip(), "RKNN Inference only supported on Rockchip devices"
156
+ if format == "executorch":
157
+ assert not isinstance(model, YOLOWorld), "YOLOWorldv2 ExecuTorch exports not supported yet"
158
+ assert not is_end2end, "End-to-end models not supported by ExecuTorch yet"
154
159
  if "cpu" in device.type:
155
160
  assert cpu, "inference not supported on CPU"
156
161
  if "cuda" in device.type:
@@ -170,6 +175,7 @@ def benchmark(
170
175
 
171
176
  # Predict
172
177
  assert model.task != "pose" or format != "pb", "GraphDef Pose inference is not supported"
178
+ assert model.task != "pose" or format != "executorch", "ExecuTorch Pose inference is not supported"
173
179
  assert format not in {"edgetpu", "tfjs"}, "inference not supported"
174
180
  assert format != "coreml" or platform.system() == "Darwin", "inference only supported on macOS>=10.13"
175
181
  if format == "ncnn":
@@ -220,8 +226,7 @@ def benchmark(
220
226
 
221
227
 
222
228
  class RF100Benchmark:
223
- """
224
- Benchmark YOLO model performance across various formats for speed and accuracy.
229
+ """Benchmark YOLO model performance across various formats for speed and accuracy.
225
230
 
226
231
  This class provides functionality to benchmark YOLO models on the RF100 dataset collection.
227
232
 
@@ -246,8 +251,7 @@ class RF100Benchmark:
246
251
  self.val_metrics = ["class", "images", "targets", "precision", "recall", "map50", "map95"]
247
252
 
248
253
  def set_key(self, api_key: str):
249
- """
250
- Set Roboflow API key for processing.
254
+ """Set Roboflow API key for processing.
251
255
 
252
256
  Args:
253
257
  api_key (str): The API key.
@@ -263,8 +267,7 @@ class RF100Benchmark:
263
267
  self.rf = Roboflow(api_key=api_key)
264
268
 
265
269
  def parse_dataset(self, ds_link_txt: str = "datasets_links.txt"):
266
- """
267
- Parse dataset links and download datasets.
270
+ """Parse dataset links and download datasets.
268
271
 
269
272
  Args:
270
273
  ds_link_txt (str): Path to the file containing dataset links.
@@ -281,12 +284,12 @@ class RF100Benchmark:
281
284
  (shutil.rmtree("rf-100"), os.mkdir("rf-100")) if os.path.exists("rf-100") else os.mkdir("rf-100")
282
285
  os.chdir("rf-100")
283
286
  os.mkdir("ultralytics-benchmarks")
284
- safe_download("https://github.com/ultralytics/assets/releases/download/v0.0.0/datasets_links.txt")
287
+ safe_download(f"{ASSETS_URL}/datasets_links.txt")
285
288
 
286
289
  with open(ds_link_txt, encoding="utf-8") as file:
287
290
  for line in file:
288
291
  try:
289
- _, url, workspace, project, version = re.split("/+", line.strip())
292
+ _, _url, workspace, project, version = re.split("/+", line.strip())
290
293
  self.ds_names.append(project)
291
294
  proj_version = f"{project}-{version}"
292
295
  if not Path(proj_version).exists():
@@ -308,8 +311,7 @@ class RF100Benchmark:
308
311
  YAML.dump(yaml_data, path)
309
312
 
310
313
  def evaluate(self, yaml_path: str, val_log_file: str, eval_log_file: str, list_ind: int):
311
- """
312
- Evaluate model performance on validation results.
314
+ """Evaluate model performance on validation results.
313
315
 
314
316
  Args:
315
317
  yaml_path (str): Path to the YAML configuration file.
@@ -357,7 +359,7 @@ class RF100Benchmark:
357
359
  map_val = lst["map50"]
358
360
  else:
359
361
  LOGGER.info("Single dict found")
360
- map_val = [res["map50"] for res in eval_lines][0]
362
+ map_val = next(res["map50"] for res in eval_lines)
361
363
 
362
364
  with open(eval_log_file, "a", encoding="utf-8") as f:
363
365
  f.write(f"{self.ds_names[list_ind]}: {map_val}\n")
@@ -366,8 +368,7 @@ class RF100Benchmark:
366
368
 
367
369
 
368
370
  class ProfileModels:
369
- """
370
- ProfileModels class for profiling different models on ONNX and TensorRT.
371
+ """ProfileModels class for profiling different models on ONNX and TensorRT.
371
372
 
372
373
  This class profiles the performance of different models, returning results such as model speed and FLOPs.
373
374
 
@@ -410,8 +411,7 @@ class ProfileModels:
410
411
  trt: bool = True,
411
412
  device: torch.device | str | None = None,
412
413
  ):
413
- """
414
- Initialize the ProfileModels class for profiling models.
414
+ """Initialize the ProfileModels class for profiling models.
415
415
 
416
416
  Args:
417
417
  paths (list[str]): List of paths of the models to be profiled.
@@ -425,12 +425,6 @@ class ProfileModels:
425
425
 
426
426
  Notes:
427
427
  FP16 'half' argument option removed for ONNX as slower on CPU than FP32.
428
-
429
- Examples:
430
- Initialize and profile models
431
- >>> from ultralytics.utils.benchmarks import ProfileModels
432
- >>> profiler = ProfileModels(["yolo11n.yaml", "yolov8s.yaml"], imgsz=640)
433
- >>> profiler.run()
434
428
  """
435
429
  self.paths = paths
436
430
  self.num_timed_runs = num_timed_runs
@@ -442,8 +436,7 @@ class ProfileModels:
442
436
  self.device = device if isinstance(device, torch.device) else select_device(device)
443
437
 
444
438
  def run(self):
445
- """
446
- Profile YOLO models for speed and accuracy across various formats including ONNX and TensorRT.
439
+ """Profile YOLO models for speed and accuracy across various formats including ONNX and TensorRT.
447
440
 
448
441
  Returns:
449
442
  (list[dict]): List of dictionaries containing profiling results for each model.
@@ -497,8 +490,7 @@ class ProfileModels:
497
490
  return output
498
491
 
499
492
  def get_files(self):
500
- """
501
- Return a list of paths for all relevant model files given by the user.
493
+ """Return a list of paths for all relevant model files given by the user.
502
494
 
503
495
  Returns:
504
496
  (list[Path]): List of Path objects for the model files.
@@ -524,8 +516,7 @@ class ProfileModels:
524
516
 
525
517
  @staticmethod
526
518
  def iterative_sigma_clipping(data: np.ndarray, sigma: float = 2, max_iters: int = 3):
527
- """
528
- Apply iterative sigma clipping to data to remove outliers.
519
+ """Apply iterative sigma clipping to data to remove outliers.
529
520
 
530
521
  Args:
531
522
  data (np.ndarray): Input data array.
@@ -545,8 +536,7 @@ class ProfileModels:
545
536
  return data
546
537
 
547
538
  def profile_tensorrt_model(self, engine_file: str, eps: float = 1e-3):
548
- """
549
- Profile YOLO model performance with TensorRT, measuring average run time and standard deviation.
539
+ """Profile YOLO model performance with TensorRT, measuring average run time and standard deviation.
550
540
 
551
541
  Args:
552
542
  engine_file (str): Path to the TensorRT engine file.
@@ -583,9 +573,13 @@ class ProfileModels:
583
573
  run_times = self.iterative_sigma_clipping(np.array(run_times), sigma=2, max_iters=3) # sigma clipping
584
574
  return np.mean(run_times), np.std(run_times)
585
575
 
576
+ @staticmethod
577
+ def check_dynamic(tensor_shape):
578
+ """Check whether the tensor shape in the ONNX model is dynamic."""
579
+ return not all(isinstance(dim, int) and dim >= 0 for dim in tensor_shape)
580
+
586
581
  def profile_onnx_model(self, onnx_file: str, eps: float = 1e-3):
587
- """
588
- Profile an ONNX model, measuring average inference time and standard deviation across multiple runs.
582
+ """Profile an ONNX model, measuring average inference time and standard deviation across multiple runs.
589
583
 
590
584
  Args:
591
585
  onnx_file (str): Path to the ONNX model file.
@@ -595,7 +589,7 @@ class ProfileModels:
595
589
  mean_time (float): Mean inference time in milliseconds.
596
590
  std_time (float): Standard deviation of inference time in milliseconds.
597
591
  """
598
- check_requirements("onnxruntime")
592
+ check_requirements([("onnxruntime", "onnxruntime-gpu")]) # either package meets requirements
599
593
  import onnxruntime as ort
600
594
 
601
595
  # Session with either 'TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider'
@@ -604,27 +598,36 @@ class ProfileModels:
604
598
  sess_options.intra_op_num_threads = 8 # Limit the number of threads
605
599
  sess = ort.InferenceSession(onnx_file, sess_options, providers=["CPUExecutionProvider"])
606
600
 
607
- input_tensor = sess.get_inputs()[0]
608
- input_type = input_tensor.type
609
- dynamic = not all(isinstance(dim, int) and dim >= 0 for dim in input_tensor.shape) # dynamic input shape
610
- input_shape = (1, 3, self.imgsz, self.imgsz) if dynamic else input_tensor.shape
611
-
612
- # Mapping ONNX datatype to numpy datatype
613
- if "float16" in input_type:
614
- input_dtype = np.float16
615
- elif "float" in input_type:
616
- input_dtype = np.float32
617
- elif "double" in input_type:
618
- input_dtype = np.float64
619
- elif "int64" in input_type:
620
- input_dtype = np.int64
621
- elif "int32" in input_type:
622
- input_dtype = np.int32
623
- else:
624
- raise ValueError(f"Unsupported ONNX datatype {input_type}")
601
+ input_data_dict = {}
602
+ for input_tensor in sess.get_inputs():
603
+ input_type = input_tensor.type
604
+ if self.check_dynamic(input_tensor.shape):
605
+ if len(input_tensor.shape) != 4 and self.check_dynamic(input_tensor.shape[1:]):
606
+ raise ValueError(f"Unsupported dynamic shape {input_tensor.shape} of {input_tensor.name}")
607
+ input_shape = (
608
+ (1, 3, self.imgsz, self.imgsz) if len(input_tensor.shape) == 4 else (1, *input_tensor.shape[1:])
609
+ )
610
+ else:
611
+ input_shape = input_tensor.shape
612
+
613
+ # Mapping ONNX datatype to numpy datatype
614
+ if "float16" in input_type:
615
+ input_dtype = np.float16
616
+ elif "float" in input_type:
617
+ input_dtype = np.float32
618
+ elif "double" in input_type:
619
+ input_dtype = np.float64
620
+ elif "int64" in input_type:
621
+ input_dtype = np.int64
622
+ elif "int32" in input_type:
623
+ input_dtype = np.int32
624
+ else:
625
+ raise ValueError(f"Unsupported ONNX datatype {input_type}")
626
+
627
+ input_data = np.random.rand(*input_shape).astype(input_dtype)
628
+ input_name = input_tensor.name
629
+ input_data_dict[input_name] = input_data
625
630
 
626
- input_data = np.random.rand(*input_shape).astype(input_dtype)
627
- input_name = input_tensor.name
628
631
  output_name = sess.get_outputs()[0].name
629
632
 
630
633
  # Warmup runs
@@ -632,7 +635,7 @@ class ProfileModels:
632
635
  for _ in range(3):
633
636
  start_time = time.time()
634
637
  for _ in range(self.num_warmup_runs):
635
- sess.run([output_name], {input_name: input_data})
638
+ sess.run([output_name], input_data_dict)
636
639
  elapsed = time.time() - start_time
637
640
 
638
641
  # Compute number of runs as higher of min_time or num_timed_runs
@@ -642,7 +645,7 @@ class ProfileModels:
642
645
  run_times = []
643
646
  for _ in TQDM(range(num_runs), desc=onnx_file):
644
647
  start_time = time.time()
645
- sess.run([output_name], {input_name: input_data})
648
+ sess.run([output_name], input_data_dict)
646
649
  run_times.append((time.time() - start_time) * 1000) # Convert to milliseconds
647
650
 
648
651
  run_times = self.iterative_sigma_clipping(np.array(run_times), sigma=2, max_iters=5) # sigma clipping
@@ -655,8 +658,7 @@ class ProfileModels:
655
658
  t_engine: tuple[float, float],
656
659
  model_info: tuple[float, float, float, float],
657
660
  ):
658
- """
659
- Generate a table row string with model performance metrics.
661
+ """Generate a table row string with model performance metrics.
660
662
 
661
663
  Args:
662
664
  model_name (str): Name of the model.
@@ -667,7 +669,7 @@ class ProfileModels:
667
669
  Returns:
668
670
  (str): Formatted table row string with model metrics.
669
671
  """
670
- layers, params, gradients, flops = model_info
672
+ _layers, params, _gradients, flops = model_info
671
673
  return (
672
674
  f"| {model_name:18s} | {self.imgsz} | - | {t_onnx[0]:.1f}±{t_onnx[1]:.1f} ms | {t_engine[0]:.1f}±"
673
675
  f"{t_engine[1]:.1f} ms | {params / 1e6:.1f} | {flops:.1f} |"
@@ -680,8 +682,7 @@ class ProfileModels:
680
682
  t_engine: tuple[float, float],
681
683
  model_info: tuple[float, float, float, float],
682
684
  ):
683
- """
684
- Generate a dictionary of profiling results.
685
+ """Generate a dictionary of profiling results.
685
686
 
686
687
  Args:
687
688
  model_name (str): Name of the model.
@@ -692,7 +693,7 @@ class ProfileModels:
692
693
  Returns:
693
694
  (dict): Dictionary containing profiling results.
694
695
  """
695
- layers, params, gradients, flops = model_info
696
+ _layers, params, _gradients, flops = model_info
696
697
  return {
697
698
  "model/name": model_name,
698
699
  "model/parameters": params,
@@ -703,8 +704,7 @@ class ProfileModels:
703
704
 
704
705
  @staticmethod
705
706
  def print_table(table_rows: list[str]):
706
- """
707
- Print a formatted table of model profiling results.
707
+ """Print a formatted table of model profiling results.
708
708
 
709
709
  Args:
710
710
  table_rows (list[str]): List of formatted table row strings.
@@ -175,13 +175,12 @@ default_callbacks = {
175
175
 
176
176
 
177
177
  def get_default_callbacks():
178
- """
179
- Get the default callbacks for Ultralytics training, validation, prediction, and export processes.
178
+ """Get the default callbacks for Ultralytics training, validation, prediction, and export processes.
180
179
 
181
180
  Returns:
182
181
  (dict): Dictionary of default callbacks for various training events. Each key represents an event during the
183
- training process, and the corresponding value is a list of callback functions executed when that event
184
- occurs.
182
+ training process, and the corresponding value is a list of callback functions executed when that
183
+ event occurs.
185
184
 
186
185
  Examples:
187
186
  >>> callbacks = get_default_callbacks()
@@ -192,17 +191,16 @@ def get_default_callbacks():
192
191
 
193
192
 
194
193
  def add_integration_callbacks(instance):
195
- """
196
- Add integration callbacks to the instance's callbacks dictionary.
194
+ """Add integration callbacks to the instance's callbacks dictionary.
197
195
 
198
196
  This function loads and adds various integration callbacks to the provided instance. The specific callbacks added
199
197
  depend on the type of instance provided. All instances receive HUB callbacks, while Trainer instances also receive
200
- additional callbacks for various integrations like ClearML, Comet, DVC, MLflow, Neptune, Ray Tune, TensorBoard,
201
- and Weights & Biases.
198
+ additional callbacks for various integrations like ClearML, Comet, DVC, MLflow, Neptune, Ray Tune, TensorBoard, and
199
+ Weights & Biases.
202
200
 
203
201
  Args:
204
- instance (Trainer | Predictor | Validator | Exporter): The object instance to which callbacks will be added.
205
- The type of instance determines which callbacks are loaded.
202
+ instance (Trainer | Predictor | Validator | Exporter): The object instance to which callbacks will be added. The
203
+ type of instance determines which callbacks are loaded.
206
204
 
207
205
  Examples:
208
206
  >>> from ultralytics.engine.trainer import BaseTrainer
@@ -15,8 +15,7 @@ except (ImportError, AssertionError):
15
15
 
16
16
 
17
17
  def _log_debug_samples(files, title: str = "Debug Samples") -> None:
18
- """
19
- Log files (images) as debug samples in the ClearML task.
18
+ """Log files (images) as debug samples in the ClearML task.
20
19
 
21
20
  Args:
22
21
  files (list[Path]): A list of file paths in PosixPath format.
@@ -35,8 +34,7 @@ def _log_debug_samples(files, title: str = "Debug Samples") -> None:
35
34
 
36
35
 
37
36
  def _log_plot(title: str, plot_path: str) -> None:
38
- """
39
- Log an image as a plot in the plot section of ClearML.
37
+ """Log an image as a plot in the plot section of ClearML.
40
38
 
41
39
  Args:
42
40
  title (str): The title of the plot.
@@ -125,15 +123,9 @@ def on_train_end(trainer) -> None:
125
123
  """Log final model and training results on training completion."""
126
124
  if task := Task.current_task():
127
125
  # Log final results, confusion matrix and PR plots
128
- files = [
129
- "results.png",
130
- "confusion_matrix.png",
131
- "confusion_matrix_normalized.png",
132
- *(f"{x}_curve.png" for x in ("F1", "PR", "P", "R")),
133
- ]
134
- files = [(trainer.save_dir / f) for f in files if (trainer.save_dir / f).exists()] # filter existing files
135
- for f in files:
136
- _log_plot(title=f.stem, plot_path=f)
126
+ for f in [*trainer.plots.keys(), *trainer.validator.plots.keys()]:
127
+ if "batch" not in f.name:
128
+ _log_plot(title=f.stem, plot_path=f)
137
129
  # Report final metrics
138
130
  for k, v in trainer.validator.metrics.results_dict.items():
139
131
  task.get_logger().report_single_value(k, v)