dgenerate-ultralytics-headless 8.3.186__py3-none-any.whl → 8.3.189__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.186.dist-info → dgenerate_ultralytics_headless-8.3.189.dist-info}/METADATA +6 -6
- {dgenerate_ultralytics_headless-8.3.186.dist-info → dgenerate_ultralytics_headless-8.3.189.dist-info}/RECORD +28 -28
- tests/test_python.py +2 -10
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/datasets/SKU-110K.yaml +2 -2
- ultralytics/engine/exporter.py +4 -4
- ultralytics/engine/results.py +1 -4
- ultralytics/engine/trainer.py +3 -3
- ultralytics/models/rtdetr/val.py +3 -1
- ultralytics/models/sam/__init__.py +8 -2
- ultralytics/models/sam/modules/sam.py +6 -6
- ultralytics/models/sam/predict.py +363 -6
- ultralytics/models/yolo/detect/val.py +13 -2
- ultralytics/models/yolo/obb/val.py +3 -1
- ultralytics/models/yolo/segment/val.py +0 -3
- ultralytics/nn/autobackend.py +6 -3
- ultralytics/nn/tasks.py +2 -2
- ultralytics/utils/__init__.py +39 -94
- ultralytics/utils/benchmarks.py +16 -9
- ultralytics/utils/callbacks/wb.py +9 -3
- ultralytics/utils/downloads.py +44 -38
- ultralytics/utils/plotting.py +13 -20
- ultralytics/utils/torch_utils.py +50 -47
- ultralytics/utils/tqdm.py +25 -37
- {dgenerate_ultralytics_headless-8.3.186.dist-info → dgenerate_ultralytics_headless-8.3.189.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.186.dist-info → dgenerate_ultralytics_headless-8.3.189.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.186.dist-info → dgenerate_ultralytics_headless-8.3.189.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.186.dist-info → dgenerate_ultralytics_headless-8.3.189.dist-info}/top_level.txt +0 -0
ultralytics/utils/torch_utils.py
CHANGED
@@ -250,68 +250,71 @@ def time_sync():
|
|
250
250
|
|
251
251
|
|
252
252
|
def fuse_conv_and_bn(conv, bn):
|
253
|
-
"""
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
groups=conv.groups,
|
263
|
-
bias=True,
|
264
|
-
)
|
265
|
-
.requires_grad_(False)
|
266
|
-
.to(conv.weight.device)
|
267
|
-
)
|
253
|
+
"""
|
254
|
+
Fuse Conv2d and BatchNorm2d layers for inference optimization.
|
255
|
+
|
256
|
+
Args:
|
257
|
+
conv (nn.Conv2d): Convolutional layer to fuse.
|
258
|
+
bn (nn.BatchNorm2d): Batch normalization layer to fuse.
|
259
|
+
|
260
|
+
Returns:
|
261
|
+
(nn.Conv2d): The fused convolutional layer with gradients disabled.
|
268
262
|
|
269
|
-
|
263
|
+
Example:
|
264
|
+
>>> conv = nn.Conv2d(3, 16, 3)
|
265
|
+
>>> bn = nn.BatchNorm2d(16)
|
266
|
+
>>> fused_conv = fuse_conv_and_bn(conv, bn)
|
267
|
+
"""
|
268
|
+
# Compute fused weights
|
270
269
|
w_conv = conv.weight.view(conv.out_channels, -1)
|
271
270
|
w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var)))
|
272
|
-
|
271
|
+
conv.weight.data = torch.mm(w_bn, w_conv).view(conv.weight.shape)
|
273
272
|
|
274
|
-
#
|
275
|
-
b_conv = (
|
276
|
-
torch.zeros(conv.weight.shape[0], dtype=conv.weight.dtype, device=conv.weight.device)
|
277
|
-
if conv.bias is None
|
278
|
-
else conv.bias
|
279
|
-
)
|
273
|
+
# Compute fused bias
|
274
|
+
b_conv = torch.zeros(conv.out_channels, device=conv.weight.device) if conv.bias is None else conv.bias
|
280
275
|
b_bn = bn.bias - bn.weight.mul(bn.running_mean).div(torch.sqrt(bn.running_var + bn.eps))
|
281
|
-
|
276
|
+
fused_bias = torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn
|
277
|
+
|
278
|
+
if conv.bias is None:
|
279
|
+
conv.register_parameter("bias", nn.Parameter(fused_bias))
|
280
|
+
else:
|
281
|
+
conv.bias.data = fused_bias
|
282
282
|
|
283
|
-
return
|
283
|
+
return conv.requires_grad_(False)
|
284
284
|
|
285
285
|
|
286
286
|
def fuse_deconv_and_bn(deconv, bn):
|
287
|
-
"""
|
288
|
-
|
289
|
-
nn.ConvTranspose2d(
|
290
|
-
deconv.in_channels,
|
291
|
-
deconv.out_channels,
|
292
|
-
kernel_size=deconv.kernel_size,
|
293
|
-
stride=deconv.stride,
|
294
|
-
padding=deconv.padding,
|
295
|
-
output_padding=deconv.output_padding,
|
296
|
-
dilation=deconv.dilation,
|
297
|
-
groups=deconv.groups,
|
298
|
-
bias=True,
|
299
|
-
)
|
300
|
-
.requires_grad_(False)
|
301
|
-
.to(deconv.weight.device)
|
302
|
-
)
|
287
|
+
"""
|
288
|
+
Fuse ConvTranspose2d and BatchNorm2d layers for inference optimization.
|
303
289
|
|
304
|
-
|
290
|
+
Args:
|
291
|
+
deconv (nn.ConvTranspose2d): Transposed convolutional layer to fuse.
|
292
|
+
bn (nn.BatchNorm2d): Batch normalization layer to fuse.
|
293
|
+
|
294
|
+
Returns:
|
295
|
+
(nn.ConvTranspose2d): The fused transposed convolutional layer with gradients disabled.
|
296
|
+
|
297
|
+
Example:
|
298
|
+
>>> deconv = nn.ConvTranspose2d(16, 3, 3)
|
299
|
+
>>> bn = nn.BatchNorm2d(3)
|
300
|
+
>>> fused_deconv = fuse_deconv_and_bn(deconv, bn)
|
301
|
+
"""
|
302
|
+
# Compute fused weights
|
305
303
|
w_deconv = deconv.weight.view(deconv.out_channels, -1)
|
306
304
|
w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var)))
|
307
|
-
|
305
|
+
deconv.weight.data = torch.mm(w_bn, w_deconv).view(deconv.weight.shape)
|
308
306
|
|
309
|
-
#
|
310
|
-
b_conv = torch.zeros(deconv.
|
307
|
+
# Compute fused bias
|
308
|
+
b_conv = torch.zeros(deconv.out_channels, device=deconv.weight.device) if deconv.bias is None else deconv.bias
|
311
309
|
b_bn = bn.bias - bn.weight.mul(bn.running_mean).div(torch.sqrt(bn.running_var + bn.eps))
|
312
|
-
|
310
|
+
fused_bias = torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn
|
311
|
+
|
312
|
+
if deconv.bias is None:
|
313
|
+
deconv.register_parameter("bias", nn.Parameter(fused_bias))
|
314
|
+
else:
|
315
|
+
deconv.bias.data = fused_bias
|
313
316
|
|
314
|
-
return
|
317
|
+
return deconv.requires_grad_(False)
|
315
318
|
|
316
319
|
|
317
320
|
def model_info(model, detailed=False, verbose=True, imgsz=640):
|
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
|
@@ -158,7 +158,7 @@ class TQDM:
|
|
158
158
|
if not self.disable and self.total is not None 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 ""
|
@@ -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,7 +213,7 @@ 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
|
@@ -223,7 +223,7 @@ class TQDM:
|
|
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
|
@@ -296,26 +296,26 @@ class TQDM:
|
|
296
296
|
except Exception:
|
297
297
|
pass
|
298
298
|
|
299
|
-
def update(self, n=1):
|
299
|
+
def update(self, n: int = 1) -> None:
|
300
300
|
"""Update progress by n steps."""
|
301
301
|
if not self.disable and not self.closed:
|
302
302
|
self.n += n
|
303
303
|
self._display()
|
304
304
|
|
305
|
-
def set_description(self, desc):
|
305
|
+
def set_description(self, desc: str | None) -> None:
|
306
306
|
"""Set description."""
|
307
307
|
self.desc = desc or ""
|
308
308
|
if not self.disable:
|
309
309
|
self._display()
|
310
310
|
|
311
|
-
def set_postfix(self, **kwargs):
|
311
|
+
def set_postfix(self, **kwargs: Any) -> None:
|
312
312
|
"""Set postfix (appends to description)."""
|
313
313
|
if kwargs:
|
314
314
|
postfix = ", ".join(f"{k}={v}" for k, v in kwargs.items())
|
315
315
|
base_desc = self.desc.split(" | ")[0] if " | " in self.desc else self.desc
|
316
316
|
self.set_description(f"{base_desc} | {postfix}")
|
317
317
|
|
318
|
-
def close(self):
|
318
|
+
def close(self) -> None:
|
319
319
|
"""Close progress bar."""
|
320
320
|
if self.closed:
|
321
321
|
return
|
@@ -339,15 +339,15 @@ class TQDM:
|
|
339
339
|
except Exception:
|
340
340
|
pass
|
341
341
|
|
342
|
-
def __enter__(self):
|
342
|
+
def __enter__(self) -> TQDM:
|
343
343
|
"""Enter context manager."""
|
344
344
|
return self
|
345
345
|
|
346
|
-
def __exit__(self, *args):
|
346
|
+
def __exit__(self, *args: Any) -> None:
|
347
347
|
"""Exit context manager and close progress bar."""
|
348
348
|
self.close()
|
349
349
|
|
350
|
-
def __iter__(self):
|
350
|
+
def __iter__(self) -> Any:
|
351
351
|
"""Iterate over the wrapped iterable with progress updates."""
|
352
352
|
if self.iterable is None:
|
353
353
|
raise TypeError("'NoneType' object is not iterable")
|
@@ -359,19 +359,19 @@ class TQDM:
|
|
359
359
|
finally:
|
360
360
|
self.close()
|
361
361
|
|
362
|
-
def __del__(self):
|
362
|
+
def __del__(self) -> None:
|
363
363
|
"""Destructor to ensure cleanup."""
|
364
364
|
try:
|
365
365
|
self.close()
|
366
366
|
except Exception:
|
367
367
|
pass
|
368
368
|
|
369
|
-
def refresh(self):
|
369
|
+
def refresh(self) -> None:
|
370
370
|
"""Refresh display."""
|
371
371
|
if not self.disable:
|
372
372
|
self._display()
|
373
373
|
|
374
|
-
def clear(self):
|
374
|
+
def clear(self) -> None:
|
375
375
|
"""Clear progress bar."""
|
376
376
|
if not self.disable:
|
377
377
|
try:
|
@@ -381,7 +381,7 @@ class TQDM:
|
|
381
381
|
pass
|
382
382
|
|
383
383
|
@staticmethod
|
384
|
-
def write(s, file=None, end="\n"):
|
384
|
+
def write(s: str, file: IO[str] | None = None, end: str = "\n") -> None:
|
385
385
|
"""Static method to write without breaking progress bar."""
|
386
386
|
file = file or sys.stdout
|
387
387
|
try:
|
@@ -394,14 +394,11 @@ class TQDM:
|
|
394
394
|
if __name__ == "__main__":
|
395
395
|
import time
|
396
396
|
|
397
|
-
# Example 1: Basic usage with known total
|
398
397
|
print("1. Basic progress bar with known total:")
|
399
|
-
for i in TQDM(range(
|
398
|
+
for i in TQDM(range(0), desc="Known total"):
|
400
399
|
time.sleep(0.05)
|
401
|
-
print()
|
402
400
|
|
403
|
-
|
404
|
-
print("2. Manual updates with known total:")
|
401
|
+
print("\n2. Manual updates with known total:")
|
405
402
|
pbar = TQDM(total=30, desc="Manual updates", unit="files")
|
406
403
|
for i in range(30):
|
407
404
|
time.sleep(0.03)
|
@@ -409,10 +406,8 @@ if __name__ == "__main__":
|
|
409
406
|
if i % 10 == 9:
|
410
407
|
pbar.set_description(f"Processing batch {i // 10 + 1}")
|
411
408
|
pbar.close()
|
412
|
-
print()
|
413
409
|
|
414
|
-
|
415
|
-
print("3. Progress bar with unknown total:")
|
410
|
+
print("\n3. Progress bar with unknown total:")
|
416
411
|
pbar = TQDM(desc="Unknown total", unit="items")
|
417
412
|
for i in range(25):
|
418
413
|
time.sleep(0.08)
|
@@ -420,18 +415,14 @@ if __name__ == "__main__":
|
|
420
415
|
if i % 5 == 4:
|
421
416
|
pbar.set_postfix(processed=i + 1, status="OK")
|
422
417
|
pbar.close()
|
423
|
-
print()
|
424
418
|
|
425
|
-
|
426
|
-
print("4. Context manager with unknown total:")
|
419
|
+
print("\n4. Context manager with unknown total:")
|
427
420
|
with TQDM(desc="Processing stream", unit="B", unit_scale=True, unit_divisor=1024) as pbar:
|
428
421
|
for i in range(30):
|
429
422
|
time.sleep(0.1)
|
430
423
|
pbar.update(1024 * 1024 * i) # Simulate processing MB of data
|
431
|
-
print()
|
432
424
|
|
433
|
-
|
434
|
-
print("5. Iterator with unknown length:")
|
425
|
+
print("\n5. Iterator with unknown length:")
|
435
426
|
|
436
427
|
def data_stream():
|
437
428
|
"""Simulate a data stream of unknown length."""
|
@@ -442,10 +433,8 @@ if __name__ == "__main__":
|
|
442
433
|
|
443
434
|
for chunk in TQDM(data_stream(), desc="Stream processing", unit="chunks"):
|
444
435
|
time.sleep(0.1)
|
445
|
-
print()
|
446
436
|
|
447
|
-
|
448
|
-
print("6. File processing simulation (unknown size):")
|
437
|
+
print("\n6. File processing simulation (unknown size):")
|
449
438
|
|
450
439
|
def process_files():
|
451
440
|
"""Simulate processing files of unknown count."""
|
@@ -459,4 +448,3 @@ if __name__ == "__main__":
|
|
459
448
|
pbar.update(1)
|
460
449
|
pbar.set_description(f"Processing {filename}")
|
461
450
|
pbar.close()
|
462
|
-
print()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|