dgenerate-ultralytics-headless 8.3.191__py3-none-any.whl → 8.3.193__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 (34) hide show
  1. {dgenerate_ultralytics_headless-8.3.191.dist-info → dgenerate_ultralytics_headless-8.3.193.dist-info}/METADATA +1 -1
  2. {dgenerate_ultralytics_headless-8.3.191.dist-info → dgenerate_ultralytics_headless-8.3.193.dist-info}/RECORD +34 -34
  3. ultralytics/__init__.py +1 -1
  4. ultralytics/cfg/__init__.py +7 -5
  5. ultralytics/cfg/datasets/SKU-110K.yaml +1 -1
  6. ultralytics/cfg/datasets/xView.yaml +1 -1
  7. ultralytics/data/utils.py +1 -1
  8. ultralytics/engine/exporter.py +5 -4
  9. ultralytics/engine/model.py +4 -4
  10. ultralytics/engine/predictor.py +7 -3
  11. ultralytics/engine/trainer.py +5 -5
  12. ultralytics/engine/tuner.py +227 -40
  13. ultralytics/models/yolo/classify/train.py +2 -2
  14. ultralytics/models/yolo/classify/val.py +1 -1
  15. ultralytics/models/yolo/detect/val.py +1 -1
  16. ultralytics/models/yolo/pose/val.py +1 -1
  17. ultralytics/models/yolo/segment/val.py +14 -14
  18. ultralytics/models/yolo/world/train.py +1 -1
  19. ultralytics/models/yolo/yoloe/train.py +3 -4
  20. ultralytics/models/yolo/yoloe/val.py +3 -3
  21. ultralytics/nn/__init__.py +2 -4
  22. ultralytics/nn/autobackend.py +2 -2
  23. ultralytics/nn/tasks.py +2 -51
  24. ultralytics/utils/__init__.py +5 -1
  25. ultralytics/utils/checks.py +2 -1
  26. ultralytics/utils/plotting.py +2 -2
  27. ultralytics/utils/tal.py +2 -2
  28. ultralytics/utils/torch_utils.py +7 -6
  29. ultralytics/utils/tqdm.py +50 -74
  30. ultralytics/utils/tuner.py +1 -1
  31. {dgenerate_ultralytics_headless-8.3.191.dist-info → dgenerate_ultralytics_headless-8.3.193.dist-info}/WHEEL +0 -0
  32. {dgenerate_ultralytics_headless-8.3.191.dist-info → dgenerate_ultralytics_headless-8.3.193.dist-info}/entry_points.txt +0 -0
  33. {dgenerate_ultralytics_headless-8.3.191.dist-info → dgenerate_ultralytics_headless-8.3.193.dist-info}/licenses/LICENSE +0 -0
  34. {dgenerate_ultralytics_headless-8.3.191.dist-info → dgenerate_ultralytics_headless-8.3.193.dist-info}/top_level.txt +0 -0
@@ -36,6 +36,7 @@ from ultralytics.utils import (
36
36
  PYTHON_VERSION,
37
37
  RKNN_CHIPS,
38
38
  ROOT,
39
+ TORCH_VERSION,
39
40
  TORCHVISION_VERSION,
40
41
  USER_CONFIG_DIR,
41
42
  WINDOWS,
@@ -464,7 +465,7 @@ def check_torchvision():
464
465
  }
465
466
 
466
467
  # Check major and minor versions
467
- v_torch = ".".join(torch.__version__.split("+", 1)[0].split(".")[:2])
468
+ v_torch = ".".join(TORCH_VERSION.split("+", 1)[0].split(".")[:2])
468
469
  if v_torch in compatibility_table:
469
470
  compatible_versions = compatibility_table[v_torch]
470
471
  v_torchvision = ".".join(TORCHVISION_VERSION.split("+", 1)[0].split(".")[:2])
