ultralytics 8.3.184__py3-none-any.whl → 8.3.186__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.
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.184"
3
+ __version__ = "8.3.186"
4
4
 
5
5
  import os
6
6
 
@@ -30,14 +30,14 @@ download: |
30
30
  import json
31
31
  from pathlib import Path
32
32
 
33
- from tqdm import tqdm
33
+ from ultralytics.utils import TQDM
34
34
  from ultralytics.utils.downloads import download
35
35
 
36
36
  def argoverse2yolo(set):
37
37
  """Convert Argoverse dataset annotations to YOLO format for object detection tasks."""
38
38
  labels = {}
39
39
  a = json.load(open(set, "rb"))
40
- for annot in tqdm(a["annotations"], desc=f"Converting {set} to YOLOv5 format..."):
40
+ for annot in TQDM(a["annotations"], desc=f"Converting {set} to YOLOv5 format..."):
41
41
  img_id = annot["image_id"]
42
42
  img_name = a["images"][img_id]["name"]
43
43
  img_label_name = f"{img_name[:-3]}txt"
@@ -387,8 +387,8 @@ download: |
387
387
  from pathlib import Path
388
388
 
389
389
  import numpy as np
390
- from tqdm import tqdm
391
390
 
391
+ from ultralytics.utils import TQDM
392
392
  from ultralytics.utils.checks import check_requirements
393
393
  from ultralytics.utils.downloads import download
394
394
  from ultralytics.utils.ops import xyxy2xywhn
@@ -419,7 +419,7 @@ download: |
419
419
  download([f"{url}images/v2/patch{i}.tar.gz" for i in range(16, patches)], dir=images, curl=True, threads=8)
420
420
 
421
421
  # Move
422
- for f in tqdm(images.rglob("*.jpg"), desc=f"Moving {split} images"):
422
+ for f in TQDM(images.rglob("*.jpg"), desc=f"Moving {split} images"):
423
423
  f.rename(images / f.name) # move to /images/{split}
424
424
 
425
425
  # Labels
@@ -428,7 +428,7 @@ download: |
428
428
  for cid, cat in enumerate(names):
429
429
  catIds = coco.getCatIds(catNms=[cat])
430
430
  imgIds = coco.getImgIds(catIds=catIds)
431
- for im in tqdm(coco.loadImgs(imgIds), desc=f"Class {cid + 1}/{len(names)} {cat}"):
431
+ for im in TQDM(coco.loadImgs(imgIds), desc=f"Class {cid + 1}/{len(names)} {cat}"):
432
432
  width, height = im["width"], im["height"]
433
433
  path = Path(im["file_name"]) # image filename
434
434
  try:
@@ -25,8 +25,8 @@ download: |
25
25
 
26
26
  import numpy as np
27
27
  import pandas as pd
28
- from tqdm import tqdm
29
28
 
29
+ from ultralytics.utils import TQDM
30
30
  from ultralytics.utils.downloads import download
31
31
  from ultralytics.utils.ops import xyxy2xywh
32
32
 
@@ -49,7 +49,7 @@ download: |
49
49
  images, unique_images = x[:, 0], np.unique(x[:, 0])
50
50
  with open((dir / d).with_suffix(".txt").__str__().replace("annotations_", ""), "w", encoding="utf-8") as f:
51
51
  f.writelines(f"./images/{s}\n" for s in unique_images)
52
- for im in tqdm(unique_images, desc=f"Converting {dir / d}"):
52
+ for im in TQDM(unique_images, desc=f"Converting {dir / d}"):
53
53
  cls = 0 # single-class dataset
54
54
  with open((dir / "labels" / im).with_suffix(".txt"), "a", encoding="utf-8") as f:
55
55
  for r in x[images == im]:
@@ -48,10 +48,8 @@ download: |
48
48
  import xml.etree.ElementTree as ET
49
49
  from pathlib import Path
50
50
 
51
- from tqdm import tqdm
52
-
53
51
  from ultralytics.utils.downloads import download
54
-
52
+ from ultralytics.utils import TQDM
55
53
 
56
54
  def convert_label(path, lb_path, year, image_id):
57
55
  """Converts XML annotations from VOC format to YOLO format by extracting bounding boxes and class IDs."""
@@ -99,7 +97,7 @@ download: |
99
97
 
100
98
  with open(path / f"VOC{year}/ImageSets/Main/{image_set}.txt") as f:
101
99
  image_ids = f.read().strip().split()
102
- for id in tqdm(image_ids, desc=f"{image_set}{year}"):
100
+ for id in TQDM(image_ids, desc=f"{image_set}{year}"):
103
101
  f = path / f"VOC{year}/JPEGImages/{id}.jpg" # old img path
104
102
  lb_path = (lbs_path / f.name).with_suffix(".txt") # new label path
105
103
  f.rename(imgs_path / f.name) # move image
@@ -34,12 +34,12 @@ download: |
34
34
  import shutil
35
35
 
36
36
  from ultralytics.utils.downloads import download
37
+ from ultralytics.utils import TQDM
37
38
 
38
39
 
39
40
  def visdrone2yolo(dir, split, source_name=None):
40
41
  """Convert VisDrone annotations to YOLO format with images/{split} and labels/{split} structure."""
41
42
  from PIL import Image
42
- from tqdm import tqdm
43
43
 
44
44
  source_dir = dir / (source_name or f"VisDrone2019-DET-{split}")
45
45
  images_dir = dir / "images" / split
@@ -52,7 +52,7 @@ download: |
52
52
  for img in source_images_dir.glob("*.jpg"):
53
53
  img.rename(images_dir / img.name)
54
54
 
55
- for f in tqdm((source_dir / "annotations").glob("*.txt"), desc=f"Converting {split}"):
55
+ for f in TQDM((source_dir / "annotations").glob("*.txt"), desc=f"Converting {split}"):
56
56
  img_size = Image.open(images_dir / f.with_suffix(".jpg").name).size
57
57
  dw, dh = 1.0 / img_size[0], 1.0 / img_size[1]
58
58
  lines = []
@@ -85,8 +85,8 @@ download: |
85
85
 
86
86
  import numpy as np
87
87
  from PIL import Image
88
- from tqdm import tqdm
89
88
 
89
+ from ultralytics.utils import TQDM
90
90
  from ultralytics.data.utils import autosplit
91
91
  from ultralytics.utils.ops import xyxy2xywhn
92
92
 
@@ -110,7 +110,7 @@ download: |
110
110
  47, 48, 49, -1, 50, 51, -1, 52, -1, -1, -1, 53, 54, -1, 55, -1, -1, 56, -1, 57, -1, 58, 59]
111
111
 
112
112
  shapes = {}
113
- for feature in tqdm(data["features"], desc=f"Converting {fname}"):
113
+ for feature in TQDM(data["features"], desc=f"Converting {fname}"):
114
114
  p = feature["properties"]
115
115
  if p["bounds_imcoords"]:
116
116
  id = p["image_id"]
ultralytics/data/build.py CHANGED
@@ -22,7 +22,7 @@ from ultralytics.data.loaders import (
22
22
  SourceTypes,
23
23
  autocast_list,
24
24
  )
25
- from ultralytics.data.utils import IMG_FORMATS, PIN_MEMORY, VID_FORMATS
25
+ from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
26
26
  from ultralytics.utils import RANK, colorstr
27
27
  from ultralytics.utils.checks import check_file
28
28
 
