dgenerate-ultralytics-headless 8.3.214__py3-none-any.whl → 8.4.7__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 (249) hide show
  1. {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/METADATA +64 -74
  2. dgenerate_ultralytics_headless-8.4.7.dist-info/RECORD +311 -0
  3. {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/WHEEL +1 -1
  4. tests/__init__.py +7 -9
  5. tests/conftest.py +8 -15
  6. tests/test_cli.py +1 -1
  7. tests/test_cuda.py +13 -10
  8. tests/test_engine.py +9 -9
  9. tests/test_exports.py +65 -13
  10. tests/test_integrations.py +13 -13
  11. tests/test_python.py +125 -69
  12. tests/test_solutions.py +161 -152
  13. ultralytics/__init__.py +1 -1
  14. ultralytics/cfg/__init__.py +86 -92
  15. ultralytics/cfg/datasets/Argoverse.yaml +7 -6
  16. ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
  17. ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
  18. ultralytics/cfg/datasets/ImageNet.yaml +1 -1
  19. ultralytics/cfg/datasets/TT100K.yaml +346 -0
  20. ultralytics/cfg/datasets/VOC.yaml +15 -16
  21. ultralytics/cfg/datasets/african-wildlife.yaml +1 -1
  22. ultralytics/cfg/datasets/coco-pose.yaml +21 -0
  23. ultralytics/cfg/datasets/coco12-formats.yaml +101 -0
  24. ultralytics/cfg/datasets/coco128-seg.yaml +1 -1
  25. ultralytics/cfg/datasets/coco8-pose.yaml +21 -0
  26. ultralytics/cfg/datasets/dog-pose.yaml +28 -0
  27. ultralytics/cfg/datasets/dota8-multispectral.yaml +1 -1
  28. ultralytics/cfg/datasets/dota8.yaml +2 -2
  29. ultralytics/cfg/datasets/hand-keypoints.yaml +26 -2
  30. ultralytics/cfg/datasets/kitti.yaml +27 -0
  31. ultralytics/cfg/datasets/lvis.yaml +5 -5
  32. ultralytics/cfg/datasets/open-images-v7.yaml +1 -1
  33. ultralytics/cfg/datasets/tiger-pose.yaml +16 -0
  34. ultralytics/cfg/datasets/xView.yaml +16 -16
  35. ultralytics/cfg/default.yaml +4 -2
  36. ultralytics/cfg/models/11/yolo11-pose.yaml +1 -1
  37. ultralytics/cfg/models/11/yoloe-11-seg.yaml +2 -2
  38. ultralytics/cfg/models/11/yoloe-11.yaml +2 -2
  39. ultralytics/cfg/models/26/yolo26-cls.yaml +33 -0
  40. ultralytics/cfg/models/26/yolo26-obb.yaml +52 -0
  41. ultralytics/cfg/models/26/yolo26-p2.yaml +60 -0
  42. ultralytics/cfg/models/26/yolo26-p6.yaml +62 -0
  43. ultralytics/cfg/models/26/yolo26-pose.yaml +53 -0
  44. ultralytics/cfg/models/26/yolo26-seg.yaml +52 -0
  45. ultralytics/cfg/models/26/yolo26.yaml +52 -0
  46. ultralytics/cfg/models/26/yoloe-26-seg.yaml +53 -0
  47. ultralytics/cfg/models/26/yoloe-26.yaml +53 -0
  48. ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +1 -1
  49. ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +1 -1
  50. ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +1 -1
  51. ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +1 -1
  52. ultralytics/cfg/models/v10/yolov10b.yaml +2 -2
  53. ultralytics/cfg/models/v10/yolov10l.yaml +2 -2
  54. ultralytics/cfg/models/v10/yolov10m.yaml +2 -2
  55. ultralytics/cfg/models/v10/yolov10n.yaml +2 -2
  56. ultralytics/cfg/models/v10/yolov10s.yaml +2 -2
  57. ultralytics/cfg/models/v10/yolov10x.yaml +2 -2
  58. ultralytics/cfg/models/v3/yolov3-tiny.yaml +1 -1
  59. ultralytics/cfg/models/v6/yolov6.yaml +1 -1
  60. ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +9 -6
  61. ultralytics/cfg/models/v8/yoloe-v8.yaml +9 -6
  62. ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +1 -1
  63. ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +1 -1
  64. ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +2 -2
  65. ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +2 -2
  66. ultralytics/cfg/models/v8/yolov8-ghost.yaml +2 -2
  67. ultralytics/cfg/models/v8/yolov8-obb.yaml +1 -1
  68. ultralytics/cfg/models/v8/yolov8-p2.yaml +1 -1
  69. ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +1 -1
  70. ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +1 -1
  71. ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +1 -1
  72. ultralytics/cfg/models/v8/yolov8-world.yaml +1 -1
  73. ultralytics/cfg/models/v8/yolov8-worldv2.yaml +6 -6
  74. ultralytics/cfg/models/v9/yolov9s.yaml +1 -1
  75. ultralytics/data/__init__.py +4 -4
  76. ultralytics/data/annotator.py +5 -6
  77. ultralytics/data/augment.py +300 -475
  78. ultralytics/data/base.py +18 -26
  79. ultralytics/data/build.py +147 -25
  80. ultralytics/data/converter.py +108 -87
  81. ultralytics/data/dataset.py +47 -75
  82. ultralytics/data/loaders.py +42 -49
  83. ultralytics/data/split.py +5 -6
  84. ultralytics/data/split_dota.py +8 -15
  85. ultralytics/data/utils.py +36 -45
  86. ultralytics/engine/exporter.py +351 -263
  87. ultralytics/engine/model.py +186 -225
  88. ultralytics/engine/predictor.py +45 -54
  89. ultralytics/engine/results.py +198 -325
  90. ultralytics/engine/trainer.py +165 -106
  91. ultralytics/engine/tuner.py +41 -43
  92. ultralytics/engine/validator.py +55 -38
  93. ultralytics/hub/__init__.py +16 -19
  94. ultralytics/hub/auth.py +6 -12
  95. ultralytics/hub/google/__init__.py +7 -10
  96. ultralytics/hub/session.py +15 -25
  97. ultralytics/hub/utils.py +5 -8
  98. ultralytics/models/__init__.py +1 -1
  99. ultralytics/models/fastsam/__init__.py +1 -1
  100. ultralytics/models/fastsam/model.py +8 -10
  101. ultralytics/models/fastsam/predict.py +18 -30
  102. ultralytics/models/fastsam/utils.py +1 -2
  103. ultralytics/models/fastsam/val.py +5 -7
  104. ultralytics/models/nas/__init__.py +1 -1
  105. ultralytics/models/nas/model.py +5 -8
  106. ultralytics/models/nas/predict.py +7 -9
  107. ultralytics/models/nas/val.py +1 -2
  108. ultralytics/models/rtdetr/__init__.py +1 -1
  109. ultralytics/models/rtdetr/model.py +5 -8
  110. ultralytics/models/rtdetr/predict.py +15 -19
  111. ultralytics/models/rtdetr/train.py +10 -13
  112. ultralytics/models/rtdetr/val.py +21 -23
  113. ultralytics/models/sam/__init__.py +15 -2
  114. ultralytics/models/sam/amg.py +14 -20
  115. ultralytics/models/sam/build.py +26 -19
  116. ultralytics/models/sam/build_sam3.py +377 -0
  117. ultralytics/models/sam/model.py +29 -32
  118. ultralytics/models/sam/modules/blocks.py +83 -144
  119. ultralytics/models/sam/modules/decoders.py +19 -37
  120. ultralytics/models/sam/modules/encoders.py +44 -101
  121. ultralytics/models/sam/modules/memory_attention.py +16 -30
  122. ultralytics/models/sam/modules/sam.py +200 -73
  123. ultralytics/models/sam/modules/tiny_encoder.py +64 -83
  124. ultralytics/models/sam/modules/transformer.py +18 -28
  125. ultralytics/models/sam/modules/utils.py +174 -50
  126. ultralytics/models/sam/predict.py +2248 -350
  127. ultralytics/models/sam/sam3/__init__.py +3 -0
  128. ultralytics/models/sam/sam3/decoder.py +546 -0
  129. ultralytics/models/sam/sam3/encoder.py +529 -0
  130. ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
  131. ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
  132. ultralytics/models/sam/sam3/model_misc.py +199 -0
  133. ultralytics/models/sam/sam3/necks.py +129 -0
  134. ultralytics/models/sam/sam3/sam3_image.py +339 -0
  135. ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
  136. ultralytics/models/sam/sam3/vitdet.py +547 -0
  137. ultralytics/models/sam/sam3/vl_combiner.py +160 -0
  138. ultralytics/models/utils/loss.py +14 -26
  139. ultralytics/models/utils/ops.py +13 -17
  140. ultralytics/models/yolo/__init__.py +1 -1
  141. ultralytics/models/yolo/classify/predict.py +10 -13
  142. ultralytics/models/yolo/classify/train.py +12 -33
  143. ultralytics/models/yolo/classify/val.py +30 -29
  144. ultralytics/models/yolo/detect/predict.py +9 -12
  145. ultralytics/models/yolo/detect/train.py +17 -23
  146. ultralytics/models/yolo/detect/val.py +77 -59
  147. ultralytics/models/yolo/model.py +43 -60
  148. ultralytics/models/yolo/obb/predict.py +7 -16
  149. ultralytics/models/yolo/obb/train.py +14 -17
  150. ultralytics/models/yolo/obb/val.py +40 -37
  151. ultralytics/models/yolo/pose/__init__.py +1 -1
  152. ultralytics/models/yolo/pose/predict.py +7 -22
  153. ultralytics/models/yolo/pose/train.py +13 -16
  154. ultralytics/models/yolo/pose/val.py +39 -58
  155. ultralytics/models/yolo/segment/predict.py +17 -21
  156. ultralytics/models/yolo/segment/train.py +7 -10
  157. ultralytics/models/yolo/segment/val.py +95 -47
  158. ultralytics/models/yolo/world/train.py +8 -14
  159. ultralytics/models/yolo/world/train_world.py +11 -34
  160. ultralytics/models/yolo/yoloe/__init__.py +7 -7
  161. ultralytics/models/yolo/yoloe/predict.py +16 -23
  162. ultralytics/models/yolo/yoloe/train.py +36 -44
  163. ultralytics/models/yolo/yoloe/train_seg.py +11 -11
  164. ultralytics/models/yolo/yoloe/val.py +15 -20
  165. ultralytics/nn/__init__.py +7 -7
  166. ultralytics/nn/autobackend.py +159 -85
  167. ultralytics/nn/modules/__init__.py +68 -60
  168. ultralytics/nn/modules/activation.py +4 -6
  169. ultralytics/nn/modules/block.py +260 -224
  170. ultralytics/nn/modules/conv.py +52 -97
  171. ultralytics/nn/modules/head.py +831 -299
  172. ultralytics/nn/modules/transformer.py +76 -88
  173. ultralytics/nn/modules/utils.py +16 -21
  174. ultralytics/nn/tasks.py +180 -195
  175. ultralytics/nn/text_model.py +45 -69
  176. ultralytics/optim/__init__.py +5 -0
  177. ultralytics/optim/muon.py +338 -0
  178. ultralytics/solutions/__init__.py +12 -12
  179. ultralytics/solutions/ai_gym.py +13 -19
  180. ultralytics/solutions/analytics.py +15 -16
  181. ultralytics/solutions/config.py +6 -7
  182. ultralytics/solutions/distance_calculation.py +10 -13
  183. ultralytics/solutions/heatmap.py +8 -14
  184. ultralytics/solutions/instance_segmentation.py +6 -9
  185. ultralytics/solutions/object_blurrer.py +7 -10
  186. ultralytics/solutions/object_counter.py +12 -19
  187. ultralytics/solutions/object_cropper.py +8 -14
  188. ultralytics/solutions/parking_management.py +34 -32
  189. ultralytics/solutions/queue_management.py +10 -12
  190. ultralytics/solutions/region_counter.py +9 -12
  191. ultralytics/solutions/security_alarm.py +15 -20
  192. ultralytics/solutions/similarity_search.py +10 -15
  193. ultralytics/solutions/solutions.py +77 -76
  194. ultralytics/solutions/speed_estimation.py +7 -10
  195. ultralytics/solutions/streamlit_inference.py +2 -4
  196. ultralytics/solutions/templates/similarity-search.html +7 -18
  197. ultralytics/solutions/trackzone.py +7 -10
  198. ultralytics/solutions/vision_eye.py +5 -8
  199. ultralytics/trackers/__init__.py +1 -1
  200. ultralytics/trackers/basetrack.py +3 -5
  201. ultralytics/trackers/bot_sort.py +10 -27
  202. ultralytics/trackers/byte_tracker.py +21 -37
  203. ultralytics/trackers/track.py +4 -7
  204. ultralytics/trackers/utils/gmc.py +11 -22
  205. ultralytics/trackers/utils/kalman_filter.py +37 -48
  206. ultralytics/trackers/utils/matching.py +12 -15
  207. ultralytics/utils/__init__.py +124 -124
  208. ultralytics/utils/autobatch.py +2 -4
  209. ultralytics/utils/autodevice.py +17 -18
  210. ultralytics/utils/benchmarks.py +57 -71
  211. ultralytics/utils/callbacks/base.py +8 -10
  212. ultralytics/utils/callbacks/clearml.py +5 -13
  213. ultralytics/utils/callbacks/comet.py +32 -46
  214. ultralytics/utils/callbacks/dvc.py +13 -18
  215. ultralytics/utils/callbacks/mlflow.py +4 -5
  216. ultralytics/utils/callbacks/neptune.py +7 -15
  217. ultralytics/utils/callbacks/platform.py +423 -38
  218. ultralytics/utils/callbacks/raytune.py +3 -4
  219. ultralytics/utils/callbacks/tensorboard.py +25 -31
  220. ultralytics/utils/callbacks/wb.py +16 -14
  221. ultralytics/utils/checks.py +127 -85
  222. ultralytics/utils/cpu.py +3 -8
  223. ultralytics/utils/dist.py +9 -12
  224. ultralytics/utils/downloads.py +25 -33
  225. ultralytics/utils/errors.py +6 -14
  226. ultralytics/utils/events.py +2 -4
  227. ultralytics/utils/export/__init__.py +4 -236
  228. ultralytics/utils/export/engine.py +246 -0
  229. ultralytics/utils/export/imx.py +117 -63
  230. ultralytics/utils/export/tensorflow.py +231 -0
  231. ultralytics/utils/files.py +26 -30
  232. ultralytics/utils/git.py +9 -11
  233. ultralytics/utils/instance.py +30 -51
  234. ultralytics/utils/logger.py +212 -114
  235. ultralytics/utils/loss.py +601 -215
  236. ultralytics/utils/metrics.py +128 -156
  237. ultralytics/utils/nms.py +13 -16
  238. ultralytics/utils/ops.py +117 -166
  239. ultralytics/utils/patches.py +75 -21
  240. ultralytics/utils/plotting.py +75 -80
  241. ultralytics/utils/tal.py +125 -59
  242. ultralytics/utils/torch_utils.py +53 -79
  243. ultralytics/utils/tqdm.py +24 -21
  244. ultralytics/utils/triton.py +13 -19
  245. ultralytics/utils/tuner.py +19 -10
  246. dgenerate_ultralytics_headless-8.3.214.dist-info/RECORD +0 -283
  247. {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/entry_points.txt +0 -0
  248. {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/licenses/LICENSE +0 -0
  249. {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/top_level.txt +0 -0
tests/test_python.py CHANGED
@@ -12,7 +12,7 @@ import pytest
12
12
  import torch
13
13
  from PIL import Image
14
14
 
15
- from tests import CFG, MODEL, MODELS, SOURCE, SOURCES_LIST, TASK_MODEL_DATA, TMP
15
+ from tests import CFG, MODEL, MODELS, SOURCE, SOURCES_LIST, TASK_MODEL_DATA
16
16
  from ultralytics import RTDETR, YOLO
17
17
  from ultralytics.cfg import TASK2DATA, TASKS
18
18
  from ultralytics.data.build import load_inference_source
@@ -33,14 +33,11 @@ from ultralytics.utils import (
33
33
  WINDOWS,
34
34
  YAML,
35
35
  checks,
36
- is_dir_writeable,
37
36
  is_github_action_running,
38
37
  )
39
38
  from ultralytics.utils.downloads import download
40
39
  from ultralytics.utils.torch_utils import TORCH_1_11, TORCH_1_13
41
40
 
42
- IS_TMP_WRITEABLE = is_dir_writeable(TMP) # WARNING: must be run once tests start as TMP does not exist on tests/init
43
-
44
41
 
45
42
  def test_model_forward():
46
43
  """Test the forward pass of the YOLO model."""
@@ -77,10 +74,9 @@ def test_model_profile():
77
74
  _ = model.predict(im, profile=True)
78
75
 
79
76
 
80
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
81
- def test_predict_txt():
77
+ def test_predict_txt(tmp_path):
82
78
  """Test YOLO predictions with file, directory, and pattern sources listed in a text file."""
83
- file = TMP / "sources_multi_row.txt"
79
+ file = tmp_path / "sources_multi_row.txt"
84
80
  with open(file, "w") as f:
85
81
  for src in SOURCES_LIST:
86
82
  f.write(f"{src}\n")
@@ -89,10 +85,9 @@ def test_predict_txt():
89
85
 
90
86
 
91
87
  @pytest.mark.skipif(True, reason="disabled for testing")
92
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
93
- def test_predict_csv_multi_row():
88
+ def test_predict_csv_multi_row(tmp_path):
94
89
  """Test YOLO predictions with sources listed in multiple rows of a CSV file."""
95
- file = TMP / "sources_multi_row.csv"
90
+ file = tmp_path / "sources_multi_row.csv"
96
91
  with open(file, "w", newline="") as f:
97
92
  writer = csv.writer(f)
98
93
  writer.writerow(["source"])
@@ -102,10 +97,9 @@ def test_predict_csv_multi_row():
102
97
 
103
98
 
104
99
  @pytest.mark.skipif(True, reason="disabled for testing")
105
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
106
- def test_predict_csv_single_row():
100
+ def test_predict_csv_single_row(tmp_path):
107
101
  """Test YOLO predictions with sources listed in a single row of a CSV file."""
108
- file = TMP / "sources_single_row.csv"
102
+ file = tmp_path / "sources_single_row.csv"
109
103
  with open(file, "w", newline="") as f:
110
104
  writer = csv.writer(f)
111
105
  writer.writerow(SOURCES_LIST)
@@ -118,7 +112,7 @@ def test_predict_img(model_name):
118
112
  """Test YOLO model predictions on various image input types and sources, including online images."""
119
113
  channels = 1 if model_name == "yolo11n-grayscale.pt" else 3
120
114
  model = YOLO(WEIGHTS_DIR / model_name)
121
- im = cv2.imread(str(SOURCE), flags=cv2.IMREAD_GRAYSCALE if channels == 1 else cv2.IMREAD_COLOR) # uint8 numpy array
115
+ im = cv2.imread(str(SOURCE), flags=cv2.IMREAD_GRAYSCALE if channels == 1 else cv2.IMREAD_COLOR) # uint8 NumPy array
122
116
  assert len(model(source=Image.open(SOURCE), save=True, verbose=True, imgsz=32)) == 1 # PIL
123
117
  assert len(model(source=im, save=True, save_txt=True, imgsz=32)) == 1 # ndarray
124
118
  assert len(model(torch.rand((2, channels, 32, 32)), imgsz=32)) == 2 # batch-size 2 Tensor, FP32 0.0-1.0 RGB order
@@ -142,31 +136,53 @@ def test_predict_visualize(model):
142
136
  YOLO(WEIGHTS_DIR / model)(SOURCE, imgsz=32, visualize=True)
143
137
 
144
138
 
145
- def test_predict_grey_and_4ch():
146
- """Test YOLO prediction on SOURCE converted to greyscale and 4-channel images with various filenames."""
139
+ def test_predict_gray_and_4ch(tmp_path):
140
+ """Test YOLO prediction on SOURCE converted to grayscale and 4-channel images with various filenames."""
147
141
  im = Image.open(SOURCE)
148
- directory = TMP / "im4"
149
- directory.mkdir(parents=True, exist_ok=True)
150
142
 
151
- source_greyscale = directory / "greyscale.jpg"
152
- source_rgba = directory / "4ch.png"
153
- source_non_utf = directory / "non_UTF_测试文件_tést_image.jpg"
154
- source_spaces = directory / "image with spaces.jpg"
143
+ source_grayscale = tmp_path / "grayscale.jpg"
144
+ source_rgba = tmp_path / "4ch.png"
145
+ source_non_utf = tmp_path / "non_UTF_测试文件_tést_image.jpg"
146
+ source_spaces = tmp_path / "image with spaces.jpg"
155
147
 
156
- im.convert("L").save(source_greyscale) # greyscale
148
+ im.convert("L").save(source_grayscale) # grayscale
157
149
  im.convert("RGBA").save(source_rgba) # 4-ch PNG with alpha
158
150
  im.save(source_non_utf) # non-UTF characters in filename
159
151
  im.save(source_spaces) # spaces in filename
160
152
 
161
153
  # Inference
162
154
  model = YOLO(MODEL)
163
- for f in source_rgba, source_greyscale, source_non_utf, source_spaces:
155
+ for f in source_rgba, source_grayscale, source_non_utf, source_spaces:
164
156
  for source in Image.open(f), cv2.imread(str(f)), f:
165
157
  results = model(source, save=True, verbose=True, imgsz=32)
166
158
  assert len(results) == 1 # verify that an image was run
167
159
  f.unlink() # cleanup
168
160
 
169
161
 
162
+ @pytest.mark.slow
163
+ @pytest.mark.skipif(not ONLINE, reason="environment is offline")
164
+ def test_predict_all_image_formats():
165
+ """Test YOLO prediction all 12 image formats (AVIF, BMP, DNG, HEIC, JP2, JPEG, JPG, MPO, PNG, TIF, TIFF, WebP)."""
166
+ # Download dataset if needed
167
+ data = check_det_dataset("coco12-formats.yaml")
168
+ dataset_path = Path(data["path"])
169
+
170
+ # Collect all images from train and val
171
+ images = list((dataset_path / "images" / "train").glob("*.*"))
172
+ images += list((dataset_path / "images" / "val").glob("*.*"))
173
+ assert len(images) == 12, f"Expected 12 images, found {len(images)}"
174
+
175
+ # Verify all format extensions are represented
176
+ extensions = {img.suffix.lower().lstrip(".") for img in images}
177
+ expected = {"avif", "bmp", "dng", "heic", "jp2", "jpeg", "jpg", "mpo", "png", "tif", "tiff", "webp"}
178
+ assert extensions == expected, f"Missing formats: {expected - extensions}"
179
+
180
+ # Run inference on all images
181
+ model = YOLO(MODEL)
182
+ results = model(images, imgsz=32)
183
+ assert len(results) == 12, f"Expected 12 results, got {len(results)}"
184
+
185
+
170
186
  @pytest.mark.slow
171
187
  @pytest.mark.skipif(not ONLINE, reason="environment is offline")
172
188
  @pytest.mark.skipif(is_github_action_running(), reason="No auth https://github.com/JuanBindez/pytubefix/issues/166")
@@ -181,15 +197,13 @@ def test_youtube():
181
197
 
182
198
 
183
199
  @pytest.mark.skipif(not ONLINE, reason="environment is offline")
184
- @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable")
185
200
  @pytest.mark.parametrize("model", MODELS)
186
- def test_track_stream(model):
187
- """
188
- Test streaming tracking on a short 10 frame video using ByteTrack tracker and different GMC methods.
201
+ def test_track_stream(model, tmp_path):
202
+ """Test streaming tracking on a short 10 frame video using ByteTrack tracker and different GMC methods.
189
203
 
190
204
  Note imgsz=160 required for tracking for higher confidence and better matches.
191
205
  """
192
- if model == "yolo11n-cls.pt": # classification model not supported for tracking
206
+ if model == "yolo26n-cls.pt": # classification model not supported for tracking
193
207
  return
194
208
  video_url = f"{ASSETS_URL}/decelera_portrait_min.mov"
195
209
  model = YOLO(model)
@@ -197,9 +211,9 @@ def test_track_stream(model):
197
211
  model.track(video_url, imgsz=160, tracker="botsort.yaml", save_frames=True) # test frame saving also
198
212
 
199
213
  # Test Global Motion Compensation (GMC) methods and ReID
200
- for gmc, reidm in zip(["orb", "sift", "ecc"], ["auto", "auto", "yolo11n-cls.pt"]):
214
+ for gmc, reidm in zip(["orb", "sift", "ecc"], ["auto", "auto", "yolo26n-cls.pt"]):
201
215
  default_args = YAML.load(ROOT / "cfg/trackers/botsort.yaml")
202
- custom_yaml = TMP / f"botsort-{gmc}.yaml"
216
+ custom_yaml = tmp_path / f"botsort-{gmc}.yaml"
203
217
  YAML.save(custom_yaml, {**default_args, "gmc_method": gmc, "with_reid": True, "model": reidm})
204
218
  model.track(video_url, imgsz=160, tracker=custom_yaml)
205
219
 
@@ -219,25 +233,26 @@ def test_val(task: str, weight: str, data: str) -> None:
219
233
  metrics.confusion_matrix.to_json()
220
234
 
221
235
 
236
+ @pytest.mark.skipif(not ONLINE, reason="environment is offline")
222
237
  @pytest.mark.skipif(IS_JETSON or IS_RASPBERRYPI, reason="Edge devices not intended for training")
223
238
  def test_train_scratch():
224
- """Test training the YOLO model from scratch using the provided configuration."""
239
+ """Test training the YOLO model from scratch on 12 different image types in the COCO12-Formats dataset."""
225
240
  model = YOLO(CFG)
226
- model.train(data="coco8.yaml", epochs=2, imgsz=32, cache="disk", batch=-1, close_mosaic=1, name="model")
241
+ model.train(data="coco12-formats.yaml", epochs=2, imgsz=32, cache="disk", batch=-1, close_mosaic=1, name="model")
227
242
  model(SOURCE)
228
243
 
229
244
 
230
245
  @pytest.mark.skipif(not ONLINE, reason="environment is offline")
231
246
  def test_train_ndjson():
232
247
  """Test training the YOLO model using NDJSON format dataset."""
233
- model = YOLO(WEIGHTS_DIR / "yolo11n.pt")
248
+ model = YOLO(WEIGHTS_DIR / "yolo26n.pt")
234
249
  model.train(data=f"{ASSETS_URL}/coco8-ndjson.ndjson", epochs=1, imgsz=32)
235
250
 
236
251
 
237
252
  @pytest.mark.parametrize("scls", [False, True])
238
253
  def test_train_pretrained(scls):
239
254
  """Test training of the YOLO model starting from a pre-trained checkpoint."""
240
- model = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt")
255
+ model = YOLO(WEIGHTS_DIR / "yolo26n-seg.pt")
241
256
  model.train(
242
257
  data="coco8-seg.yaml", epochs=1, imgsz=32, cache="ram", copy_paste=0.5, mixup=0.5, name=0, single_cls=scls
243
258
  )
@@ -278,7 +293,7 @@ def test_predict_callback_and_setup():
278
293
  model.add_callback("on_predict_batch_end", on_predict_batch_end)
279
294
 
280
295
  dataset = load_inference_source(source=SOURCE)
281
- bs = dataset.bs # noqa access predictor properties
296
+ bs = dataset.bs # access predictor properties
282
297
  results = model.predict(dataset, stream=True, imgsz=160) # source already setup
283
298
  for r, im0, bs in results:
284
299
  print("test_callback", im0.shape)
@@ -288,21 +303,21 @@ def test_predict_callback_and_setup():
288
303
 
289
304
 
290
305
  @pytest.mark.parametrize("model", MODELS)
291
- def test_results(model: str):
306
+ def test_results(model: str, tmp_path):
292
307
  """Test YOLO model results processing and output in various formats."""
293
- im = f"{ASSETS_URL}/boats.jpg" if model == "yolo11n-obb.pt" else SOURCE
308
+ im = f"{ASSETS_URL}/boats.jpg" if model == "yolo26n-obb.pt" else SOURCE
294
309
  results = YOLO(WEIGHTS_DIR / model)([im, im], imgsz=160)
295
310
  for r in results:
296
311
  assert len(r), f"'{model}' results should not be empty!"
297
312
  r = r.cpu().numpy()
298
313
  print(r, len(r), r.path) # print numpy attributes
299
314
  r = r.to(device="cpu", dtype=torch.float32)
300
- r.save_txt(txt_file=TMP / "runs/tests/label.txt", save_conf=True)
301
- r.save_crop(save_dir=TMP / "runs/tests/crops/")
315
+ r.save_txt(txt_file=tmp_path / "runs/tests/label.txt", save_conf=True)
316
+ r.save_crop(save_dir=tmp_path / "runs/tests/crops/")
302
317
  r.to_df(decimals=3) # Align to_ methods: https://docs.ultralytics.com/modes/predict/#working-with-results
303
318
  r.to_csv()
304
319
  r.to_json(normalize=True)
305
- r.plot(pil=True, save=True, filename=TMP / "results_plot_save.jpg")
320
+ r.plot(pil=True, save=True, filename=tmp_path / "results_plot_save.jpg")
306
321
  r.plot(conf=True, boxes=True)
307
322
  print(r, len(r), r.path) # print after methods
308
323
 
@@ -310,13 +325,13 @@ def test_results(model: str):
310
325
  def test_labels_and_crops():
311
326
  """Test output from prediction args for saving YOLO detection labels and crops."""
312
327
  imgs = [SOURCE, ASSETS / "zidane.jpg"]
313
- results = YOLO(WEIGHTS_DIR / "yolo11n.pt")(imgs, imgsz=160, save_txt=True, save_crop=True)
328
+ results = YOLO(WEIGHTS_DIR / "yolo26n.pt")(imgs, imgsz=320, save_txt=True, save_crop=True)
314
329
  save_path = Path(results[0].save_dir)
315
330
  for r in results:
316
331
  im_name = Path(r.path).stem
317
332
  cls_idxs = r.boxes.cls.int().tolist()
318
- # Check correct detections
319
- assert cls_idxs == ([0, 7, 0, 0] if r.path.endswith("bus.jpg") else [0, 0, 0]) # bus.jpg and zidane.jpg classes
333
+ # Check that detections are made (at least 2 detections per image expected)
334
+ assert len(cls_idxs) >= 2, f"Expected at least 2 detections, got {len(cls_idxs)}"
320
335
  # Check label path
321
336
  labels = save_path / f"labels/{im_name}.txt"
322
337
  assert labels.exists()
@@ -332,7 +347,7 @@ def test_labels_and_crops():
332
347
 
333
348
 
334
349
  @pytest.mark.skipif(not ONLINE, reason="environment is offline")
335
- def test_data_utils():
350
+ def test_data_utils(tmp_path):
336
351
  """Test utility functions in ultralytics/data/utils.py, including dataset stats and auto-splitting."""
337
352
  from ultralytics.data.split import autosplit
338
353
  from ultralytics.data.utils import HUBDatasetStats
@@ -343,34 +358,36 @@ def test_data_utils():
343
358
 
344
359
  for task in TASKS:
345
360
  file = Path(TASK2DATA[task]).with_suffix(".zip") # i.e. coco8.zip
346
- download(f"https://github.com/ultralytics/hub/raw/main/example_datasets/{file}", unzip=False, dir=TMP)
347
- stats = HUBDatasetStats(TMP / file, task=task)
361
+ download(f"https://github.com/ultralytics/hub/raw/main/example_datasets/{file}", unzip=False, dir=tmp_path)
362
+ stats = HUBDatasetStats(tmp_path / file, task=task)
348
363
  stats.get_json(save=True)
349
364
  stats.process_images()
350
365
 
351
- autosplit(TMP / "coco8")
352
- zip_directory(TMP / "coco8/images/val") # zip
366
+ autosplit(tmp_path / "coco8")
367
+ zip_directory(tmp_path / "coco8/images/val") # zip
353
368
 
354
369
 
355
370
  @pytest.mark.skipif(not ONLINE, reason="environment is offline")
356
- def test_data_converter():
371
+ def test_data_converter(tmp_path):
357
372
  """Test dataset conversion functions from COCO to YOLO format and class mappings."""
358
373
  from ultralytics.data.converter import coco80_to_coco91_class, convert_coco
359
374
 
360
- download(f"{ASSETS_URL}/instances_val2017.json", dir=TMP)
361
- convert_coco(labels_dir=TMP, save_dir=TMP / "yolo_labels", use_segments=True, use_keypoints=False, cls91to80=True)
375
+ download(f"{ASSETS_URL}/instances_val2017.json", dir=tmp_path)
376
+ convert_coco(
377
+ labels_dir=tmp_path, save_dir=tmp_path / "yolo_labels", use_segments=True, use_keypoints=False, cls91to80=True
378
+ )
362
379
  coco80_to_coco91_class()
363
380
 
364
381
 
365
- def test_data_annotator():
382
+ def test_data_annotator(tmp_path):
366
383
  """Test automatic annotation of data using detection and segmentation models."""
367
384
  from ultralytics.data.annotator import auto_annotate
368
385
 
369
386
  auto_annotate(
370
387
  ASSETS,
371
- det_model=WEIGHTS_DIR / "yolo11n.pt",
388
+ det_model=WEIGHTS_DIR / "yolo26n.pt",
372
389
  sam_model=WEIGHTS_DIR / "mobile_sam.pt",
373
- output_dir=TMP / "auto_annotate_labels",
390
+ output_dir=tmp_path / "auto_annotate_labels",
374
391
  )
375
392
 
376
393
 
@@ -393,7 +410,46 @@ def test_cfg_init():
393
410
  check_dict_alignment({"a": 1}, {"b": 2})
394
411
  copy_default_cfg()
395
412
  (Path.cwd() / DEFAULT_CFG_PATH.name.replace(".yaml", "_copy.yaml")).unlink(missing_ok=False)
396
- [smart_value(x) for x in {"none", "true", "false"}]
413
+
414
+ # Test smart_value() with comprehensive cases
415
+ # Test None conversion
416
+ assert smart_value("none") is None
417
+ assert smart_value("None") is None
418
+ assert smart_value("NONE") is None
419
+
420
+ # Test boolean conversion
421
+ assert smart_value("true") is True
422
+ assert smart_value("True") is True
423
+ assert smart_value("TRUE") is True
424
+ assert smart_value("false") is False
425
+ assert smart_value("False") is False
426
+ assert smart_value("FALSE") is False
427
+
428
+ # Test numeric conversion (ast.literal_eval)
429
+ assert smart_value("42") == 42
430
+ assert smart_value("-42") == -42
431
+ assert smart_value("3.14") == 3.14
432
+ assert smart_value("-3.14") == -3.14
433
+ assert smart_value("1e-3") == 0.001
434
+
435
+ # Test list/tuple conversion (ast.literal_eval)
436
+ assert smart_value("[1, 2, 3]") == [1, 2, 3]
437
+ assert smart_value("(1, 2, 3)") == (1, 2, 3)
438
+ assert smart_value("[640, 640]") == [640, 640]
439
+
440
+ # Test dict conversion (ast.literal_eval)
441
+ assert smart_value("{'a': 1, 'b': 2}") == {"a": 1, "b": 2}
442
+
443
+ # Test string fallback (when ast.literal_eval fails)
444
+ assert smart_value("some_string") == "some_string"
445
+ assert smart_value("path/to/file") == "path/to/file"
446
+ assert smart_value("hello world") == "hello world"
447
+
448
+ # Test that code injection is prevented (ast.literal_eval safety)
449
+ # These should return strings, not execute code
450
+ assert smart_value("__import__('os').system('ls')") == "__import__('os').system('ls')"
451
+ assert smart_value("eval('1+1')") == "eval('1+1')"
452
+ assert smart_value("exec('x=1')") == "exec('x=1')"
397
453
 
398
454
 
399
455
  def test_utils_init():
@@ -419,7 +475,7 @@ def test_utils_benchmarks():
419
475
  """Benchmark model performance using 'ProfileModels' from 'ultralytics.utils.benchmarks'."""
420
476
  from ultralytics.utils.benchmarks import ProfileModels
421
477
 
422
- ProfileModels(["yolo11n.yaml"], imgsz=32, min_time=1, num_timed_runs=3, num_warmup_runs=1).run()
478
+ ProfileModels(["yolo26n.yaml"], imgsz=32, min_time=1, num_timed_runs=3, num_warmup_runs=1).run()
423
479
 
424
480
 
425
481
  def test_utils_torchutils():
@@ -464,7 +520,7 @@ def test_utils_ops():
464
520
  torch.allclose(boxes, xyxyxyxy2xywhr(xywhr2xyxyxyxy(boxes)), rtol=1e-3)
465
521
 
466
522
 
467
- def test_utils_files():
523
+ def test_utils_files(tmp_path):
468
524
  """Test file handling utilities including file age, date, and paths with spaces."""
469
525
  from ultralytics.utils.files import file_age, file_date, get_latest_run, spaces_in_path
470
526
 
@@ -472,14 +528,14 @@ def test_utils_files():
472
528
  file_date(SOURCE)
473
529
  get_latest_run(ROOT / "runs")
474
530
 
475
- path = TMP / "path/with spaces"
531
+ path = tmp_path / "path/with spaces"
476
532
  path.mkdir(parents=True, exist_ok=True)
477
533
  with spaces_in_path(path) as new_path:
478
534
  print(new_path)
479
535
 
480
536
 
481
537
  @pytest.mark.slow
482
- def test_utils_patches_torch_save():
538
+ def test_utils_patches_torch_save(tmp_path):
483
539
  """Test torch_save backoff when _torch_save raises RuntimeError."""
484
540
  from unittest.mock import MagicMock, patch
485
541
 
@@ -489,7 +545,7 @@ def test_utils_patches_torch_save():
489
545
 
490
546
  with patch("ultralytics.utils.patches._torch_save", new=mock):
491
547
  with pytest.raises(RuntimeError):
492
- torch_save(torch.zeros(1), TMP / "test.pt")
548
+ torch_save(torch.zeros(1), tmp_path / "test.pt")
493
549
 
494
550
  assert mock.call_count == 4, "torch_save was not attempted the expected number of times"
495
551
 
@@ -541,7 +597,7 @@ def test_hub():
541
597
 
542
598
  @pytest.fixture
543
599
  def image():
544
- """Load and return an image from a predefined source."""
600
+ """Load and return an image from a predefined source (OpenCV BGR)."""
545
601
  return cv2.imread(str(SOURCE))
546
602
 
547
603
 
@@ -585,14 +641,14 @@ def test_classify_transforms_train(image, auto_augment, erasing, force_color_jit
585
641
  @pytest.mark.skipif(not ONLINE, reason="environment is offline")
586
642
  def test_model_tune():
587
643
  """Tune YOLO model for performance improvement."""
588
- YOLO("yolo11n-pose.pt").tune(data="coco8-pose.yaml", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu")
589
- YOLO("yolo11n-cls.pt").tune(data="imagenet10", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu")
644
+ YOLO("yolo26n-pose.pt").tune(data="coco8-pose.yaml", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu")
645
+ YOLO("yolo26n-cls.pt").tune(data="imagenet10", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu")
590
646
 
591
647
 
592
648
  def test_model_embeddings():
593
649
  """Test YOLO model embeddings extraction functionality."""
594
650
  model_detect = YOLO(MODEL)
595
- model_segment = YOLO(WEIGHTS_DIR / "yolo11n-seg.pt")
651
+ model_segment = YOLO(WEIGHTS_DIR / "yolo26n-seg.pt")
596
652
 
597
653
  for batch in [SOURCE], [SOURCE, SOURCE]: # test batch size 1 and 2
598
654
  assert len(model_detect.embed(source=batch, imgsz=32)) == len(batch)
@@ -713,7 +769,7 @@ def test_yolov10():
713
769
 
714
770
  def test_multichannel():
715
771
  """Test YOLO model multi-channel training, validation, and prediction functionality."""
716
- model = YOLO("yolo11n.pt")
772
+ model = YOLO("yolo26n.pt")
717
773
  model.train(data="coco8-multispectral.yaml", epochs=1, imgsz=32, close_mosaic=1, cache="disk")
718
774
  model.val(data="coco8-multispectral.yaml")
719
775
  im = np.zeros((32, 32, 10), dtype=np.uint8)
@@ -722,14 +778,14 @@ def test_multichannel():
722
778
 
723
779
 
724
780
  @pytest.mark.parametrize("task,model,data", TASK_MODEL_DATA)
725
- def test_grayscale(task: str, model: str, data: str) -> None:
781
+ def test_grayscale(task: str, model: str, data: str, tmp_path) -> None:
726
782
  """Test YOLO model grayscale training, validation, and prediction functionality."""
727
783
  if task == "classify": # not support grayscale classification yet
728
784
  return
729
- grayscale_data = Path(TMP) / f"{Path(data).stem}-grayscale.yaml"
785
+ grayscale_data = tmp_path / f"{Path(data).stem}-grayscale.yaml"
730
786
  data = check_det_dataset(data)
731
787
  data["channels"] = 1 # add additional channels key for grayscale
732
- YAML.save(grayscale_data, data)
788
+ YAML.save(data=data, file=grayscale_data)
733
789
  # remove npy files in train/val splits if exists, might be created by previous tests
734
790
  for split in {"train", "val"}:
735
791
  for npy_file in (Path(data["path"]) / data[split]).glob("*.npy"):