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.
- {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/METADATA +3 -2
- {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/RECORD +38 -37
- ultralytics/__init__.py +1 -1
- ultralytics/data/utils.py +2 -2
- ultralytics/engine/exporter.py +9 -6
- ultralytics/engine/predictor.py +1 -1
- ultralytics/engine/results.py +5 -5
- ultralytics/engine/trainer.py +2 -0
- ultralytics/engine/validator.py +3 -1
- ultralytics/hub/__init__.py +6 -2
- ultralytics/hub/auth.py +2 -2
- ultralytics/hub/google/__init__.py +2 -2
- ultralytics/hub/session.py +3 -5
- ultralytics/hub/utils.py +5 -5
- ultralytics/models/rtdetr/val.py +3 -1
- ultralytics/models/yolo/detect/predict.py +2 -2
- ultralytics/models/yolo/detect/val.py +15 -4
- ultralytics/models/yolo/obb/val.py +5 -2
- ultralytics/models/yolo/segment/val.py +0 -3
- ultralytics/nn/autobackend.py +29 -36
- ultralytics/nn/modules/__init__.py +3 -3
- ultralytics/nn/modules/head.py +5 -1
- ultralytics/nn/tasks.py +2 -2
- ultralytics/utils/__init__.py +49 -14
- ultralytics/utils/benchmarks.py +12 -6
- ultralytics/utils/callbacks/platform.py +2 -1
- ultralytics/utils/checks.py +3 -3
- ultralytics/utils/downloads.py +46 -40
- ultralytics/utils/logger.py +7 -6
- ultralytics/utils/nms.py +346 -0
- ultralytics/utils/ops.py +80 -249
- ultralytics/utils/tal.py +1 -1
- ultralytics/utils/torch_utils.py +50 -47
- ultralytics/utils/tqdm.py +58 -59
- {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.187.dist-info → dgenerate_ultralytics_headless-8.3.190.dist-info}/licenses/LICENSE +0 -0
- {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
|
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
|
143
|
-
self.bar_format = bar_format or "{desc}: {
|
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} {
|
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
|
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 [(
|
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
|
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
|
261
|
-
|
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
|
-
|
264
|
-
|
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
|
-
|
271
|
+
n = n.rstrip("KMGTPB") # Remove unit suffix from current
|
267
272
|
else:
|
268
|
-
|
269
|
-
|
270
|
-
|
273
|
+
percent = 0
|
274
|
+
n = self._format_num(self.n)
|
275
|
+
total = "?"
|
271
276
|
|
272
277
|
elapsed_str = self._format_time(elapsed)
|
273
|
-
|
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 =
|
286
|
+
progress_str = format_str.format(
|
277
287
|
desc=self.desc,
|
278
|
-
|
288
|
+
percent=percent,
|
279
289
|
bar=self._generate_bar(),
|
280
|
-
|
281
|
-
|
282
|
-
|
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(
|
409
|
+
for i in TQDM(range(3), desc="Known total"):
|
400
410
|
time.sleep(0.05)
|
401
|
-
print()
|
402
411
|
|
403
|
-
|
404
|
-
|
405
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|