@@ -206,7 +206,7 @@ def build_dataloader(dataset, batch: int, workers: int, shuffle: bool = True, ra
206
206
  shuffle=shuffle and sampler is None,
207
207
  num_workers=nw,
208
208
  sampler=sampler,
209
- pin_memory=PIN_MEMORY,
209
+ pin_memory=nd > 0,
210
210
  collate_fn=getattr(dataset, "collate_fn", None),
211
211
  worker_init_fn=seed_worker,
212
212
  generator=generator,
@@ -613,7 +613,7 @@ def yolo_bbox2segment(
613
613
  from ultralytics.utils.ops import xywh2xyxy
614
614
 
615
615
  # NOTE: add placeholder to pass class index check
616
- dataset = YOLODataset(im_dir, data=dict(names=list(range(1000))))
616
+ dataset = YOLODataset(im_dir, data=dict(names=list(range(1000)), channels=3))
617
617
  if len(dataset.labels[0]["segments"]) > 0: # if it's segment data
618
618
  LOGGER.info("Segmentation labels detected, no need to generate new ones!")
619
619
  return
@@ -85,7 +85,7 @@ class YOLODataset(BaseDataset):
85
85
  self.use_obb = task == "obb"
86
86
  self.data = data
87
87
  assert not (self.use_segments and self.use_keypoints), "Can not use both segments and keypoints."
88
- super().__init__(*args, channels=self.data["channels"], **kwargs)
88
+ super().__init__(*args, channels=self.data.get("channels", 3), **kwargs)
89
89
 
90
90
  def cache_labels(self, path: Path = Path("./labels.cache")) -> Dict:
91
91
  """
ultralytics/data/utils.py CHANGED
@@ -19,7 +19,6 @@ from ultralytics.nn.autobackend import check_class_names
19
19
  from ultralytics.utils import (
20
20
  DATASETS_DIR,
21
21
  LOGGER,
22
- MACOS,
23
22
  NUM_THREADS,
24
23
  ROOT,
25
24
  SETTINGS_FILE,
@@ -37,7 +36,6 @@ from ultralytics.utils.ops import segments2boxes
37
36
  HELP_URL = "See https://docs.ultralytics.com/datasets for dataset formatting guidance."
38
37
  IMG_FORMATS = {"bmp", "dng", "jpeg", "jpg", "mpo", "png", "tif", "tiff", "webp", "pfm", "heic"} # image suffixes
39
38
  VID_FORMATS = {"asf", "avi", "gif", "m4v", "mkv", "mov", "mp4", "mpeg", "mpg", "ts", "wmv", "webm"} # video suffixes
40
- PIN_MEMORY = str(os.getenv("PIN_MEMORY", not MACOS)).lower() == "true" # global pin_memory for dataloaders
41
39
  FORMATS_HELP_MSG = f"Supported formats are:\nimages: {IMG_FORMATS}\nvideos: {VID_FORMATS}"
42
40
 
43
41
 
@@ -1479,7 +1479,10 @@ class IOSDetectModel(torch.nn.Module):
1479
1479
  if w == h:
1480
1480
  self.normalize = 1.0 / w # scalar
1481
1481
  else:
1482
- self.normalize = torch.tensor([1.0 / w, 1.0 / h, 1.0 / w, 1.0 / h]) # broadcast (slower, smaller)
1482
+ self.normalize = torch.tensor(
1483
+ [1.0 / w, 1.0 / h, 1.0 / w, 1.0 / h], # broadcast (slower, smaller)
1484
+ device=next(model.parameters()).device,
1485
+ )
1483
1486
 
1484
1487
  def forward(self, x):
1485
1488
  """Normalize predictions of object detection model with input size-dependent factors."""
@@ -115,8 +115,9 @@ class RegionCounter(BaseSolution):
115
115
 
116
116
  # Display region counts
117
117
  for region in self.counting_regions:
118
- x1, y1, x2, y2 = map(int, region["polygon"].bounds)
119
- pts = [(x1, y1), (x2, y1), (x2, y2), (x1, y2)]
118
+ poly = region["polygon"]
119
+ pts = list(map(tuple, np.array(poly.exterior.coords, dtype=np.int32)))
120
+ (x1, y1), (x2, y2) = [(int(poly.centroid.x), int(poly.centroid.y))] * 2
120
121
  annotator.draw_region(pts, region["region_color"], self.line_width * 2)
121
122
  annotator.adaptive_label(
122
123
  [x1, y1, x2, y2],
@@ -12,7 +12,6 @@ import subprocess
12
12
  import sys
13
13
  import threading
14
14
  import time
15
- import warnings
16
15
  from pathlib import Path
17
16
  from threading import Lock
18
17
  from types import SimpleNamespace
@@ -22,10 +21,10 @@ from urllib.parse import unquote
22
21
  import cv2
23
22
  import numpy as np
24
23
  import torch
25
- import tqdm
26
24
 
27
25
  from ultralytics import __version__
28
26
  from ultralytics.utils.patches import imread, imshow, imwrite, torch_save # for patches
27
+ from ultralytics.utils.tqdm import TQDM # noqa
29
28
 
30
29
  # PyTorch Multi-GPU DDP Constants
31
30
  RANK = int(os.getenv("RANK", -1))
@@ -41,7 +40,6 @@ DEFAULT_CFG_PATH = ROOT / "cfg/default.yaml"
41
40
  NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLO multiprocessing threads
42
41
  AUTOINSTALL = str(os.getenv("YOLO_AUTOINSTALL", True)).lower() == "true" # global auto-install mode
43
42
  VERBOSE = str(os.getenv("YOLO_VERBOSE", True)).lower() == "true" # global verbose mode
44
- TQDM_BAR_FORMAT = "{l_bar}{bar:10}{r_bar}" if VERBOSE else None # tqdm bar format
45
43
  LOGGING_NAME = "ultralytics"
46
44
  MACOS, LINUX, WINDOWS = (platform.system() == x for x in ["Darwin", "Linux", "Windows"]) # environment booleans
47
45
  MACOS_VERSION = platform.mac_ver()[0] if MACOS else None
@@ -130,65 +128,6 @@ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" # suppress verbose TF compiler warning
130
128
  os.environ["TORCH_CPP_LOG_LEVEL"] = "ERROR" # suppress "NNPACK.cpp could not initialize NNPACK" warnings
131
129
  os.environ["KINETO_LOG_LEVEL"] = "5" # suppress verbose PyTorch profiler output when computing FLOPs
132
130
 
133
- if TQDM_RICH := str(os.getenv("YOLO_TQDM_RICH", False)).lower() == "true":
134
- from tqdm import rich
135
-
136
-
137
- class TQDM(rich.tqdm if TQDM_RICH else tqdm.tqdm):
138
- """
139
- A custom TQDM progress bar class that extends the original tqdm functionality.
140
-
141
- This class modifies the behavior of the original tqdm progress bar based on global settings and provides
142
- additional customization options for Ultralytics projects. The progress bar is automatically disabled when
143
- VERBOSE is False or when explicitly disabled.
144
-
145
- Attributes:
146
- disable (bool): Whether to disable the progress bar. Determined by the global VERBOSE setting and
147
- any passed 'disable' argument.
148
- bar_format (str): The format string for the progress bar. Uses the global TQDM_BAR_FORMAT if not
149
- explicitly set.
150
-
151
- Methods:
152
- __init__: Initialize the TQDM object with custom settings.
153
- __iter__: Return self as iterator to satisfy Iterable interface.
154
-
155
- Examples:
156
- >>> from ultralytics.utils import TQDM
157
- >>> for i in TQDM(range(100)):
158
- ... # Your processing code here
159
- ... pass
160
- """
161
-
162
- def __init__(self, *args, **kwargs):
163
- """
164
- Initialize a custom TQDM progress bar with Ultralytics-specific settings.
165
-
166
- Args:
167
- *args (Any): Variable length argument list to be passed to the original tqdm constructor.
168
- **kwargs (Any): Arbitrary keyword arguments to be passed to the original tqdm constructor.
169
-
170
- Notes:
171
- - The progress bar is disabled if VERBOSE is False or if 'disable' is explicitly set to True in kwargs.
172
- - The default bar format is set to TQDM_BAR_FORMAT unless overridden in kwargs.
173
- - In GitHub Actions, progress bars only update at completion to keep CI logs clean.
174
-
175
- Examples:
176
- >>> from ultralytics.utils import TQDM
177
- >>> for i in TQDM(range(100)):
178
- ... # Your code here
179
- ... pass
180
- """
181
- warnings.filterwarnings("ignore", category=tqdm.TqdmExperimentalWarning) # suppress tqdm.rich warning
182
- if is_github_action_running():
183
- kwargs["mininterval"] = 60 # only update every 60 seconds
184
- kwargs["disable"] = not VERBOSE or kwargs.get("disable", False) or LOGGER.getEffectiveLevel() > 20
185
- kwargs.setdefault("bar_format", TQDM_BAR_FORMAT) # override default value if passed
186
- super().__init__(*args, **kwargs)
187
-
188
- def __iter__(self):
189
- """Return self as iterator to satisfy Iterable interface."""
190
- return super().__iter__()
191
-
192
131
 
193
132
  class DataExportMixin:
194
133
  """
@@ -49,7 +49,7 @@ class GPUInfo:
49
49
  self.gpu_stats: List[Dict[str, Any]] = []
50
50
 
51
51
  try:
52
- check_requirements("pynvml>=12.0.0")
52
+ check_requirements("nvidia-ml-py>=12.0.0")
53
53
  self.pynvml = __import__("pynvml")
54
54
  self.pynvml.nvmlInit()
55
55
  self.nvml_available = True
@@ -118,11 +118,11 @@ def zip_directory(directory, compress: bool = True, exclude=(".DS_Store", "__MAC
118
118
  raise FileNotFoundError(f"Directory '{directory}' does not exist.")
119
119
 
120
120
  # Zip with progress bar
121
- files_to_zip = [f for f in directory.rglob("*") if f.is_file() and all(x not in f.name for x in exclude)]
121
+ files = [f for f in directory.rglob("*") if f.is_file() and all(x not in f.name for x in exclude)] # files to zip
122
122
  zip_file = directory.with_suffix(".zip")
123
123
  compression = ZIP_DEFLATED if compress else ZIP_STORED
124
124
  with ZipFile(zip_file, "w", compression) as f:
125
- for file in TQDM(files_to_zip, desc=f"Zipping {directory} to {zip_file}...", unit="file", disable=not progress):
125
+ for file in TQDM(files, desc=f"Zipping {directory} to {zip_file}...", unit="files", disable=not progress):
126
126
  f.write(file, file.relative_to(directory))
127
127
 
128
128
  return zip_file # return path to zip file
@@ -187,7 +187,7 @@ def unzip_file(
187
187
  LOGGER.warning(f"Skipping {file} unzip as destination directory {path} is not empty.")
188
188
  return path
189
189
 
190
- for f in TQDM(files, desc=f"Unzipping {file} to {Path(path).resolve()}...", unit="file", disable=not progress):
190
+ for f in TQDM(files, desc=f"Unzipping {file} to {Path(path).resolve()}...", unit="files", disable=not progress):
191
191
  # Ensure the file is within the extract_path to avoid path traversal security vulnerability
192
192
  if ".." in Path(f).parts:
193
193
  LOGGER.warning(f"Potentially insecure file path: {f}, skipping extraction.")
@@ -295,7 +295,8 @@ def safe_download(
295
295
  progress: bool = True,
296
296
  ):
297
297
  """
298
- Download files from a URL with options for retrying, unzipping, and deleting the downloaded file.
298
+ Download files from a URL with options for retrying, unzipping, and deleting the downloaded file. Enhanced with
299
+ robust partial download detection using Content-Length validation.
299
300
 
300
301
  Args:
301
302
  url (str): The URL of the file to be downloaded.
@@ -342,24 +343,33 @@ def safe_download(
342
343
  s = "sS" * (not progress) # silent
343
344
  r = subprocess.run(["curl", "-#", f"-{s}L", url, "-o", f, "--retry", "3", "-C", "-"]).returncode
344
345
  assert r == 0, f"Curl return value {r}"
346
+ expected_size = None # Can't get size with curl
345
347
  else: # urllib download
346
- # torch.hub.download_url_to_file(url, f, progress=progress) # do not use as progress tqdm differs
347
- with request.urlopen(url) as response, TQDM(
348
- total=int(response.getheader("Content-Length", 0)),
349
- desc=desc,
350
- disable=not progress,
351
- unit="B",
352
- unit_scale=True,
353
- unit_divisor=1024,
354
- ) as pbar:
355
- with open(f, "wb") as f_opened:
356
- for data in response:
357
- f_opened.write(data)
358
- pbar.update(len(data))
348
+ with request.urlopen(url) as response:
349
+ expected_size = int(response.getheader("Content-Length", 0))
350
+ with TQDM(
351
+ total=expected_size,
352
+ desc=desc,
353
+ disable=not progress,
354
+ unit="B",
355
+ unit_scale=True,
356
+ unit_divisor=1024,
357
+ ) as pbar:
358
+ with open(f, "wb") as f_opened:
359
+ for data in response:
360
+ f_opened.write(data)
361
+ pbar.update(len(data))
359
362
 
360
363
  if f.exists():
361
- if f.stat().st_size > min_bytes:
362
- break # success
364
+ file_size = f.stat().st_size
365
+ if file_size > min_bytes:
366
+ # Check if download is complete (only if we have expected_size)
367
+ if expected_size and file_size != expected_size:
368
+ LOGGER.warning(
369
+ f"Partial download: {file_size}/{expected_size} bytes ({file_size / expected_size * 100:.1f}%)"
370
+ )
371
+ else:
372
+ break # success
363
373
  f.unlink() # remove partial downloads
364
374
  except Exception as e:
365
375
  if i == 0 and not is_online():
@@ -77,7 +77,7 @@ class ConsoleLogger:
77
77
  # State tracking
78
78
  self.last_line = ""
79
79
  self.last_time = 0.0
80
- self.last_progress_line = "" # Track 100% progress lines separately
80
+ self.last_progress_line = "" # Track last progress line for deduplication
81
81
  self.last_was_progress = False # Track if last line was a progress bar
82
82
 
83
83
  def start_capture(self):
@@ -127,15 +127,14 @@ class ConsoleLogger:
127
127
  for line in lines:
128
128
  line = line.rstrip()
129
129
 
130
- # Handle progress bars - only show 100% completions
131
- if ("it/s" in line and ("%|" in line or "━" in line)) or (
132
- "100%" in line and ("it/s" in line or "[" in line)
133
- ):
134
- if "100%" not in line:
135
- continue
136
- # Dedupe 100% lines by core content (strip timing)
137
- progress_core = line.split("[")[0].split("]")[0].strip()
138
- if progress_core == self.last_progress_line:
130
+ # Skip lines with only thin progress bars (partial progress)
131
+ if "" in line: # Has thin lines but no thick lines
132
+ continue
133
+
134
+ # Deduplicate completed progress bars only if they match the previous progress line
135
+ if " ━━" in line:
136
+ progress_core = line.split(" ━━")[0].strip()
137
+ if progress_core == self.last_progress_line and self.last_was_progress:
139
138
  continue
140
139
  self.last_progress_line = progress_core
141
140
  self.last_was_progress = True
@@ -271,7 +270,7 @@ class SystemLogger:
271
270
  """Initialize NVIDIA GPU monitoring with pynvml."""
272
271
  try:
273
272
  assert not MACOS
274
- check_requirements("pynvml>=12.0.0")
273
+ check_requirements("nvidia-ml-py>=12.0.0")
275
274
  self.pynvml = __import__("pynvml")
276
275
  self.pynvml.nvmlInit()
277
276
  return True
@@ -285,16 +284,16 @@ class SystemLogger:
285
284
  Collects comprehensive system metrics including CPU usage, RAM usage, disk I/O statistics,
286
285
  network I/O statistics, and GPU metrics (if available). Example output:
287
286
 
288
- ```json
289
- {
290
- 'cpu': 45.2,
291
- 'ram': 78.9,
292
- 'disk': {'read_mb': 156.7, 'write_mb': 89.3, 'used_gb': 256.8},
293
- 'network': {'recv_mb': 157.2, 'sent_mb': 89.1},
294
- 'gpus': {
295
- 0: {'usage': 95.6, 'memory': 85.4, 'temp': 72, 'power': 285},
296
- 1: {'usage': 94.1, 'memory': 82.7, 'temp': 70, 'power': 278}
297
- }
287
+ ```python
288
+ metrics = {
289
+ "cpu": 45.2,
290
+ "ram": 78.9,
291
+ "disk": {"read_mb": 156.7, "write_mb": 89.3, "used_gb": 256.8},
292
+ "network": {"recv_mb": 157.2, "sent_mb": 89.1},
293
+ "gpus": {
294
+ 0: {"usage": 95.6, "memory": 85.4, "temp": 72, "power": 285},
295
+ 1: {"usage": 94.1, "memory": 82.7, "temp": 70, "power": 278},
296
+ },
298
297
  }
299
298
  ```
300
299
 
@@ -314,7 +313,7 @@ class SystemLogger:
314
313
  - power (int): GPU power consumption in watts
315
314
 
316
315
  Returns:
317
- (dict): System metrics containing 'cpu', 'ram', 'disk', 'network', 'gpus' with respective usage data.
316
+ metrics (dict): System metrics containing 'cpu', 'ram', 'disk', 'network', 'gpus' with respective usage data.
318
317
  """
319
318
  net = psutil.net_io_counters()
320
319
  disk = psutil.disk_io_counters()
@@ -0,0 +1,462 @@
1
+ # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import sys
7
+ import time
8
+ from functools import lru_cache
9
+ from typing import IO, Any
10
+
11
+
12
+ @lru_cache(maxsize=1)
13
+ def is_noninteractive_console():
14
+ """Check for known non-interactive console environments."""
15
+ return "GITHUB_ACTIONS" in os.environ or "RUNPOD_POD_ID" in os.environ
16
+
17
+
18
+ class TQDM:
19
+ """
20
+ Lightweight zero-dependency progress bar for Ultralytics.
21
+
22
+ Provides clean, rich-style progress bars suitable for various environments including Weights & Biases,
23
+ console outputs, and other logging systems. Features zero external dependencies, clean single-line output,
24
+ rich-style progress bars with Unicode block characters, context manager support, iterator protocol support,
25
+ and dynamic description updates.
26
+
27
+ Attributes:
28
+ iterable (object): Iterable to wrap with progress bar.
29
+ desc (str): Prefix description for the progress bar.
30
+ total (int): Expected number of iterations.
31
+ disable (bool): Whether to disable the progress bar.
32
+ unit (str): String for units of iteration.
33
+ unit_scale (bool): Auto-scale units flag.
34
+ unit_divisor (int): Divisor for unit scaling.
35
+ leave (bool): Whether to leave the progress bar after completion.
36
+ mininterval (float): Minimum time interval between updates.
37
+ initial (int): Initial counter value.
38
+ n (int): Current iteration count.
39
+ closed (bool): Whether the progress bar is closed.
40
+ bar_format (str): Custom bar format string.
41
+ file (object): Output file stream.
42
+
43
+ Methods:
44
+ update: Update progress by n steps.
45
+ set_description: Set or update the description.
46
+ set_postfix: Set postfix for the progress bar.
47
+ close: Close the progress bar and clean up.
48
+ refresh: Refresh the progress bar display.
49
+ clear: Clear the progress bar from display.
50
+ write: Write a message without breaking the progress bar.
51
+
52
+ Examples:
53
+ Basic usage with iterator:
54
+ >>> for i in TQDM(range(100)):
55
+ ... time.sleep(0.01)
56
+
57
+ With custom description:
58
+ >>> pbar = TQDM(range(100), desc="Processing")
59
+ >>> for i in pbar:
60
+ ... pbar.set_description(f"Processing item {i}")
61
+
62
+ Context manager usage:
63
+ >>> with TQDM(total=100, unit="B", unit_scale=True) as pbar:
64
+ ... for i in range(100):
65
+ ... pbar.update(1)
66
+
67
+ Manual updates:
68
+ >>> pbar = TQDM(total=100, desc="Training")
69
+ >>> for epoch in range(100):
70
+ ... # Do work
71
+ ... pbar.update(1)
72
+ >>> pbar.close()
73
+ """
74
+
75
+ # Constants
76
+ MIN_RATE_CALC_INTERVAL = 0.01 # Minimum time interval for rate calculation
77
+ RATE_SMOOTHING_FACTOR = 0.3 # Factor for exponential smoothing of rates
78
+ MAX_SMOOTHED_RATE = 1000000 # Maximum rate to apply smoothing to
79
+ NONINTERACTIVE_MIN_INTERVAL = 60.0 # Minimum interval for non-interactive environments
80
+
81
+ def __init__(
82
+ self,
83
+ iterable: Any = None,
84
+ desc: str | None = None,
85
+ total: int | None = None,
86
+ leave: bool = True,
87
+ file: IO[str] | None = None,
88
+ mininterval: float = 0.1,
89
+ disable: bool | None = None,
90
+ unit: str = "it",
91
+ unit_scale: bool = False,
92
+ unit_divisor: int = 1000,
93
+ bar_format: str | None = None,
94
+ initial: int = 0,
95
+ **kwargs, # Accept unused args for compatibility
96
+ ) -> None:
97
+ """
98
+ Initialize the TQDM progress bar with specified configuration options.
99
+
100
+ Args:
101
+ iterable (object, optional): Iterable to wrap with progress bar.
102
+ desc (str, optional): Prefix description for the progress bar.
103
+ total (int, optional): Expected number of iterations.
104
+ leave (bool, optional): Whether to leave the progress bar after completion.
105
+ file (object, optional): Output file stream for progress display.
106
+ mininterval (float, optional): Minimum time interval between updates (default 0.1s, 60s in GitHub Actions).
107
+ disable (bool, optional): Whether to disable the progress bar. Auto-detected if None.
108
+ unit (str, optional): String for units of iteration (default "it" for items).
109
+ unit_scale (bool, optional): Auto-scale units for bytes/data units.
110
+ unit_divisor (int, optional): Divisor for unit scaling (default 1000).
111
+ bar_format (str, optional): Custom bar format string.
112
+ initial (int, optional): Initial counter value.
113
+ **kwargs (Any): Additional keyword arguments for compatibility (ignored).
114
+
115
+ Examples:
116
+ >>> pbar = TQDM(range(100), desc="Processing")
117
+ >>> with TQDM(total=1000, unit="B", unit_scale=True) as pbar:
118
+ ... pbar.update(1024) # Updates by 1KB
119
+ """
120
+ # Disable if not verbose
121
+ if disable is None:
122
+ try:
123
+ from ultralytics.utils import LOGGER, VERBOSE
124
+
125
+ disable = not VERBOSE or LOGGER.getEffectiveLevel() > 20
126
+ except ImportError:
127
+ disable = False
128
+
129
+ self.iterable = iterable
130
+ self.desc = desc or ""
131
+ self.total = total if total is not None else (len(iterable) if hasattr(iterable, "__len__") else None)
132
+ self.disable = disable
133
+ self.unit = unit
134
+ self.unit_scale = unit_scale
135
+ self.unit_divisor = unit_divisor
136
+ self.leave = leave
137
+ self.noninteractive = is_noninteractive_console()
138
+ self.mininterval = max(mininterval, self.NONINTERACTIVE_MIN_INTERVAL) if self.noninteractive else mininterval
139
+ self.initial = initial
140
+
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}"
144
+ else:
145
+ self.bar_format = bar_format or "{desc}: {bar} {n_fmt} {rate_fmt} {elapsed}"
146
+
147
+ self.file = file or sys.stdout
148
+
149
+ # Internal state
150
+ self.n = self.initial
151
+ self.last_print_n = self.initial
152
+ self.last_print_t = time.time()
153
+ self.start_t = time.time()
154
+ self.last_rate = 0
155
+ self.closed = False
156
+
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:
159
+ self._display()
160
+
161
+ def _format_rate(self, rate):
162
+ """Format rate with proper units and reasonable precision."""
163
+ if rate <= 0:
164
+ return ""
165
+
166
+ # For bytes with scaling, use binary units
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")]:
169
+ if rate >= threshold:
170
+ return f"{rate / threshold:.1f}{unit}"
171
+ return f"{rate:.1f}B/s"
172
+
173
+ # For other scalable units, use decimal units
174
+ if self.unit_scale and self.unit in ("it", "items", ""):
175
+ for threshold, prefix in [(1000000, "M"), (1000, "K")]:
176
+ if rate >= threshold:
177
+ return f"{rate / threshold:.1f}{prefix}{self.unit}/s"
178
+
179
+ # Default formatting
180
+ precision = ".1f" if rate >= 1 else ".2f"
181
+ return f"{rate:{precision}}{self.unit}/s"
182
+
183
+ def _format_num(self, num):
184
+ """Format number with optional unit scaling."""
185
+ if not self.unit_scale or self.unit not in ("B", "bytes"):
186
+ return str(num)
187
+
188
+ for unit in ["", "K", "M", "G", "T"]:
189
+ if abs(num) < self.unit_divisor:
190
+ return f"{num:3.1f}{unit}B" if unit else f"{num:.0f}B"
191
+ num /= self.unit_divisor
192
+ return f"{num:.1f}PB"
193
+
194
+ def _format_time(self, seconds):
195
+ """Format time duration."""
196
+ if seconds < 60:
197
+ return f"{seconds:.1f}s"
198
+ elif seconds < 3600:
199
+ return f"{int(seconds // 60)}:{seconds % 60:02.0f}"
200
+ else:
201
+ h, m = int(seconds // 3600), int((seconds % 3600) // 60)
202
+ return f"{h}:{m:02d}:{seconds % 60:02.0f}"
203
+
204
+ def _generate_bar(self, width=12):
205
+ """Generate progress bar."""
206
+ if self.total is None:
207
+ return "━" * width if self.closed else "─" * width
208
+
209
+ frac = min(1.0, self.n / self.total)
210
+ filled = int(frac * width)
211
+ bar = "━" * filled + "─" * (width - filled)
212
+ if filled < width and frac * width - filled > 0.5:
213
+ bar = bar[:filled] + "╸" + bar[filled + 1 :]
214
+ return bar
215
+
216
+ def _should_update(self, dt, dn):
217
+ """Check if display should update."""
218
+ if self.noninteractive:
219
+ return False
220
+
221
+ if self.total is not None and self.n >= self.total:
222
+ return True
223
+
224
+ return dt >= self.mininterval
225
+
226
+ def _display(self, final=False):
227
+ """Display progress bar."""
228
+ if self.disable or (self.closed and not final):
229
+ return
230
+
231
+ current_time = time.time()
232
+ dt = current_time - self.last_print_t
233
+ dn = self.n - self.last_print_n
234
+
235
+ if not final and not self._should_update(dt, dn):
236
+ return
237
+
238
+ # Calculate rate (avoid crazy numbers)
239
+ if dt > self.MIN_RATE_CALC_INTERVAL: # Only calculate rate if enough time has passed
240
+ rate = dn / dt
241
+ # Smooth rate for reasonable values, use raw rate for very high values
242
+ if rate < self.MAX_SMOOTHED_RATE:
243
+ self.last_rate = self.RATE_SMOOTHING_FACTOR * rate + (1 - self.RATE_SMOOTHING_FACTOR) * self.last_rate
244
+ rate = self.last_rate
245
+ else:
246
+ rate = self.last_rate
247
+
248
+ # At completion, use the overall rate for more accurate display
249
+ if self.n >= (self.total or float("inf")) and self.total and self.total > 0:
250
+ overall_elapsed = current_time - self.start_t
251
+ if overall_elapsed > 0:
252
+ rate = self.n / overall_elapsed
253
+
254
+ # Update counters
255
+ self.last_print_n = self.n
256
+ self.last_print_t = current_time
257
+ elapsed = current_time - self.start_t
258
+
259
+ # Build progress components
260
+ if self.total is not None:
261
+ percentage = (self.n / self.total) * 100
262
+ # 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)
265
+ if self.unit_scale and self.unit in ("B", "bytes"):
266
+ n_fmt = n_fmt.rstrip("KMGTPB") # Remove unit suffix from current
267
+ else:
268
+ percentage = 0
269
+ n_fmt = self._format_num(self.n)
270
+ total_fmt = "?"
271
+
272
+ elapsed_str = self._format_time(elapsed)
273
+ rate_fmt = self._format_rate(rate) or (self._format_rate(self.n / elapsed) if elapsed > 0 else "")
274
+
275
+ # Format progress string
276
+ progress_str = self.bar_format.format(
277
+ desc=self.desc,
278
+ percentage=percentage,
279
+ bar=self._generate_bar(),
280
+ n_fmt=n_fmt,
281
+ total_fmt=total_fmt,
282
+ rate_fmt=rate_fmt,
283
+ elapsed=elapsed_str,
284
+ unit=self.unit,
285
+ )
286
+
287
+ # Write to output
288
+ try:
289
+ if self.noninteractive:
290
+ # In non-interactive environments, avoid carriage return which creates empty lines
291
+ self.file.write(progress_str)
292
+ else:
293
+ # In interactive terminals, use carriage return and clear line for updating display
294
+ self.file.write(f"\r\033[K{progress_str}")
295
+ self.file.flush()
296
+ except Exception:
297
+ pass
298
+
299
+ def update(self, n=1):
300
+ """Update progress by n steps."""
301
+ if not self.disable and not self.closed:
302
+ self.n += n
303
+ self._display()
304
+
305
+ def set_description(self, desc):
306
+ """Set description."""
307
+ self.desc = desc or ""
308
+ if not self.disable:
309
+ self._display()
310
+
311
+ def set_postfix(self, **kwargs):
312
+ """Set postfix (appends to description)."""
313
+ if kwargs:
314
+ postfix = ", ".join(f"{k}={v}" for k, v in kwargs.items())
315
+ base_desc = self.desc.split(" | ")[0] if " | " in self.desc else self.desc
316
+ self.set_description(f"{base_desc} | {postfix}")
317
+
318
+ def close(self):
319
+ """Close progress bar."""
320
+ if self.closed:
321
+ return
322
+
323
+ self.closed = True # Set before final display
324
+
325
+ if not self.disable:
326
+ # Final display
327
+ if self.total and self.n >= self.total:
328
+ self.n = self.total
329
+ self._display(final=True)
330
+
331
+ # Cleanup
332
+ if self.leave:
333
+ self.file.write("\n")
334
+ else:
335
+ self.file.write("\r\033[K")
336
+
337
+ try:
338
+ self.file.flush()
339
+ except Exception:
340
+ pass
341
+
342
+ def __enter__(self):
343
+ """Enter context manager."""
344
+ return self
345
+
346
+ def __exit__(self, *args):
347
+ """Exit context manager and close progress bar."""
348
+ self.close()
349
+
350
+ def __iter__(self):
351
+ """Iterate over the wrapped iterable with progress updates."""
352
+ if self.iterable is None:
353
+ raise TypeError("'NoneType' object is not iterable")
354
+
355
+ try:
356
+ for item in self.iterable:
357
+ yield item
358
+ self.update(1)
359
+ finally:
360
+ self.close()
361
+
362
+ def __del__(self):
363
+ """Destructor to ensure cleanup."""
364
+ try:
365
+ self.close()
366
+ except Exception:
367
+ pass
368
+
369
+ def refresh(self):
370
+ """Refresh display."""
371
+ if not self.disable:
372
+ self._display()
373
+
374
+ def clear(self):
375
+ """Clear progress bar."""
376
+ if not self.disable:
377
+ try:
378
+ self.file.write("\r\033[K")
379
+ self.file.flush()
380
+ except Exception:
381
+ pass
382
+
383
+ @staticmethod
384
+ def write(s, file=None, end="\n"):
385
+ """Static method to write without breaking progress bar."""
386
+ file = file or sys.stdout
387
+ try:
388
+ file.write(s + end)
389
+ file.flush()
390
+ except Exception:
391
+ pass
392
+
393
+
394
+ if __name__ == "__main__":
395
+ import time
396
+
397
+ # Example 1: Basic usage with known total
398
+ print("1. Basic progress bar with known total:")
399
+ for i in TQDM(range(20), desc="Known total"):
400
+ time.sleep(0.05)
401
+ print()
402
+
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):
407
+ time.sleep(0.03)
408
+ pbar.update(1)
409
+ if i % 10 == 9:
410
+ pbar.set_description(f"Processing batch {i // 10 + 1}")
411
+ pbar.close()
412
+ print()
413
+
414
+ # Example 3: Unknown total - this was the problematic case
415
+ print("3. Progress bar with unknown total:")
416
+ pbar = TQDM(desc="Unknown total", unit="items")
417
+ for i in range(25):
418
+ time.sleep(0.08)
419
+ pbar.update(1)
420
+ if i % 5 == 4:
421
+ pbar.set_postfix(processed=i + 1, status="OK")
422
+ pbar.close()
423
+ print()
424
+
425
+ # Example 4: Context manager with unknown total
426
+ print("4. Context manager with unknown total:")
427
+ with TQDM(desc="Processing stream", unit="B", unit_scale=True, unit_divisor=1024) as pbar:
428
+ for i in range(30):
429
+ time.sleep(0.1)
430
+ pbar.update(1024 * 1024 * i) # Simulate processing MB of data
431
+ print()
432
+
433
+ # Example 5: Generator with unknown length
434
+ print("5. Iterator with unknown length:")
435
+
436
+ def data_stream():
437
+ """Simulate a data stream of unknown length."""
438
+ import random
439
+
440
+ for i in range(random.randint(10, 20)):
441
+ yield f"data_chunk_{i}"
442
+
443
+ for chunk in TQDM(data_stream(), desc="Stream processing", unit="chunks"):
444
+ time.sleep(0.1)
445
+ print()
446
+
447
+ # Example 6: File-like processing simulation
448
+ print("6. File processing simulation (unknown size):")
449
+
450
+ def process_files():
451
+ """Simulate processing files of unknown count."""
452
+ files = [f"file_{i}.txt" for i in range(18)]
453
+ return files
454
+
455
+ pbar = TQDM(desc="Scanning files", unit="files")
456
+ files = process_files()
457
+ for i, filename in enumerate(files):
458
+ time.sleep(0.06)
459
+ pbar.update(1)
460
+ pbar.set_description(f"Processing {filename}")
461
+ pbar.close()
462
+ print()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ultralytics
3
- Version: 8.3.184
3
+ Version: 8.3.186
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>
@@ -42,7 +42,6 @@ Requires-Dist: scipy>=1.4.1
42
42
  Requires-Dist: torch>=1.8.0
43
43
  Requires-Dist: torch!=2.4.0,>=1.8.0; sys_platform == "win32"
44
44
  Requires-Dist: torchvision>=0.9.0
45
- Requires-Dist: tqdm>=4.64.0
46
45
  Requires-Dist: psutil
47
46
  Requires-Dist: py-cpuinfo
48
47
  Requires-Dist: pandas>=1.1.4
@@ -55,7 +54,7 @@ Requires-Dist: coverage[toml]; extra == "dev"
55
54
  Requires-Dist: mkdocs>=1.6.0; extra == "dev"
56
55
  Requires-Dist: mkdocs-material>=9.5.9; extra == "dev"
57
56
  Requires-Dist: mkdocstrings[python]; extra == "dev"
58
- Requires-Dist: mkdocs-ultralytics-plugin>=0.1.26; extra == "dev"
57
+ Requires-Dist: mkdocs-ultralytics-plugin>=0.1.28; extra == "dev"
59
58
  Requires-Dist: mkdocs-macros-plugin>=1.0.5; extra == "dev"
60
59
  Provides-Extra: export
61
60
  Requires-Dist: numpy<2.0.0; extra == "export"
@@ -100,7 +99,7 @@ Dynamic: license-file
100
99
 
101
100
  <div>
102
101
  <a href="https://github.com/ultralytics/ultralytics/actions/workflows/ci.yml"><img src="https://github.com/ultralytics/ultralytics/actions/workflows/ci.yml/badge.svg" alt="Ultralytics CI"></a>
103
- <a href="https://pepy.tech/projects/ultralytics"><img src="https://static.pepy.tech/badge/ultralytics" alt="Ultralytics Downloads"></a>
102
+ <a href="https://clickpy.clickhouse.com/dashboard/ultralytics"><img src="https://static.pepy.tech/badge/ultralytics" alt="Ultralytics Downloads"></a>
104
103
  <a href="https://zenodo.org/badge/latestdoi/264818686"><img src="https://zenodo.org/badge/264818686.svg" alt="Ultralytics YOLO Citation"></a>
105
104
  <a href="https://discord.com/invite/ultralytics"><img alt="Ultralytics Discord" src="https://img.shields.io/discord/1089800235347353640?logo=discord&logoColor=white&label=Discord&color=blue"></a>
106
105
  <a href="https://community.ultralytics.com/"><img alt="Ultralytics Forums" src="https://img.shields.io/discourse/users?server=https%3A%2F%2Fcommunity.ultralytics.com&logo=discourse&label=Forums&color=blue"></a>
@@ -149,7 +148,7 @@ See below for quickstart installation and usage examples. For comprehensive guid
149
148
 
150
149
  Install the `ultralytics` package, including all [requirements](https://github.com/ultralytics/ultralytics/blob/main/pyproject.toml), in a [**Python>=3.8**](https://www.python.org/) environment with [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/).
151
150
 
152
- [![PyPI - Version](https://img.shields.io/pypi/v/ultralytics?logo=pypi&logoColor=white)](https://pypi.org/project/ultralytics/) [![Ultralytics Downloads](https://static.pepy.tech/badge/ultralytics)](https://www.pepy.tech/projects/ultralytics) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ultralytics?logo=python&logoColor=gold)](https://pypi.org/project/ultralytics/)
151
+ [![PyPI - Version](https://img.shields.io/pypi/v/ultralytics?logo=pypi&logoColor=white)](https://pypi.org/project/ultralytics/) [![Ultralytics Downloads](https://static.pepy.tech/badge/ultralytics)](https://clickpy.clickhouse.com/dashboard/ultralytics) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/ultralytics?logo=python&logoColor=gold)](https://pypi.org/project/ultralytics/)
153
152
 
154
153
  ```bash
155
154
  pip install ultralytics
@@ -7,22 +7,22 @@ tests/test_exports.py,sha256=CY-4xVZlVM16vdyIC0mSR3Ix59aiZm1qjFGIhSNmB20,11007
7
7
  tests/test_integrations.py,sha256=kl_AKmE_Qs1GB0_91iVwbzNxofm_hFTt0zzU6JF-pg4,6323
8
8
  tests/test_python.py,sha256=JbOB6pbTkoQtPCjkl_idagV0_W2QLWGbsh2IvGmru0M,28274
9
9
  tests/test_solutions.py,sha256=tuf6n_fsI8KvSdJrnc-cqP2qYdiYqCWuVrx0z9dOz3Q,13213
10
- ultralytics/__init__.py,sha256=kmDSXeMJ22pJg_A2qaxP4Tfo1tvv2GgD4p-GFyVa2iI,730
10
+ ultralytics/__init__.py,sha256=CCcYcTlUEFxDB3syD60I3oQ4B2UFVPb4gCZ-jatuAsU,730
11
11
  ultralytics/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
12
12
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
13
13
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
14
14
  ultralytics/cfg/__init__.py,sha256=Uj1br3-NVFvP6VY5CL4PK63mAQAom93XFC5cqSbM6t4,39887
15
15
  ultralytics/cfg/default.yaml,sha256=1SspGAK_K_DT7DBfEScJh4jsJUTOxahehZYj92xmj7o,8347
16
- ultralytics/cfg/datasets/Argoverse.yaml,sha256=4SGaJio9JFUkrscHJTPnH_QSbYm48Wbk8EFwl39zntc,3262
16
+ ultralytics/cfg/datasets/Argoverse.yaml,sha256=J4ItoUlE_EiYTmp1DFKYHfbqHkj8j4wUtRJQhaMIlBM,3275
17
17
  ultralytics/cfg/datasets/DOTAv1.5.yaml,sha256=VZ_KKFX0H2YvlFVJ8JHcLWYBZ2xiQ6Z-ROSTiKWpS7c,1211
18
18
  ultralytics/cfg/datasets/DOTAv1.yaml,sha256=JrDuYcQ0JU9lJlCA-dCkMNko_jaj6MAVGHjsfjeZ_u0,1181
19
19
  ultralytics/cfg/datasets/GlobalWheat2020.yaml,sha256=dnr_loeYSE6Eo_f7V1yubILsMRBMRm1ozyC5r7uT-iY,2144
20
20
  ultralytics/cfg/datasets/HomeObjects-3K.yaml,sha256=xEtSqEad-rtfGuIrERjjhdISggmPlvaX-315ZzKz50I,934
21
21
  ultralytics/cfg/datasets/ImageNet.yaml,sha256=GvDWypLVG_H3H67Ai8IC1pvK6fwcTtF5FRhzO1OXXDU,42530
22
- ultralytics/cfg/datasets/Objects365.yaml,sha256=vLzbT3xgpLR-bHhrHOiYyzYvDIniRdevgSyPetm8QHk,9354
23
- ultralytics/cfg/datasets/SKU-110K.yaml,sha256=a52le1-JQ2YH6b1WLMUxVz7RkZ36YsmXgWyw0z3q9nQ,2542
24
- ultralytics/cfg/datasets/VOC.yaml,sha256=o09FWAAsr1MH3ftBJ_n-4Tmc3zxnVJL1HqlqKRUYVTQ,3774
25
- ultralytics/cfg/datasets/VisDrone.yaml,sha256=dYAewe84CrGmxAA_z6UnZUAd7peaw5l3ARDcssojADk,3604
22
+ ultralytics/cfg/datasets/Objects365.yaml,sha256=eMQuA8B4ZGp_GsmMNKFP4CziMSVduyuAK1IANkAZaJw,9367
23
+ ultralytics/cfg/datasets/SKU-110K.yaml,sha256=25M1xoJRqw-UEHmeAiyLKCzk0kTLj0FSlwpZ9dRKwIw,2555
24
+ ultralytics/cfg/datasets/VOC.yaml,sha256=NhVLvsmLOwMIteW4DPKxetURP5bTaJvYc7w08-HYAUs,3785
25
+ ultralytics/cfg/datasets/VisDrone.yaml,sha256=RauTGwmGetLjamcPCiBL7FEWwd8mAA1Y4ARlozX6-E8,3613
26
26
  ultralytics/cfg/datasets/african-wildlife.yaml,sha256=SuloMp9WAZBigGC8az-VLACsFhTM76_O29yhTvUqdnU,915
27
27
  ultralytics/cfg/datasets/brain-tumor.yaml,sha256=qrxPO_t9wxbn2kHFwP3vGTzSWj2ELTLelUwYL3_b6nc,800
28
28
  ultralytics/cfg/datasets/carparts-seg.yaml,sha256=A4e9hM1unTY2jjZIXGiKSarF6R-Ad9R99t57OgRJ37w,1253
@@ -46,7 +46,7 @@ ultralytics/cfg/datasets/open-images-v7.yaml,sha256=wK9v3OAGdHORkFdqoBi0hS0fa1b7
46
46
  ultralytics/cfg/datasets/package-seg.yaml,sha256=V4uyTDWWzgft24y9HJWuELKuZ5AndAHXbanxMI6T8GU,849
47
47
  ultralytics/cfg/datasets/signature.yaml,sha256=gBvU3715gVxVAafI_yaYczGX3kfEfA4BttbiMkgOXNk,774
48
48
  ultralytics/cfg/datasets/tiger-pose.yaml,sha256=Y_8htA4--6hmpqHTW-Ix4t9SdaWenSSyl_FUtI2A7n8,926
49
- ultralytics/cfg/datasets/xView.yaml,sha256=NEEGaRTvTGafckJiFD1ltFyMl0b04zOyOFu_J-PN-Ik,5340
49
+ ultralytics/cfg/datasets/xView.yaml,sha256=P347BJlmb7AG7YC29JyyOtNy52QqZ87Sn7gFP8Dx86s,5353
50
50
  ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml,sha256=1Ycp9qMrwpb8rq7cqht3Q-1gMN0R87U35nm2j_isdro,524
51
51
  ultralytics/cfg/models/11/yolo11-cls.yaml,sha256=17l5GdN-Vst4LvafsK2-q6Li9VX9UlUcT5ClCtikweE,1412
52
52
  ultralytics/cfg/models/11/yolo11-obb.yaml,sha256=3M_c06B-y8da4tunHVxQQ-iFUNLKUfofqCZTpnH5FEU,2034
@@ -108,19 +108,19 @@ ultralytics/data/__init__.py,sha256=nAXaL1puCc7z_NjzQNlJnhbVhT9Fla2u7Dsqo7q1dAc,
108
108
  ultralytics/data/annotator.py,sha256=uAgd7K-yudxiwdNqHz0ubfFg5JsfNlae4cgxdvCMyuY,3030
109
109
  ultralytics/data/augment.py,sha256=Ps1s-ug_oXdyAz4Jyur6OmxzRlyzwP3VP-3hDalSxj8,132959
110
110
  ultralytics/data/base.py,sha256=mRcuehK1thNuuzQGL6D1AaZkod71oHRdYTod_zdQZQg,19688
111
- ultralytics/data/build.py,sha256=TfMLSPMbE2hGZVMLl178NTFrihC1-50jNOt1ex9elxw,11480
112
- ultralytics/data/converter.py,sha256=G5IDSk9kJAERNeJC2G3FwV_CGZ6EKV9oyuf-uKbAmzA,32084
113
- ultralytics/data/dataset.py,sha256=GhoFzBiuGvTr_5-3pzgWu6D_3aQVwW-hcS7kCo8XscM,36752
111
+ ultralytics/data/build.py,sha256=v2dHe52m_cqKnRSWZhEcpGynKMCB-dgw4SyVnfTNAXA,11464
112
+ ultralytics/data/converter.py,sha256=h-0liMb7OkxoR7P0h_mOUpEu5KUsocH3fVEAz3_-p-I,32096
113
+ ultralytics/data/dataset.py,sha256=0GyB6PPsUXMxpf88RyvhGcsREDCenS7Xvc8CrMWivco,36759
114
114
  ultralytics/data/loaders.py,sha256=u9sExTGPy1iiqVd_p29zVoEkQ3C36g2rE0FEbYPET0A,31767
115
115
  ultralytics/data/split.py,sha256=F6O73bAbESj70FQZzqkydXQeXgPXGHGiC06b5MkLHjQ,5109
116
116
  ultralytics/data/split_dota.py,sha256=rr-lLpTUVaFZMggV_fUYZdFVIJk_zbbSOpgB_Qp50_M,12893
117
- ultralytics/data/utils.py,sha256=YA0fLAwxgXdEbQnbieEv4wPFhtnmJX1L67LzVbVwVZk,36794
117
+ ultralytics/data/utils.py,sha256=Zt01BBVwpdHBLwkJC_qTUpaokhF_74hmBYQC3d9Ic8w,36675
118
118
  ultralytics/data/scripts/download_weights.sh,sha256=0y8XtZxOru7dVThXDFUXLHBuICgOIqZNUwpyL4Rh6lg,595
119
119
  ultralytics/data/scripts/get_coco.sh,sha256=UuJpJeo3qQpTHVINeOpmP0NYmg8PhEFE3A8J3jKrnPw,1768
120
120
  ultralytics/data/scripts/get_coco128.sh,sha256=qmRQl_hOKrsdHrTrnyQuFIH01oDz3lfaz138OgGfLt8,650
121
121
  ultralytics/data/scripts/get_imagenet.sh,sha256=hr42H16bM47iT27rgS7MpEo-GeOZAYUQXgr0B2cwn48,1705
122
122
  ultralytics/engine/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6DXppv1-QUM,70
123
- ultralytics/engine/exporter.py,sha256=Vr7K8Yf3wyf91ZvDpRosAohwa_W0oe4qW-JvqigCPfk,75190
123
+ ultralytics/engine/exporter.py,sha256=-AUku73LwK0l_Gt71evXQIJg3WpC2jr73S-87vw5T6g,75277
124
124
  ultralytics/engine/model.py,sha256=877u2n0ISz2COOYtEMUqQe0E-HHB4Atb2DuH1XCE98k,53530
125
125
  ultralytics/engine/predictor.py,sha256=iXnUB-tvBHtVpKbB-5EKs1wSREBIerdUxWx39MaFYuk,22485
126
126
  ultralytics/engine/results.py,sha256=QcHcbPVlLBiy_APwABr-T5K65HR8Bl1rRzxawjjP76E,71873
@@ -217,7 +217,7 @@ ultralytics/solutions/object_counter.py,sha256=zD-EYIxu_y7qCFEkv6aqV60oMCZ4q6b_k
217
217
  ultralytics/solutions/object_cropper.py,sha256=lRKtWINAe9GDxau1Xejbjydsqg2hrpGZXPtZwTgvyKQ,3603
218
218
  ultralytics/solutions/parking_management.py,sha256=IfPUn15aelxz6YZNo9WYkVEl5IOVSw8VD0OrpKtExPE,13613
219
219
  ultralytics/solutions/queue_management.py,sha256=gTkILx4dVcsKRZXSCXtelkEjCRiDS5iznb3FnddC61c,4390
220
- ultralytics/solutions/region_counter.py,sha256=Ncd6_qIXmSQXUxCwQkgYc2-nI7KifQYhxPi3pOelZak,5950
220
+ ultralytics/solutions/region_counter.py,sha256=gaBN5piMyIJSk0DBycKxm7HXHOfixA0meITcMxbwHOg,6031
221
221
  ultralytics/solutions/security_alarm.py,sha256=czEaMcy04q-iBkKqT_14d8H20CFB6zcKH_31nBGQnyw,6345
222
222
  ultralytics/solutions/similarity_search.py,sha256=c18TK0qW5AvanXU28nAX4o_WtB1SDAJStUtyLDuEBHQ,9505
223
223
  ultralytics/solutions/solutions.py,sha256=9dTkAx1W-0oaZGwKyysXTxKCYNBEV4kThRjqsQea2VQ,36059
@@ -235,18 +235,18 @@ ultralytics/trackers/utils/__init__.py,sha256=lm6MckFYCPTbqIoX7w0s_daxdjNeBeKW6D
235
235
  ultralytics/trackers/utils/gmc.py,sha256=9IvCf5MhBYY9ppVHykN02_oBWHmE98R8EaYFKaykdV0,14032
236
236
  ultralytics/trackers/utils/kalman_filter.py,sha256=PPmM0lwBMdT_hGojvfLoUsBUFMBBMNRAxKbMcQa3wJ0,21619
237
237
  ultralytics/trackers/utils/matching.py,sha256=uSYtywqi1lE_uNN1FwuBFPyISfDQXHMu8K5KH69nrRI,7160
238
- ultralytics/utils/__init__.py,sha256=aplfwLydgiAC4DQt3AO4gNh2U58z16ss5UTQkRd5Jz0,59643
238
+ ultralytics/utils/__init__.py,sha256=jI8xbKM4OrRFvYbT7j1qAlRmvKTnVSHyHzY-On3yAjI,56982
239
239
  ultralytics/utils/autobatch.py,sha256=33m8YgggLIhltDqMXZ5OE-FGs2QiHrl2-LfgY1mI4cw,5119
240
- ultralytics/utils/autodevice.py,sha256=AvgXFt8c1Cg4icKh0Hbhhz8UmVQ2Wjyfdfkeb2C8zck,8855
240
+ ultralytics/utils/autodevice.py,sha256=1wwjkO2tmyR5IAYa6t8G9QJgGrm00niPY4bTbTRH0Uk,8861
241
241
  ultralytics/utils/benchmarks.py,sha256=btsi_B0mfLPfhE8GrsBpi79vl7SRam0YYngNFAsY8Ak,31035
242
242
  ultralytics/utils/checks.py,sha256=q64U5wKyejD-2W2fCPqJ0Oiaa4_4vq2pVxV9wp6lMz4,34707
243
243
  ultralytics/utils/dist.py,sha256=A9lDGtGefTjSVvVS38w86GOdbtLzNBDZuDGK0MT4PRI,4170
244
- ultralytics/utils/downloads.py,sha256=A7r4LpWUojGkam9-VQ3Ylu-Cn1lAUGKyJE6VzwQbp7M,22016
244
+ ultralytics/utils/downloads.py,sha256=5p9X5XN3I4RzZYGv8wP8Iehm3fDR4KXtN7KgGsJ0iAg,22621
245
245
  ultralytics/utils/errors.py,sha256=XT9Ru7ivoBgofK6PlnyigGoa7Fmf5nEhyHtnD-8TRXI,1584
246
246
  ultralytics/utils/export.py,sha256=LK-wlTlyb_zIKtSvOmfmvR70RcUU9Ct9UBDt5wn9_rY,9880
247
247
  ultralytics/utils/files.py,sha256=ZCbLGleiF0f-PqYfaxMFAWop88w7U1hpreHXl8b2ko0,8238
248
248
  ultralytics/utils/instance.py,sha256=dC83rHvQXciAED3rOiScFs3BOX9OI06Ey1mj9sjUKvs,19070
249
- ultralytics/utils/logger.py,sha256=wt1IWdfJGa6nZDLj54UBlupRJvcHW3QnkN7017avXf8,15142
249
+ ultralytics/utils/logger.py,sha256=KDHLdpBe3su3OkMpLSUgDk3-cXMkRgH3oK0hhxsxxvM,15137
250
250
  ultralytics/utils/loss.py,sha256=fbOWc3Iu0QOJiWbi-mXWA9-1otTYlehtmUsI7os7ydM,39799
251
251
  ultralytics/utils/metrics.py,sha256=Q0cD4J1_7WRElv_En6YUM94l4SjE7XTF9LdZUMvrGys,68853
252
252
  ultralytics/utils/ops.py,sha256=8d60fbpntrexK3gPoLUS6mWAYGrtrQaQCOYyRJsCjuI,34521
@@ -254,6 +254,7 @@ ultralytics/utils/patches.py,sha256=PPWiKzwGbCvuawLzDKVR8tWOQAlZbJBi8g_-A6eTCYA,
254
254
  ultralytics/utils/plotting.py,sha256=4TG_J8rz9VVPrOXbdjRHPJZVgJrFYVmEYE0BcVDdolc,47745
255
255
  ultralytics/utils/tal.py,sha256=aXawOnhn8ni65tJWIW-PYqWr_TRvltbHBjrTo7o6lDQ,20924
256
256
  ultralytics/utils/torch_utils.py,sha256=D76Pvmw5OKh-vd4aJkOMO0dSLbM5WzGr7Hmds54hPEk,39233
257
+ ultralytics/utils/tqdm.py,sha256=cJSzlv6NP72kN7_J0PETA3h4bwGh5a_YHA2gdmZqL8U,16535
257
258
  ultralytics/utils/triton.py,sha256=M7qe4RztiADBJQEWQKaIQsp94ERFJ_8_DUHDR6TXEOM,5410
258
259
  ultralytics/utils/tuner.py,sha256=bHr09Fz-0-t0ei55gX5wJh-obyiAQoicP7HUVM2I8qA,6826
259
260
  ultralytics/utils/callbacks/__init__.py,sha256=hzL63Rce6VkZhP4Lcim9LKjadixaQG86nKqPhk7IkS0,242
@@ -268,9 +269,9 @@ ultralytics/utils/callbacks/platform.py,sha256=gdbEuedXEs1VjdU0IiedjPFwttZJUiI0d
268
269
  ultralytics/utils/callbacks/raytune.py,sha256=S6Bq16oQDQ8BQgnZzA0zJHGN_BBr8iAM_WtGoLiEcwg,1283
269
270
  ultralytics/utils/callbacks/tensorboard.py,sha256=MDPBW7aDes-66OE6YqKXXvqA_EocjzEMHWGM-8z9vUQ,5281
270
271
  ultralytics/utils/callbacks/wb.py,sha256=Tm_-aRr2CN32MJkY9tylpMBJkb007-MSRNSQ7rDJ5QU,7521
271
- ultralytics-8.3.184.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
272
- ultralytics-8.3.184.dist-info/METADATA,sha256=8Qds5WM9GWM3yyv-mcPLsOexKaOS0zGzoySANdGAETM,37631
273
- ultralytics-8.3.184.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
274
- ultralytics-8.3.184.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
275
- ultralytics-8.3.184.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
276
- ultralytics-8.3.184.dist-info/RECORD,,
272
+ ultralytics-8.3.186.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
273
+ ultralytics-8.3.186.dist-info/METADATA,sha256=C2K13z0W5TI4cQ4-q0r9c-8tHrXHF3RFQDal4_4df7A,37627
274
+ ultralytics-8.3.186.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
275
+ ultralytics-8.3.186.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
276
+ ultralytics-8.3.186.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
277
+ ultralytics-8.3.186.dist-info/RECORD,,