ultralytics 8.3.67__py3-none-any.whl → 8.3.68__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.
tests/test_exports.py CHANGED
@@ -44,18 +44,25 @@ def test_export_openvino():
44
44
  @pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13")
45
45
  @pytest.mark.parametrize(
46
46
  "task, dynamic, int8, half, batch, nms",
47
- [ # generate all combinations but exclude those where both int8 and half are True
47
+ [ # generate all combinations except for exclusion cases
48
48
  (task, dynamic, int8, half, batch, nms)
49
49
  for task, dynamic, int8, half, batch, nms in product(
50
50
  TASKS, [True, False], [True, False], [True, False], [1, 2], [True, False]
51
51
  )
52
- if not (int8 and half) # exclude cases where both int8 and half are True
52
+ if not ((int8 and half) or (task == "classify" and nms))
53
53
  ],
54
54
  )
55
55
  def test_export_openvino_matrix(task, dynamic, int8, half, batch, nms):
56
56
  """Test YOLO model exports to OpenVINO under various configuration matrix conditions."""
57
57
  file = YOLO(TASK2MODEL[task]).export(
58
- format="openvino", imgsz=32, dynamic=dynamic, int8=int8, half=half, batch=batch, data=TASK2DATA[task], nms=nms
58
+ format="openvino",
59
+ imgsz=32,
60
+ dynamic=dynamic,
61
+ int8=int8,
62
+ half=half,
63
+ batch=batch,
64
+ data=TASK2DATA[task],
65
+ nms=nms,
59
66
  )
60
67
  if WINDOWS:
61
68
  # Use unique filenames due to Windows file permissions bug possibly due to latent threaded use
@@ -69,7 +76,13 @@ def test_export_openvino_matrix(task, dynamic, int8, half, batch, nms):
69
76
  @pytest.mark.slow
70
77
  @pytest.mark.parametrize(
71
78
  "task, dynamic, int8, half, batch, simplify, nms",
72
- product(TASKS, [True, False], [False], [False], [1, 2], [True, False], [True, False]),
79
+ [ # generate all combinations except for exclusion cases
80
+ (task, dynamic, int8, half, batch, simplify, nms)
81
+ for task, dynamic, int8, half, batch, simplify, nms in product(
82
+ TASKS, [True, False], [False], [False], [1, 2], [True, False], [True, False]
83
+ )
84
+ if not ((int8 and half) or (task == "classify" and nms) or (task == "obb" and nms and not TORCH_1_13))
85
+ ],
73
86
  )
74
87
  def test_export_onnx_matrix(task, dynamic, int8, half, batch, simplify, nms):
75
88
  """Test YOLO exports to ONNX format with various configurations and parameters."""
@@ -82,14 +95,19 @@ def test_export_onnx_matrix(task, dynamic, int8, half, batch, simplify, nms):
82
95
 
83
96
  @pytest.mark.slow
84
97
  @pytest.mark.parametrize(
85
- "task, dynamic, int8, half, batch, nms", product(TASKS, [False], [False], [False], [1, 2], [True, False])
98
+ "task, dynamic, int8, half, batch, nms",
99
+ [ # generate all combinations except for exclusion cases
100
+ (task, dynamic, int8, half, batch, nms)
101
+ for task, dynamic, int8, half, batch, nms in product(TASKS, [False], [False], [False], [1, 2], [True, False])
102
+ if not (task == "classify" and nms)
103
+ ],
86
104
  )
87
105
  def test_export_torchscript_matrix(task, dynamic, int8, half, batch, nms):
88
106
  """Tests YOLO model exports to TorchScript format under varied configurations."""
89
107
  file = YOLO(TASK2MODEL[task]).export(
90
108
  format="torchscript", imgsz=32, dynamic=dynamic, int8=int8, half=half, batch=batch, nms=nms
91
109
  )
92
- YOLO(file)([SOURCE] * 3, imgsz=64 if dynamic else 32) # exported model inference at batch=3
110
+ YOLO(file)([SOURCE] * batch, imgsz=64 if dynamic else 32) # exported model inference
93
111
  Path(file).unlink() # cleanup
94
112
 
95
113
 
@@ -99,10 +117,10 @@ def test_export_torchscript_matrix(task, dynamic, int8, half, batch, nms):
99
117
  @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12")
100
118
  @pytest.mark.parametrize(
101
119
  "task, dynamic, int8, half, batch",
102
- [ # generate all combinations but exclude those where both int8 and half are True
120
+ [ # generate all combinations except for exclusion cases
103
121
  (task, dynamic, int8, half, batch)
104
122
  for task, dynamic, int8, half, batch in product(TASKS, [False], [True, False], [True, False], [1])
105
- if not (int8 and half) # exclude cases where both int8 and half are True
123
+ if not (int8 and half)
106
124
  ],
107
125
  )
108
126
  def test_export_coreml_matrix(task, dynamic, int8, half, batch):
@@ -124,12 +142,12 @@ def test_export_coreml_matrix(task, dynamic, int8, half, batch):
124
142
  @pytest.mark.skipif(not LINUX, reason="Test disabled as TF suffers from install conflicts on Windows and macOS")
125
143
  @pytest.mark.parametrize(
126
144
  "task, dynamic, int8, half, batch, nms",
127
- [ # generate all combinations but exclude those where both int8 and half are True
145
+ [ # generate all combinations except for exclusion cases
128
146
  (task, dynamic, int8, half, batch, nms)
129
147
  for task, dynamic, int8, half, batch, nms in product(
130
148
  TASKS, [False], [True, False], [True, False], [1], [True, False]
131
149
  )
132
- if not (int8 and half) # exclude cases where both int8 and half are True
150
+ if not ((int8 and half) or (task == "classify" and nms))
133
151
  ],
134
152
  )
135
153
  def test_export_tflite_matrix(task, dynamic, int8, half, batch, nms):
ultralytics/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
- __version__ = "8.3.67"
3
+ __version__ = "8.3.68"
4
4
 
5
5
  import os
6
6
 
@@ -75,7 +75,7 @@ from ultralytics.data.dataset import YOLODataset
75
75
  from ultralytics.data.utils import check_cls_dataset, check_det_dataset
76
76
  from ultralytics.nn.autobackend import check_class_names, default_class_names
77
77
  from ultralytics.nn.modules import C2f, Classify, Detect, RTDETRDecoder
78
- from ultralytics.nn.tasks import DetectionModel, SegmentationModel, WorldModel
78
+ from ultralytics.nn.tasks import ClassificationModel, DetectionModel, SegmentationModel, WorldModel
79
79
  from ultralytics.utils import (
80
80
  ARM64,
81
81
  DEFAULT_CFG,
@@ -282,6 +282,7 @@ class Exporter:
282
282
  if self.args.int8 and tflite:
283
283
  assert not getattr(model, "end2end", False), "TFLite INT8 export not supported for end2end models."
284
284
  if self.args.nms:
285
+ assert not isinstance(model, ClassificationModel), "'nms=True' is not valid for classification models."
285
286
  if getattr(model, "end2end", False):
286
287
  LOGGER.warning("WARNING ⚠️ 'nms=True' is not available for end2end models. Forcing 'nms=False'.")
287
288
  self.args.nms = False
@@ -507,6 +508,7 @@ class Exporter:
507
508
  output_names = ["output0", "output1"] if isinstance(self.model, SegmentationModel) else ["output0"]
508
509
  dynamic = self.args.dynamic
509
510
  if dynamic:
511
+ self.model.cpu() # dynamic=True only compatible with cpu
510
512
  dynamic = {"images": {0: "batch", 2: "height", 3: "width"}} # shape(1,3,640,640)
511
513
  if isinstance(self.model, SegmentationModel):
512
514
  dynamic["output0"] = {0: "batch", 2: "anchors"} # shape(1, 116, 8400)
@@ -518,13 +520,14 @@ class Exporter:
518
520
  if self.args.nms and self.model.task == "obb":
519
521
  self.args.opset = opset_version # for NMSModel
520
522
  # OBB error https://github.com/pytorch/pytorch/issues/110859#issuecomment-1757841865
521
- torch.onnx.register_custom_op_symbolic("aten::lift_fresh", lambda g, x: x, opset_version)
523
+ try:
524
+ torch.onnx.register_custom_op_symbolic("aten::lift_fresh", lambda g, x: x, opset_version)
525
+ except RuntimeError: # it will fail if it's already registered
526
+ pass
522
527
  check_requirements("onnxslim>=0.1.46") # Older versions has bug with OBB
523
528
 
524
529
  torch.onnx.export(
525
- NMSModel(self.model.cpu() if dynamic else self.model, self.args)
526
- if self.args.nms
527
- else self.model, # dynamic=True only compatible with cpu
530
+ NMSModel(self.model, self.args) if self.args.nms else self.model,
528
531
  self.im.cpu() if dynamic else self.im,
529
532
  f,
530
533
  verbose=False,
@@ -1556,6 +1559,7 @@ class NMSModel(torch.nn.Module):
1556
1559
  extra_shape = pred.shape[-1] - (4 + self.model.nc) # extras from Segment, OBB, Pose
1557
1560
  boxes, scores, extras = pred.split([4, self.model.nc, extra_shape], dim=2)
1558
1561
  scores, classes = scores.max(dim=-1)
1562
+ self.args.max_det = min(pred.shape[1], self.args.max_det) # in case num_anchors < max_det
1559
1563
  # (N, max_det, 4 coords + 1 class score + 1 class label + extra_shape).
1560
1564
  out = torch.zeros(
1561
1565
  boxes.shape[0],
@@ -1570,7 +1574,7 @@ class NMSModel(torch.nn.Module):
1570
1574
  # TFLite GatherND error if mask is empty
1571
1575
  score *= mask
1572
1576
  # Explicit length otherwise reshape error, hardcoded to `self.args.max_det * 5`
1573
- mask = score.topk(self.args.max_det * 5).indices
1577
+ mask = score.topk(min(self.args.max_det * 5, score.shape[0])).indices
1574
1578
  box, score, cls, extra = box[mask], score[mask], cls[mask], extra[mask]
1575
1579
  if not self.obb:
1576
1580
  box = xywh2xyxy(box)
@@ -1593,14 +1597,25 @@ class NMSModel(torch.nn.Module):
1593
1597
  offbox = nmsbox[:, :end] + cls_offset * multiplier
1594
1598
  nmsbox = torch.cat((offbox, nmsbox[:, end:]), dim=-1)
1595
1599
  nms_fn = (
1596
- partial(nms_rotated, use_triu=not (self.is_tf or (self.args.opset or 14) < 14)) if self.obb else nms
1600
+ partial(
1601
+ nms_rotated,
1602
+ use_triu=not (
1603
+ self.is_tf
1604
+ or (self.args.opset or 14) < 14
1605
+ or (self.args.format == "openvino" and self.args.int8) # OpenVINO int8 error with triu
1606
+ ),
1607
+ )
1608
+ if self.obb
1609
+ else nms
1597
1610
  )
1598
1611
  keep = nms_fn(
1599
1612
  torch.cat([nmsbox, extra], dim=-1) if self.obb else nmsbox,
1600
1613
  score,
1601
1614
  self.args.iou,
1602
1615
  )[: self.args.max_det]
1603
- dets = torch.cat([box[keep], score[keep].view(-1, 1), cls[keep].view(-1, 1), extra[keep]], dim=-1)
1616
+ dets = torch.cat(
1617
+ [box[keep], score[keep].view(-1, 1), cls[keep].view(-1, 1).to(out.dtype), extra[keep]], dim=-1
1618
+ )
1604
1619
  # Zero-pad to max_det size to avoid reshape error
1605
1620
  pad = (0, 0, 0, self.args.max_det - dets.shape[0])
1606
1621
  out[i] = torch.nn.functional.pad(dets, pad)
@@ -134,7 +134,7 @@ def benchmark(
134
134
 
135
135
  # Export
136
136
  if format == "-":
137
- filename = model.ckpt_path or model.cfg
137
+ filename = model.pt_path or model.ckpt_path or model.model_name
138
138
  exported_model = model # PyTorch format
139
139
  else:
140
140
  filename = model.export(imgsz=imgsz, format=format, half=half, int8=int8, device=device, verbose=False)
@@ -169,7 +169,7 @@ def benchmark(
169
169
  check_yolo(device=device) # print system info
170
170
  df = pd.DataFrame(y, columns=["Format", "Status❔", "Size (MB)", key, "Inference time (ms/im)", "FPS"])
171
171
 
172
- name = Path(model.ckpt_path).name
172
+ name = model.model_name
173
173
  s = f"\nBenchmarks complete for {name} on {data} at imgsz={imgsz} ({time.time() - t0:.2f}s)\n{df}\n"
174
174
  LOGGER.info(s)
175
175
  with open("benchmarks.log", "a", errors="ignore", encoding="utf-8") as f:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ultralytics
3
- Version: 8.3.67
3
+ Version: 8.3.68
4
4
  Summary: Ultralytics YOLO 🚀 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>, Jing Qiu <jing.qiu@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -3,11 +3,11 @@ tests/conftest.py,sha256=DE4-5JqWhsQPyDhU5hHqRevz971yPBQORs3LitLc6Fo,3010
3
3
  tests/test_cli.py,sha256=b9pPCu6x_MejPw-G7TI3wxSZnaMmutcXW7aCzMzz4ig,5076
4
4
  tests/test_cuda.py,sha256=inPe0f_L0GutDxYLbe49BPEmjMevaS9XXCWX1Lfjo2g,5971
5
5
  tests/test_engine.py,sha256=aGqZ8P7QO5C_nOa1b4FOyk92Ysdk5WiP-ST310Vyxys,4962
6
- tests/test_exports.py,sha256=Y4enSgWxhxSyq7uu-vlFeWqgCbeh-QF-nxnaNEsEpCw,8838
6
+ tests/test_exports.py,sha256=T_z_NUS9URQXv83k5XNLHTuksJ8srtzbZnWuiiQWM98,9260
7
7
  tests/test_integrations.py,sha256=p3DMnnPMKsV0Qm82JVJUIY1UZ67xRgF9E8AaL76TEHE,6154
8
8
  tests/test_python.py,sha256=tW-EFJC2rjl_DvAa8khXGWYdypseQjrLjGHhe2p9r9A,23238
9
9
  tests/test_solutions.py,sha256=aY0G3vNzXGCENG9FD76MfUp7jgzeESPsUvbvQYBUvH0,4205
10
- ultralytics/__init__.py,sha256=-pbOPM7jE9MCRGiQugGcikq7OUWsYt2YkjiRmMDsY6E,709
10
+ ultralytics/__init__.py,sha256=n5q3ToHB7gVfXmfVkZ0WhUK4hNEtU2DDIumDdhLV43E,709
11
11
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
12
12
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
13
13
  ultralytics/cfg/__init__.py,sha256=qP44HnFP4QcC5FQz29A-EGTuwdtxXAzPvw_IvCVmiqA,39771
@@ -102,7 +102,7 @@ ultralytics/data/loaders.py,sha256=JOwXbz-dxgG2bx0_cQHp-olz5FleoCX8EzrUvZ77vvg,2
102
102
  ultralytics/data/split_dota.py,sha256=YI-i2MqdiBt06W67TJnBXQHJrqTnkJDJ3zzoL0UZVro,10733
103
103
  ultralytics/data/utils.py,sha256=K8xyA1xHLpaeluUbqOl5fy6AWZ6nDciCBZJofjxzOuw,33841
104
104
  ultralytics/engine/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6DXppv1-QUM,70
105
- ultralytics/engine/exporter.py,sha256=n8f28FkSJC6KSu2TiFyVDC7MEbRTZlO2henB2KdmZro,75968
105
+ ultralytics/engine/exporter.py,sha256=aXUX8GZUw1CBaXYSI7OFwx1tsnl6VkgQQXb_iKi-cs8,76632
106
106
  ultralytics/engine/model.py,sha256=IHeaCwXlbxs6f2gVF5hEQVUiY-3F9Oz1wJNSTPZ-tZ0,53110
107
107
  ultralytics/engine/predictor.py,sha256=jiYDAjupOlRUpPvw9tu7or9PjXtLm-YCRiawANtWxj0,17881
108
108
  ultralytics/engine/results.py,sha256=0u-8GbhLoWBidfoWJ__CIV-_OKxoIRXk2j2OlaWMfd4,75327
@@ -206,7 +206,7 @@ ultralytics/trackers/utils/kalman_filter.py,sha256=OBvemZXptgn9v1sgBLvFomCqOWwjI
206
206
  ultralytics/trackers/utils/matching.py,sha256=64PKHGoETwXhuZ9udE217hbjJHygLOPaYA66J2qMSno,7130
207
207
  ultralytics/utils/__init__.py,sha256=Ahn7Vn60HIquaBZwLWfWH4bKnm0JcpJXYxnOnY-RH-s,50010
208
208
  ultralytics/utils/autobatch.py,sha256=zc81HlAMArPASEbExty0E_zpITF8PVwin7w-xBFFZ5w,5048
209
- ultralytics/utils/benchmarks.py,sha256=o9T7xfwhMsrOP0ce3F654L1an3fIoBKxUKz1CHNXerw,25979
209
+ ultralytics/utils/benchmarks.py,sha256=48NaNwlHy_ZZOm3QwUxAM1qdVtff2xjw18tpx07H7uQ,25993
210
210
  ultralytics/utils/checks.py,sha256=P543iMxEbXi0WWGrY67GaA7jIsas63K4uCSZpqmVx8M,31017
211
211
  ultralytics/utils/dist.py,sha256=fuiJQEnyyL-SighlI3hUlZPaaSreUl4Q39snF6OhQtI,2386
212
212
  ultralytics/utils/downloads.py,sha256=aUESyJOE2d7mJwbGECHWLR3RF8HVQPSwNH0cfmLGgdI,21999
@@ -233,9 +233,9 @@ ultralytics/utils/callbacks/neptune.py,sha256=waZ_bRu0-qBKujTLuqonC2gx2DkgBuVnfq
233
233
  ultralytics/utils/callbacks/raytune.py,sha256=TbuZlDb721aIkh-nMozZcP2g_ttUh2cG5LUaXmept6g,728
234
234
  ultralytics/utils/callbacks/tensorboard.py,sha256=JHOEVlNQ5dYJPd4Z-EvqbXowuK5uA0p8wPgyyaIUQs0,4194
235
235
  ultralytics/utils/callbacks/wb.py,sha256=ayhT2y62AcSOacnawshATU0rWrlSFQ77mrGgBdRl3W4,7086
236
- ultralytics-8.3.67.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
237
- ultralytics-8.3.67.dist-info/METADATA,sha256=ObYbsIICOizFYrlFM-E9UxGiF1TZ7n-HTwalyVWnMd8,35202
238
- ultralytics-8.3.67.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
239
- ultralytics-8.3.67.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
240
- ultralytics-8.3.67.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
241
- ultralytics-8.3.67.dist-info/RECORD,,
236
+ ultralytics-8.3.68.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
237
+ ultralytics-8.3.68.dist-info/METADATA,sha256=WO4rbpms65Um7GOdhwAt7w7z6fUBBtiikVAvvH0q5lU,35202
238
+ ultralytics-8.3.68.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
239
+ ultralytics-8.3.68.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
240
+ ultralytics-8.3.68.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
241
+ ultralytics-8.3.68.dist-info/RECORD,,