dgenerate-ultralytics-headless 8.3.187__py3-none-any.whl → 8.3.190__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 (38) hide show
  1. {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/METADATA +3 -2
  2. {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/RECORD +38 -37
  3. ultralytics/__init__.py +1 -1
  4. ultralytics/data/utils.py +2 -2
  5. ultralytics/engine/exporter.py +9 -6
  6. ultralytics/engine/predictor.py +1 -1
  7. ultralytics/engine/results.py +5 -5
  8. ultralytics/engine/trainer.py +2 -0
  9. ultralytics/engine/validator.py +3 -1
  10. ultralytics/hub/__init__.py +6 -2
  11. ultralytics/hub/auth.py +2 -2
  12. ultralytics/hub/google/__init__.py +2 -2
  13. ultralytics/hub/session.py +3 -5
  14. ultralytics/hub/utils.py +5 -5
  15. ultralytics/models/rtdetr/val.py +3 -1
  16. ultralytics/models/yolo/detect/predict.py +2 -2
  17. ultralytics/models/yolo/detect/val.py +15 -4
  18. ultralytics/models/yolo/obb/val.py +5 -2
  19. ultralytics/models/yolo/segment/val.py +0 -3
  20. ultralytics/nn/autobackend.py +29 -36
  21. ultralytics/nn/modules/__init__.py +3 -3
  22. ultralytics/nn/modules/head.py +5 -1
  23. ultralytics/nn/tasks.py +2 -2
  24. ultralytics/utils/__init__.py +49 -14
  25. ultralytics/utils/benchmarks.py +12 -6
  26. ultralytics/utils/callbacks/platform.py +2 -1
  27. ultralytics/utils/checks.py +3 -3
  28. ultralytics/utils/downloads.py +46 -40
  29. ultralytics/utils/logger.py +7 -6
  30. ultralytics/utils/nms.py +346 -0
  31. ultralytics/utils/ops.py +80 -249
  32. ultralytics/utils/tal.py +1 -1
  33. ultralytics/utils/torch_utils.py +50 -47
  34. ultralytics/utils/tqdm.py +58 -59
  35. {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/WHEEL +0 -0
  36. {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/entry_points.txt +0 -0
  37. {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/licenses/LICENSE +0 -0
  38. {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/top_level.txt +0 -0
ultralytics/utils/tqdm.py CHANGED
@@ -10,7 +10,7 @@ from typing import IO, Any
10
10
 
11
11
 
12
12
  @lru_cache(maxsize=1)
13
- def is_noninteractive_console():
13
+ def is_noninteractive_console() -> bool:
14
14
  """Check for known non-interactive console environments."""
15
15
  return "GITHUB_ACTIONS" in os.environ or "RUNPOD_POD_ID" in os.environ
16
16
 
@@ -128,7 +128,7 @@ class TQDM:
128
128
 
129
129
  self.iterable = iterable
130
130
  self.desc = desc or ""
131
- self.total = total if total is not None else (len(iterable) if hasattr(iterable, "__len__") else None)
131
+ self.total = total or (len(iterable) if hasattr(iterable, "__len__") else None) or None # prevent total=0
132
132
  self.disable = disable
133
133
  self.unit = unit
134
134
  self.unit_scale = unit_scale
@@ -139,10 +139,10 @@ class TQDM:
139
139
  self.initial = initial
140
140
 
141
141
  # Set bar format based on whether we have a total
142
- if self.total is not None:
143
- self.bar_format = bar_format or "{desc}: {percentage:3.0f}% {bar} {n_fmt}/{total_fmt} {rate_fmt} {elapsed}"
142
+ if self.total:
143
+ self.bar_format = bar_format or "{desc}: {percent:.0f}% {bar} {n}/{total} {rate} {elapsed}<{remaining}"
144
144
  else:
145
- self.bar_format = bar_format or "{desc}: {bar} {n_fmt} {rate_fmt} {elapsed}"
145
+ self.bar_format = bar_format or "{desc}: {bar} {n} {rate} {elapsed}"
146
146
 
147
147
  self.file = file or sys.stdout
148
148
 
@@ -155,17 +155,17 @@ class TQDM:
155
155
  self.closed = False
156
156
 
157
157
  # Display initial bar if we have total and not disabled
158
- if not self.disable and self.total is not None and not self.noninteractive:
158
+ if not self.disable and self.total and not self.noninteractive:
159
159
  self._display()
160
160
 
161
- def _format_rate(self, rate):
161
+ def _format_rate(self, rate: float) -> str:
162
162
  """Format rate with proper units and reasonable precision."""
163
163
  if rate <= 0:
164
164
  return ""
165
165
 
166
166
  # For bytes with scaling, use binary units
167
167
  if self.unit in ("B", "bytes") and self.unit_scale:
168
- for threshold, unit in [(1024**3, "GB/s"), (1024**2, "MB/s"), (1024, "KB/s")]:
168
+ for threshold, unit in [(1073741824, "GB/s"), (1048576, "MB/s"), (1024, "KB/s")]: # 1 << 30, << 20, << 10
169
169
  if rate >= threshold:
170
170
  return f"{rate / threshold:.1f}{unit}"
171
171
  return f"{rate:.1f}B/s"
@@ -180,7 +180,7 @@ class TQDM:
180
180
  precision = ".1f" if rate >= 1 else ".2f"
181
181
  return f"{rate:{precision}}{self.unit}/s"
182
182
 
183
- def _format_num(self, num):
183
+ def _format_num(self, num: int) -> str:
184
184
  """Format number with optional unit scaling."""
185
185
  if not self.unit_scale or self.unit not in ("B", "bytes"):
186
186
  return str(num)
@@ -191,7 +191,7 @@ class TQDM:
191
191
  num /= self.unit_divisor
192
192
  return f"{num:.1f}PB"
193
193
 
194
- def _format_time(self, seconds):
194
+ def _format_time(self, seconds: float) -> str:
195
195
  """Format time duration."""
196
196
  if seconds < 60:
197
197
  return f"{seconds:.1f}s"
@@ -201,7 +201,7 @@ class TQDM:
201
201
  h, m = int(seconds // 3600), int((seconds % 3600) // 60)
202
202
  return f"{h}:{m:02d}:{seconds % 60:02.0f}"
203
203
 
204
- def _generate_bar(self, width=12):
204
+ def _generate_bar(self, width: int = 12) -> str:
205
205
  """Generate progress bar."""
206
206
  if self.total is None:
207
207
  return "━" * width if self.closed else "─" * width
@@ -213,17 +213,17 @@ class TQDM:
213
213
  bar = bar[:filled] + "╸" + bar[filled + 1 :]
214
214
  return bar
215
215
 
216
- def _should_update(self, dt, dn):
216
+ def _should_update(self, dt: float, dn: int) -> bool:
217
217
  """Check if display should update."""
218
218
  if self.noninteractive:
219
219
  return False
220
220
 
221
- if self.total is not None and self.n >= self.total:
221
+ if self.total and self.n >= self.total:
222
222
  return True
223
223
 
224
224
  return dt >= self.mininterval
225
225
 
226
- def _display(self, final=False):
226
+ def _display(self, final: bool = False) -> None:
227
227
  """Display progress bar."""
228
228
  if self.disable or (self.closed and not final):
229
229
  return
@@ -256,30 +256,41 @@ class TQDM:
256
256
  self.last_print_t = current_time
257
257
  elapsed = current_time - self.start_t
258
258
 
259
+ # Calculate remaining time
260
+ remaining_str = ""
261
+ if self.total and 0 < self.n < self.total and rate > 0:
262
+ remaining_str = self._format_time((self.total - self.n) / rate)
263
+
259
264
  # Build progress components
260
- if self.total is not None:
261
- percentage = (self.n / self.total) * 100
265
+ if self.total:
266
+ percent = (self.n / self.total) * 100
262
267
  # For bytes with unit scaling, avoid repeating units: show "5.4/5.4MB" not "5.4MB/5.4MB"
263
- n_fmt = self._format_num(self.n)
264
- total_fmt = self._format_num(self.total)
268
+ n = self._format_num(self.n)
269
+ total = self._format_num(self.total)
265
270
  if self.unit_scale and self.unit in ("B", "bytes"):
266
- n_fmt = n_fmt.rstrip("KMGTPB") # Remove unit suffix from current
271
+ n = n.rstrip("KMGTPB") # Remove unit suffix from current
267
272
  else:
268
- percentage = 0
269
- n_fmt = self._format_num(self.n)
270
- total_fmt = "?"
273
+ percent = 0
274
+ n = self._format_num(self.n)
275
+ total = "?"
271
276
 
272
277
  elapsed_str = self._format_time(elapsed)
273
- rate_fmt = self._format_rate(rate) or (self._format_rate(self.n / elapsed) if elapsed > 0 else "")
278
+
279
+ # Use different format for completion
280
+ if self.total and self.n >= self.total:
281
+ format_str = self.bar_format.replace("<{remaining}", "")
282
+ else:
283
+ format_str = self.bar_format
274
284
 
275
285
  # Format progress string
276
- progress_str = self.bar_format.format(
286
+ progress_str = format_str.format(
277
287
  desc=self.desc,
278
- percentage=percentage,
288
+ percent=percent,
279
289
  bar=self._generate_bar(),
280
- n_fmt=n_fmt,
281
- total_fmt=total_fmt,
282
- rate_fmt=rate_fmt,
290
+ n=n,
291
+ total=total,
292
+ rate=self._format_rate(rate) or (self._format_rate(self.n / elapsed) if elapsed > 0 else ""),
293
+ remaining=remaining_str,
283
294
  elapsed=elapsed_str,
284
295
  unit=self.unit,
285
296
  )
@@ -296,26 +307,26 @@ class TQDM:
296
307
  except Exception:
297
308
  pass
298
309
 
299
- def update(self, n=1):
310
+ def update(self, n: int = 1) -> None:
300
311
  """Update progress by n steps."""
301
312
  if not self.disable and not self.closed:
302
313
  self.n += n
303
314
  self._display()
304
315
 
305
- def set_description(self, desc):
316
+ def set_description(self, desc: str | None) -> None:
306
317
  """Set description."""
307
318
  self.desc = desc or ""
308
319
  if not self.disable:
309
320
  self._display()
310
321
 
311
- def set_postfix(self, **kwargs):
322
+ def set_postfix(self, **kwargs: Any) -> None:
312
323
  """Set postfix (appends to description)."""
313
324
  if kwargs:
314
325
  postfix = ", ".join(f"{k}={v}" for k, v in kwargs.items())
315
326
  base_desc = self.desc.split(" | ")[0] if " | " in self.desc else self.desc
316
327
  self.set_description(f"{base_desc} | {postfix}")
317
328
 
318
- def close(self):
329
+ def close(self) -> None:
319
330
  """Close progress bar."""
320
331
  if self.closed:
321
332
  return
@@ -339,15 +350,15 @@ class TQDM:
339
350
  except Exception:
340
351
  pass
341
352
 
342
- def __enter__(self):
353
+ def __enter__(self) -> TQDM:
343
354
  """Enter context manager."""
344
355
  return self
345
356
 
346
- def __exit__(self, *args):
357
+ def __exit__(self, *args: Any) -> None:
347
358
  """Exit context manager and close progress bar."""
348
359
  self.close()
349
360
 
350
- def __iter__(self):
361
+ def __iter__(self) -> Any:
351
362
  """Iterate over the wrapped iterable with progress updates."""
352
363
  if self.iterable is None:
353
364
  raise TypeError("'NoneType' object is not iterable")
@@ -359,19 +370,19 @@ class TQDM:
359
370
  finally:
360
371
  self.close()
361
372
 
362
- def __del__(self):
373
+ def __del__(self) -> None:
363
374
  """Destructor to ensure cleanup."""
364
375
  try:
365
376
  self.close()
366
377
  except Exception:
367
378
  pass
368
379
 
369
- def refresh(self):
380
+ def refresh(self) -> None:
370
381
  """Refresh display."""
371
382
  if not self.disable:
372
383
  self._display()
373
384
 
374
- def clear(self):
385
+ def clear(self) -> None:
375
386
  """Clear progress bar."""
376
387
  if not self.disable:
377
388
  try:
@@ -381,7 +392,7 @@ class TQDM:
381
392
  pass
382
393
 
383
394
  @staticmethod
384
- def write(s, file=None, end="\n"):
395
+ def write(s: str, file: IO[str] | None = None, end: str = "\n") -> None:
385
396
  """Static method to write without breaking progress bar."""
386
397
  file = file or sys.stdout
387
398
  try:
@@ -394,25 +405,20 @@ class TQDM:
394
405
  if __name__ == "__main__":
395
406
  import time
396
407
 
397
- # Example 1: Basic usage with known total
398
408
  print("1. Basic progress bar with known total:")
399
- for i in TQDM(range(20), desc="Known total"):
409
+ for i in TQDM(range(3), desc="Known total"):
400
410
  time.sleep(0.05)
401
- print()
402
411
 
403
- # Example 2: Manual updates with known total
404
- print("2. Manual updates with known total:")
405
- pbar = TQDM(total=30, desc="Manual updates", unit="files")
406
- for i in range(30):
412
+ print("\n2. Manual updates with known total:")
413
+ pbar = TQDM(total=300, desc="Manual updates", unit="files")
414
+ for i in range(300):
407
415
  time.sleep(0.03)
408
416
  pbar.update(1)
409
417
  if i % 10 == 9:
410
418
  pbar.set_description(f"Processing batch {i // 10 + 1}")
411
419
  pbar.close()
412
- print()
413
420
 
414
- # Example 3: Unknown total - this was the problematic case
415
- print("3. Progress bar with unknown total:")
421
+ print("\n3. Progress bar with unknown total:")
416
422
  pbar = TQDM(desc="Unknown total", unit="items")
417
423
  for i in range(25):
418
424
  time.sleep(0.08)
@@ -420,18 +426,14 @@ if __name__ == "__main__":
420
426
  if i % 5 == 4:
421
427
  pbar.set_postfix(processed=i + 1, status="OK")
422
428
  pbar.close()
423
- print()
424
429
 
425
- # Example 4: Context manager with unknown total
426
- print("4. Context manager with unknown total:")
430
+ print("\n4. Context manager with unknown total:")
427
431
  with TQDM(desc="Processing stream", unit="B", unit_scale=True, unit_divisor=1024) as pbar:
428
432
  for i in range(30):
429
433
  time.sleep(0.1)
430
434
  pbar.update(1024 * 1024 * i) # Simulate processing MB of data
431
- print()
432
435
 
433
- # Example 5: Generator with unknown length
434
- print("5. Iterator with unknown length:")
436
+ print("\n5. Iterator with unknown length:")
435
437
 
436
438
  def data_stream():
437
439
  """Simulate a data stream of unknown length."""
@@ -442,10 +444,8 @@ if __name__ == "__main__":
442
444
 
443
445
  for chunk in TQDM(data_stream(), desc="Stream processing", unit="chunks"):
444
446
  time.sleep(0.1)
445
- print()
446
447
 
447
- # Example 6: File-like processing simulation
448
- print("6. File processing simulation (unknown size):")
448
+ print("\n6. File processing simulation (unknown size):")
449
449
 
450
450
  def process_files():
451
451
  """Simulate processing files of unknown count."""
@@ -459,4 +459,3 @@ if __name__ == "__main__":
459
459
  pbar.update(1)
460
460
  pbar.set_description(f"Processing {filename}")
461
461
  pbar.close()
462
- print()