@@ -893,7 +893,7 @@ def plot_results(
893
893
  assert len(files), f"No results.csv files found in {save_dir.resolve()}, nothing to plot."
894
894
  for f in files:
895
895
  try:
896
- data = pl.read_csv(f)
896
+ data = pl.read_csv(f, infer_schema_length=None)
897
897
  s = [x.strip() for x in data.columns]
898
898
  x = data.select(data.columns[0]).to_numpy().flatten()
899
899
  for i, j in enumerate(index):
@@ -971,7 +971,7 @@ def plot_tune_results(csv_file: str = "tune_results.csv"):
971
971
 
972
972
  # Scatter plots for each hyperparameter
973
973
  csv_file = Path(csv_file)
974
- data = pl.read_csv(csv_file)
974
+ data = pl.read_csv(csv_file, infer_schema_length=None)
975
975
  num_metrics_columns = 1
976
976
  keys = [x.strip() for x in data.columns][num_metrics_columns:]
977
977
  x = data.to_numpy()
ultralytics/utils/tal.py CHANGED
@@ -3,12 +3,12 @@
3
3
  import torch
4
4
  import torch.nn as nn
5
5
 
6
- from . import LOGGER
6
+ from . import LOGGER, TORCH_VERSION
7
7
  from .checks import check_version
8
8
  from .metrics import bbox_iou, probiou
9
9
  from .ops import xywhr2xyxyxyxy
10
10
 
11
- TORCH_1_10 = check_version(torch.__version__, "1.10.0")
11
+ TORCH_1_10 = check_version(TORCH_VERSION, "1.10.0")
12
12
 
13
13
 
14
14
  class TaskAlignedAssigner(nn.Module):
@@ -27,6 +27,7 @@ from ultralytics.utils import (
27
27
  LOGGER,
28
28
  NUM_THREADS,
29
29
  PYTHON_VERSION,
30
+ TORCH_VERSION,
30
31
  TORCHVISION_VERSION,
31
32
  WINDOWS,
32
33
  colorstr,
@@ -35,15 +36,15 @@ from ultralytics.utils.checks import check_version
35
36
  from ultralytics.utils.patches import torch_load
36
37
 
37
38
  # Version checks (all default to version>=min_version)
38
- TORCH_1_9 = check_version(torch.__version__, "1.9.0")
39
- TORCH_1_13 = check_version(torch.__version__, "1.13.0")
40
- TORCH_2_0 = check_version(torch.__version__, "2.0.0")
41
- TORCH_2_4 = check_version(torch.__version__, "2.4.0")
39
+ TORCH_1_9 = check_version(TORCH_VERSION, "1.9.0")
40
+ TORCH_1_13 = check_version(TORCH_VERSION, "1.13.0")
41
+ TORCH_2_0 = check_version(TORCH_VERSION, "2.0.0")
42
+ TORCH_2_4 = check_version(TORCH_VERSION, "2.4.0")
42
43
  TORCHVISION_0_10 = check_version(TORCHVISION_VERSION, "0.10.0")
43
44
  TORCHVISION_0_11 = check_version(TORCHVISION_VERSION, "0.11.0")
44
45
  TORCHVISION_0_13 = check_version(TORCHVISION_VERSION, "0.13.0")
45
46
  TORCHVISION_0_18 = check_version(TORCHVISION_VERSION, "0.18.0")
46
- if WINDOWS and check_version(torch.__version__, "==2.4.0"): # reject version 2.4.0 on Windows
47
+ if WINDOWS and check_version(TORCH_VERSION, "==2.4.0"): # reject version 2.4.0 on Windows
47
48
  LOGGER.warning(
48
49
  "Known issue with torch==2.4.0 on Windows with CPU, recommend upgrading to torch>=2.4.1 to resolve "
49
50
  "https://github.com/ultralytics/ultralytics/issues/15049"
@@ -165,7 +166,7 @@ def select_device(device="", batch=0, newline=False, verbose=True):
165
166
  if isinstance(device, torch.device) or str(device).startswith(("tpu", "intel")):
166
167
  return device
167
168
 
168
- s = f"Ultralytics {__version__} 🚀 Python-{PYTHON_VERSION} torch-{torch.__version__} "
169
+ s = f"Ultralytics {__version__} 🚀 Python-{PYTHON_VERSION} torch-{TORCH_VERSION} "
169
170
  device = str(device).lower()
170
171
  for remove in "cuda:", "none", "(", ")", "[", "]", "'", " ":
171
172
  device = device.replace(remove, "") # to string, 'cuda:0' -> '0' and '(0, 1)' -> '0,1'
ultralytics/utils/tqdm.py CHANGED
@@ -88,11 +88,11 @@ class TQDM:
88
88
  mininterval: float = 0.1,
89
89
  disable: bool | None = None,
90
90
  unit: str = "it",
91
- unit_scale: bool = False,
91
+ unit_scale: bool = True,
92
92
  unit_divisor: int = 1000,
93
- bar_format: str | None = None,
93
+ bar_format: str | None = None, # kept for API compatibility; not used for formatting
94
94
  initial: int = 0,
95
- **kwargs, # Accept unused args for compatibility
95
+ **kwargs,
96
96
  ) -> None:
97
97
  """
98
98
  Initialize the TQDM progress bar with specified configuration options.
@@ -138,11 +138,8 @@ class TQDM:
138
138
  self.mininterval = max(mininterval, self.NONINTERACTIVE_MIN_INTERVAL) if self.noninteractive else mininterval
139
139
  self.initial = initial
140
140
 
141
- # Set bar format based on whether we have a total
142
- if self.total:
143
- self.bar_format = bar_format or "{desc}: {percent:.0f}% {bar} {n}/{total} {rate} {elapsed}<{remaining}"
144
- else:
145
- self.bar_format = bar_format or "{desc}: {bar} {n} {rate} {elapsed}"
141
+ # Kept for API compatibility (unused for f-string formatting)
142
+ self.bar_format = bar_format
146
143
 
147
144
  self.file = file or sys.stdout
148
145
 
@@ -151,48 +148,31 @@ class TQDM:
151
148
  self.last_print_n = self.initial
152
149
  self.last_print_t = time.time()
153
150
  self.start_t = time.time()
154
- self.last_rate = 0
151
+ self.last_rate = 0.0
155
152
  self.closed = False
153
+ self.is_bytes = unit_scale and unit in ("B", "bytes")
154
+ self.scales = (
155
+ [(1073741824, "GB/s"), (1048576, "MB/s"), (1024, "KB/s")]
156
+ if self.is_bytes
157
+ else [(1e9, f"G{self.unit}/s"), (1e6, f"M{self.unit}/s"), (1e3, f"K{self.unit}/s")]
158
+ )
156
159
 
157
- # Display initial bar if we have total and not disabled
158
160
  if not self.disable and self.total and not self.noninteractive:
159
161
  self._display()
160
162
 
161
163
  def _format_rate(self, rate: float) -> str:
162
- """Format rate with proper units and reasonable precision."""
164
+ """Format rate with units."""
163
165
  if rate <= 0:
164
166
  return ""
167
+ fallback = f"{rate:.1f}B/s" if self.is_bytes else f"{rate:.1f}{self.unit}/s"
168
+ return next((f"{rate / t:.1f}{u}" for t, u in self.scales if rate >= t), fallback)
165
169
 
166
- # For bytes with scaling, use binary units
167
- if self.unit in ("B", "bytes") and self.unit_scale:
168
- return next(
169
- (
170
- f"{rate / threshold:.1f}{unit}"
171
- for threshold, unit in [
172
- (1073741824, "GB/s"),
173
- (1048576, "MB/s"),
174
- (1024, "KB/s"),
175
- ]
176
- if rate >= threshold
177
- ),
178
- f"{rate:.1f}B/s",
179
- )
180
- # For other scalable units, use decimal units
181
- if self.unit_scale and self.unit in ("it", "items", ""):
182
- for threshold, prefix in [(1000000, "M"), (1000, "K")]:
183
- if rate >= threshold:
184
- return f"{rate / threshold:.1f}{prefix}{self.unit}/s"
185
-
186
- # Default formatting
187
- precision = ".1f" if rate >= 1 else ".2f"
188
- return f"{rate:{precision}}{self.unit}/s"
189
-
190
- def _format_num(self, num: int) -> str:
170
+ def _format_num(self, num: int | float) -> str:
191
171
  """Format number with optional unit scaling."""
192
- if not self.unit_scale or self.unit not in ("B", "bytes"):
172
+ if not self.unit_scale or not self.is_bytes:
193
173
  return str(num)
194
174
 
195
- for unit in ["", "K", "M", "G", "T"]:
175
+ for unit in ("", "K", "M", "G", "T"):
196
176
  if abs(num) < self.unit_divisor:
197
177
  return f"{num:3.1f}{unit}B" if unit else f"{num:.0f}B"
198
178
  num /= self.unit_divisor
@@ -224,8 +204,7 @@ class TQDM:
224
204
  """Check if display should update."""
225
205
  if self.noninteractive:
226
206
  return False
227
-
228
- return True if self.total and self.n >= self.total else dt >= self.mininterval
207
+ return (self.total is not None and self.n >= self.total) or (dt >= self.mininterval)
229
208
 
230
209
  def _display(self, final: bool = False) -> None:
231
210
  """Display progress bar."""
@@ -240,8 +219,8 @@ class TQDM:
240
219
  return
241
220
 
242
221
  # Calculate rate (avoid crazy numbers)
243
- if dt > self.MIN_RATE_CALC_INTERVAL: # Only calculate rate if enough time has passed
244
- rate = dn / dt
222
+ if dt > self.MIN_RATE_CALC_INTERVAL:
223
+ rate = dn / dt if dt else 0.0
245
224
  # Smooth rate for reasonable values, use raw rate for very high values
246
225
  if rate < self.MAX_SMOOTHED_RATE:
247
226
  self.last_rate = self.RATE_SMOOTHING_FACTOR * rate + (1 - self.RATE_SMOOTHING_FACTOR) * self.last_rate
@@ -249,8 +228,8 @@ class TQDM:
249
228
  else:
250
229
  rate = self.last_rate
251
230
 
252
- # At completion, use the overall rate for more accurate display
253
- if self.n >= (self.total or float("inf")) and self.total and self.total > 0:
231
+ # At completion, use overall rate
232
+ if self.total and self.n >= self.total:
254
233
  overall_elapsed = current_time - self.start_t
255
234
  if overall_elapsed > 0:
256
235
  rate = self.n / overall_elapsed
@@ -260,44 +239,41 @@ class TQDM:
260
239
  self.last_print_t = current_time
261
240
  elapsed = current_time - self.start_t
262
241
 
263
- # Calculate remaining time
242
+ # Remaining time
264
243
  remaining_str = ""
265
- if self.total and 0 < self.n < self.total and rate > 0:
266
- remaining_str = self._format_time((self.total - self.n) / rate)
244
+ if self.total and 0 < self.n < self.total and elapsed > 0:
245
+ est_rate = rate or (self.n / elapsed)
246
+ remaining_str = f"<{self._format_time((self.total - self.n) / est_rate)}"
267
247
 
268
- # Build progress components
248
+ # Numbers and percent
269
249
  if self.total:
270
250
  percent = (self.n / self.total) * 100
271
- # For bytes with unit scaling, avoid repeating units: show "5.4/5.4MB" not "5.4MB/5.4MB"
272
- n = self._format_num(self.n)
273
- total = self._format_num(self.total)
274
- if self.unit_scale and self.unit in ("B", "bytes"):
275
- n = n.rstrip("KMGTPB") # Remove unit suffix from current
251
+ n_str = self._format_num(self.n)
252
+ t_str = self._format_num(self.total)
253
+ if self.is_bytes:
254
+ # Collapse suffix only when identical (e.g. "5.4/5.4MB")
255
+ if n_str[-2] == t_str[-2]:
256
+ n_str = n_str.rstrip("KMGTPB") # Remove unit suffix from current if different than total
276
257
  else:
277
- percent = 0
278
- n = self._format_num(self.n)
279
- total = "?"
258
+ percent = 0.0
259
+ n_str, t_str = self._format_num(self.n), "?"
280
260
 
281
261
  elapsed_str = self._format_time(elapsed)
262
+ rate_str = self._format_rate(rate) or (self._format_rate(self.n / elapsed) if elapsed > 0 else "")
282
263
 
283
- # Use different format for completion
284
- if self.total and self.n >= self.total:
285
- format_str = self.bar_format.replace("<{remaining}", "")
264
+ bar = self._generate_bar()
265
+
266
+ # Compose progress line via f-strings (two shapes: with/without total)
267
+ if self.total:
268
+ if self.is_bytes and self.n >= self.total:
269
+ # Completed bytes: show only final size
270
+ progress_str = f"{self.desc}: {percent:.0f}% {bar} {t_str} {rate_str} {elapsed_str}"
271
+ else:
272
+ progress_str = (
273
+ f"{self.desc}: {percent:.0f}% {bar} {n_str}/{t_str} {rate_str} {elapsed_str}{remaining_str}"
274
+ )
286
275
  else:
287
- format_str = self.bar_format
288
-
289
- # Format progress string
290
- progress_str = format_str.format(
291
- desc=self.desc,
292
- percent=percent,
293
- bar=self._generate_bar(),
294
- n=n,
295
- total=total,
296
- rate=self._format_rate(rate) or (self._format_rate(self.n / elapsed) if elapsed > 0 else ""),
297
- remaining=remaining_str,
298
- elapsed=elapsed_str,
299
- unit=self.unit,
300
- )
276
+ progress_str = f"{self.desc}: {bar} {n_str} {rate_str} {elapsed_str}"
301
277
 
302
278
  # Write to output
303
279
  try:
@@ -335,7 +311,7 @@ class TQDM:
335
311
  if self.closed:
336
312
  return
337
313
 
338
- self.closed = True # Set before final display
314
+ self.closed = True
339
315
 
340
316
  if not self.disable:
341
317
  # Final display
@@ -129,7 +129,7 @@ def run_ray_tune(
129
129
  {**train_args, **{"exist_ok": train_args.pop("resume", False)}}, # resume w/ same tune_dir
130
130
  ),
131
131
  name=train_args.pop("name", "tune"), # runs/{task}/{tune_dir}
132
- ).resolve() # must be absolute dir
132
+ ) # must be absolute dir
133
133
  tune_dir.mkdir(parents=True, exist_ok=True)
134
134
  if tune.Tuner.can_restore(tune_dir):
135
135
  LOGGER.info(f"{colorstr('Tuner: ')} Resuming tuning run {tune_dir}...")