mirror of
https://github.com/THU-MIG/yolov10.git
synced 2025-05-23 05:24:22 +08:00
ultralytics 8.0.182
remove deprecated pkg_resources
(#4979)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
0cf82f5040
commit
28569ced8a
27
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
27
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -25,13 +25,14 @@ body:
|
|||||||
Please select the part of YOLOv8 where you found the bug.
|
Please select the part of YOLOv8 where you found the bug.
|
||||||
multiple: true
|
multiple: true
|
||||||
options:
|
options:
|
||||||
- "Training"
|
- "Install"
|
||||||
- "Validation"
|
- "Train"
|
||||||
- "Detection"
|
- "Val"
|
||||||
|
- "Predict"
|
||||||
- "Export"
|
- "Export"
|
||||||
- "PyTorch Hub"
|
|
||||||
- "Multi-GPU"
|
- "Multi-GPU"
|
||||||
- "Evolution"
|
- "Augmentation"
|
||||||
|
- "Hyperparameter Tuning"
|
||||||
- "Integrations"
|
- "Integrations"
|
||||||
- "Other"
|
- "Other"
|
||||||
validations:
|
validations:
|
||||||
@ -51,9 +52,19 @@ body:
|
|||||||
label: Environment
|
label: Environment
|
||||||
description: Please specify the software and hardware you used to produce the bug.
|
description: Please specify the software and hardware you used to produce the bug.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
- YOLO: Ultralytics YOLOv8.0.21 🚀 Python-3.8.10 torch-1.13.1+cu117 CUDA:0 (A100-SXM-80GB, 81251MiB)
|
Paste output of `yolo checks` or `ultralytics.checks()` commands:
|
||||||
- OS: Ubuntu 20.04
|
```
|
||||||
- Python: 3.8.10
|
Ultralytics YOLOv8.0.181 🚀 Python-3.11.2 torch-2.0.1 CPU (Apple M2)
|
||||||
|
Setup complete ✅ (8 CPUs, 16.0 GB RAM, 266.5/460.4 GB disk)
|
||||||
|
|
||||||
|
OS macOS-13.5.2
|
||||||
|
Environment Jupyter
|
||||||
|
Python 3.11.2
|
||||||
|
Install git
|
||||||
|
RAM 16.00 GB
|
||||||
|
CPU Apple M2
|
||||||
|
CUDA None
|
||||||
|
```
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ FROM ultralytics/ultralytics:latest
|
|||||||
WORKDIR /actions-runner
|
WORKDIR /actions-runner
|
||||||
|
|
||||||
# Download and unpack the latest runner from https://github.com/actions/runner
|
# Download and unpack the latest runner from https://github.com/actions/runner
|
||||||
RUN FILENAME=actions-runner-linux-x64-2.308.0.tar.gz && \
|
RUN FILENAME=actions-runner-linux-x64-2.309.0.tar.gz && \
|
||||||
curl -o $FILENAME -L https://github.com/actions/runner/releases/download/v2.308.0/$FILENAME && \
|
curl -o $FILENAME -L https://github.com/actions/runner/releases/download/v2.309.0/$FILENAME && \
|
||||||
tar xzf $FILENAME && \
|
tar xzf $FILENAME && \
|
||||||
rm $FILENAME
|
rm $FILENAME
|
||||||
|
|
||||||
|
@ -9,6 +9,14 @@ keywords: Ultralytics, utility checks, ASCII, check_version, pip_update, check_p
|
|||||||
|
|
||||||
Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/checks.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/checks.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏!
|
Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/checks.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/checks.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏!
|
||||||
|
|
||||||
|
---
|
||||||
|
## ::: ultralytics.utils.checks.parse_requirements
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
---
|
||||||
|
## ::: ultralytics.utils.checks.parse_version
|
||||||
|
<br><br>
|
||||||
|
|
||||||
---
|
---
|
||||||
## ::: ultralytics.utils.checks.is_ascii
|
## ::: ultralytics.utils.checks.is_ascii
|
||||||
<br><br>
|
<br><br>
|
||||||
@ -69,6 +77,10 @@ keywords: Ultralytics, utility checks, ASCII, check_version, pip_update, check_p
|
|||||||
## ::: ultralytics.utils.checks.check_yolo
|
## ::: ultralytics.utils.checks.check_yolo
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
|
---
|
||||||
|
## ::: ultralytics.utils.checks.collect_system_info
|
||||||
|
<br><br>
|
||||||
|
|
||||||
---
|
---
|
||||||
## ::: ultralytics.utils.checks.check_amp
|
## ::: ultralytics.utils.checks.check_amp
|
||||||
<br><br>
|
<br><br>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
||||||
|
|
||||||
__version__ = '8.0.181'
|
__version__ = '8.0.182'
|
||||||
|
|
||||||
from ultralytics.models import RTDETR, SAM, YOLO
|
from ultralytics.models import RTDETR, SAM, YOLO
|
||||||
from ultralytics.models.fastsam import FastSAM
|
from ultralytics.models.fastsam import FastSAM
|
||||||
|
@ -333,7 +333,7 @@ def entrypoint(debug=''):
|
|||||||
|
|
||||||
special = {
|
special = {
|
||||||
'help': lambda: LOGGER.info(CLI_HELP_MSG),
|
'help': lambda: LOGGER.info(CLI_HELP_MSG),
|
||||||
'checks': checks.check_yolo,
|
'checks': checks.collect_system_info,
|
||||||
'version': lambda: LOGGER.info(__version__),
|
'version': lambda: LOGGER.info(__version__),
|
||||||
'settings': lambda: handle_yolo_settings(args[1:]),
|
'settings': lambda: handle_yolo_settings(args[1:]),
|
||||||
'cfg': lambda: yaml_print(DEFAULT_CFG_PATH),
|
'cfg': lambda: yaml_print(DEFAULT_CFG_PATH),
|
||||||
|
@ -143,6 +143,9 @@ class Exporter:
|
|||||||
_callbacks (list, optional): List of callback functions. Defaults to None.
|
_callbacks (list, optional): List of callback functions. Defaults to None.
|
||||||
"""
|
"""
|
||||||
self.args = get_cfg(cfg, overrides)
|
self.args = get_cfg(cfg, overrides)
|
||||||
|
if self.args.format.lower() in ('coreml', 'mlmodel'): # fix attempt for protobuf<3.20.x errors
|
||||||
|
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python' # must run before TensorBoard callback
|
||||||
|
|
||||||
self.callbacks = _callbacks or callbacks.get_default_callbacks()
|
self.callbacks = _callbacks or callbacks.get_default_callbacks()
|
||||||
callbacks.add_integration_callbacks(self)
|
callbacks.add_integration_callbacks(self)
|
||||||
|
|
||||||
@ -155,7 +158,6 @@ class Exporter:
|
|||||||
if format in ('tensorrt', 'trt'): # 'engine' aliases
|
if format in ('tensorrt', 'trt'): # 'engine' aliases
|
||||||
format = 'engine'
|
format = 'engine'
|
||||||
if format in ('mlmodel', 'mlpackage', 'mlprogram', 'apple', 'ios', 'coreml'): # 'coreml' aliases
|
if format in ('mlmodel', 'mlpackage', 'mlprogram', 'apple', 'ios', 'coreml'): # 'coreml' aliases
|
||||||
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python' # fix attempt for protobuf<3.20.x errors
|
|
||||||
format = 'coreml'
|
format = 'coreml'
|
||||||
fmts = tuple(export_formats()['Argument'][1:]) # available export formats
|
fmts = tuple(export_formats()['Argument'][1:]) # available export formats
|
||||||
flags = [x == format for x in fmts]
|
flags = [x == format for x in fmts]
|
||||||
|
@ -143,7 +143,7 @@ class FastSAMPrompt:
|
|||||||
|
|
||||||
save_path = Path(output) / result_name
|
save_path = Path(output) / result_name
|
||||||
save_path.parent.mkdir(exist_ok=True, parents=True)
|
save_path.parent.mkdir(exist_ok=True, parents=True)
|
||||||
image = Image.frombytes('RGB', fig.canvas.get_width_height(), fig.canvas.tostring_rgb())
|
image = Image.frombytes('RGB', fig.canvas.get_width_height(), fig.canvas.buffer_rgba())
|
||||||
image.save(save_path)
|
image.save(save_path)
|
||||||
plt.close()
|
plt.close()
|
||||||
pbar.set_description(f'Saving {result_name} to {save_path}')
|
pbar.set_description(f'Saving {result_name} to {save_path}')
|
||||||
|
@ -213,11 +213,6 @@ def add_integration_callbacks(instance):
|
|||||||
from .wb import callbacks as wb_cb
|
from .wb import callbacks as wb_cb
|
||||||
callbacks_list.extend([clear_cb, comet_cb, dvc_cb, mlflow_cb, neptune_cb, tune_cb, tb_cb, wb_cb])
|
callbacks_list.extend([clear_cb, comet_cb, dvc_cb, mlflow_cb, neptune_cb, tune_cb, tb_cb, wb_cb])
|
||||||
|
|
||||||
# Load export callbacks (patch to avoid CoreML protobuf error)
|
|
||||||
if 'Exporter' in instance.__class__.__name__:
|
|
||||||
from .tensorboard import callbacks as tb_cb
|
|
||||||
callbacks_list.append(tb_cb)
|
|
||||||
|
|
||||||
# Add the callbacks to the callbacks dictionary
|
# Add the callbacks to the callbacks dictionary
|
||||||
for callbacks in callbacks_list:
|
for callbacks in callbacks_list:
|
||||||
for k, v in callbacks.items():
|
for k, v in callbacks.items():
|
||||||
|
@ -9,20 +9,60 @@ import platform
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from importlib.metadata import PackageNotFoundError, version
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pkg_resources as pkg
|
|
||||||
import requests
|
import requests
|
||||||
import torch
|
import torch
|
||||||
from matplotlib import font_manager
|
from matplotlib import font_manager
|
||||||
|
|
||||||
from ultralytics.utils import (ASSETS, AUTOINSTALL, LINUX, LOGGER, ONLINE, ROOT, USER_CONFIG_DIR, ThreadingLocked,
|
from ultralytics.utils import (ASSETS, AUTOINSTALL, LINUX, LOGGER, ONLINE, ROOT, USER_CONFIG_DIR, SimpleNamespace,
|
||||||
TryExcept, clean_url, colorstr, downloads, emojis, is_colab, is_docker, is_jupyter,
|
ThreadingLocked, TryExcept, clean_url, colorstr, downloads, emojis, is_colab, is_docker,
|
||||||
is_kaggle, is_online, is_pip_package, url2file)
|
is_jupyter, is_kaggle, is_online, is_pip_package, url2file)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_requirements(file_path=ROOT.parent / 'requirements.txt'):
|
||||||
|
"""
|
||||||
|
Parse a requirements.txt file, ignoring lines that start with '#' and any text after '#'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path (Path): Path to the requirements.txt file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(List[Dict[str, str]]): List of parsed requirements as dictionaries with `name` and `specifier` keys.
|
||||||
|
"""
|
||||||
|
|
||||||
|
requirements = []
|
||||||
|
for line in Path(file_path).read_text().splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('#'):
|
||||||
|
line = line.split('#')[0].strip() # ignore inline comments
|
||||||
|
match = re.match(r'([a-zA-Z0-9-_]+)([<>!=~]+.*)?', line)
|
||||||
|
if match:
|
||||||
|
requirements.append(SimpleNamespace(name=match[1], specifier=match[2].strip() if match[2] else ''))
|
||||||
|
|
||||||
|
return requirements
|
||||||
|
|
||||||
|
|
||||||
|
def parse_version(v='0.0.0') -> tuple:
|
||||||
|
"""
|
||||||
|
Convert a version string to a tuple of integers, also returning any extra non-numeric string attached to the version.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
v (str): Version string, i.e. '2.0.1+cpu'
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(tuple): Tuple of integers representing the numeric part of the version and the extra string, i.e. (2, 0, 1)
|
||||||
|
"""
|
||||||
|
correct = [True if x == '.' else x.isdigit() for x in v] # first non-number index
|
||||||
|
if False in correct:
|
||||||
|
v = v[:correct.index(False)]
|
||||||
|
return tuple(map(int, v.split('.'))) # '2.0.1+cpu' -> (2, 0, 1)
|
||||||
|
|
||||||
|
|
||||||
def is_ascii(s) -> bool:
|
def is_ascii(s) -> bool:
|
||||||
@ -121,24 +161,33 @@ def check_version(current: str = '0.0.0',
|
|||||||
# check if current version is between 20.04 (inclusive) and 22.04 (exclusive)
|
# check if current version is between 20.04 (inclusive) and 22.04 (exclusive)
|
||||||
check_version(current='21.10', required='>20.04,<22.04')
|
check_version(current='21.10', required='>20.04,<22.04')
|
||||||
"""
|
"""
|
||||||
current = pkg.parse_version(current)
|
if not required:
|
||||||
|
return True # in case required is '' or None
|
||||||
|
|
||||||
|
# import pkg_resources as pkg
|
||||||
|
# current = pkg.parse_version(current)
|
||||||
|
current = parse_version(current) # '1.2.3' -> (1, 2, 3)
|
||||||
|
|
||||||
constraints = re.findall(r'([<>!=]{1,2}\s*\d+\.\d+)', required) or [f'>={required}']
|
constraints = re.findall(r'([<>!=]{1,2}\s*\d+\.\d+)', required) or [f'>={required}']
|
||||||
|
|
||||||
result = True
|
result = True
|
||||||
for constraint in constraints:
|
for constraint in constraints:
|
||||||
op, version = re.match(r'([<>!=]{1,2})\s*(\d+\.\d+)', constraint).groups()
|
op, v = re.match(r'([<>!=]{1,2})\s*(\d+\.\d+)', constraint).groups()
|
||||||
version = pkg.parse_version(version)
|
|
||||||
if op == '==' and current != version:
|
# v = pkg.parse_version(v)
|
||||||
|
v = parse_version(v) # '1.2.3' -> (1, 2, 3)
|
||||||
|
|
||||||
|
if op == '==' and current != v:
|
||||||
result = False
|
result = False
|
||||||
elif op == '!=' and current == version:
|
elif op == '!=' and current == v:
|
||||||
result = False
|
result = False
|
||||||
elif op == '>=' and not (current >= version):
|
elif op == '>=' and not (current >= v):
|
||||||
result = False
|
result = False
|
||||||
elif op == '<=' and not (current <= version):
|
elif op == '<=' and not (current <= v):
|
||||||
result = False
|
result = False
|
||||||
elif op == '>' and not (current > version):
|
elif op == '>' and not (current > v):
|
||||||
result = False
|
result = False
|
||||||
elif op == '<' and not (current < version):
|
elif op == '<' and not (current < v):
|
||||||
result = False
|
result = False
|
||||||
if not result:
|
if not result:
|
||||||
warning_message = f'WARNING ⚠️ {name}{op}{required} is required, but {name}=={current} is currently installed'
|
warning_message = f'WARNING ⚠️ {name}{op}{required} is required, but {name}=={current} is currently installed'
|
||||||
@ -177,7 +226,7 @@ def check_pip_update_available():
|
|||||||
with contextlib.suppress(Exception):
|
with contextlib.suppress(Exception):
|
||||||
from ultralytics import __version__
|
from ultralytics import __version__
|
||||||
latest = check_latest_pypi_version()
|
latest = check_latest_pypi_version()
|
||||||
if pkg.parse_version(__version__) < pkg.parse_version(latest): # update is available
|
if check_version(__version__, f'<{latest}'): # check if current version is < latest version
|
||||||
LOGGER.info(f'New https://pypi.org/project/ultralytics/{latest} available 😃 '
|
LOGGER.info(f'New https://pypi.org/project/ultralytics/{latest} available 😃 '
|
||||||
f"Update with 'pip install -U ultralytics'")
|
f"Update with 'pip install -U ultralytics'")
|
||||||
return True
|
return True
|
||||||
@ -253,29 +302,25 @@ def check_requirements(requirements=ROOT.parent / 'requirements.txt', exclude=()
|
|||||||
check_requirements(['numpy', 'ultralytics>=8.0.0'])
|
check_requirements(['numpy', 'ultralytics>=8.0.0'])
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
prefix = colorstr('red', 'bold', 'requirements:')
|
prefix = colorstr('red', 'bold', 'requirements:')
|
||||||
check_python() # check python version
|
check_python() # check python version
|
||||||
check_torchvision() # check torch-torchvision compatibility
|
check_torchvision() # check torch-torchvision compatibility
|
||||||
if isinstance(requirements, Path): # requirements.txt file
|
if isinstance(requirements, Path): # requirements.txt file
|
||||||
file = requirements.resolve()
|
file = requirements.resolve()
|
||||||
assert file.exists(), f'{prefix} {file} not found, check failed.'
|
assert file.exists(), f'{prefix} {file} not found, check failed.'
|
||||||
with file.open() as f:
|
requirements = [f'{x.name}{x.specifier}' for x in parse_requirements(file) if x.name not in exclude]
|
||||||
requirements = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements(f) if x.name not in exclude]
|
|
||||||
elif isinstance(requirements, str):
|
elif isinstance(requirements, str):
|
||||||
requirements = [requirements]
|
requirements = [requirements]
|
||||||
|
|
||||||
pkgs = []
|
pkgs = []
|
||||||
for r in requirements:
|
for r in requirements:
|
||||||
r_stripped = r.split('/')[-1].replace('.git', '') # replace git+https://org/repo.git -> 'repo'
|
r_stripped = r.split('/')[-1].replace('.git', '') # replace git+https://org/repo.git -> 'repo'
|
||||||
|
match = re.match(r'([a-zA-Z0-9-_]+)([<>!=~]+.*)?', r_stripped)
|
||||||
|
name, required = match[1], match[2].strip() if match[2] else ''
|
||||||
try:
|
try:
|
||||||
pkg.require(r_stripped) # exception if requirements not met
|
assert check_version(version(name), required) # exception if requirements not met
|
||||||
except pkg.DistributionNotFound:
|
except (AssertionError, PackageNotFoundError):
|
||||||
try: # attempt to import (slower but more accurate)
|
|
||||||
import importlib
|
|
||||||
importlib.import_module(next(pkg.parse_requirements(r_stripped)).name)
|
|
||||||
except ImportError:
|
|
||||||
pkgs.append(r)
|
|
||||||
except pkg.VersionConflict:
|
|
||||||
pkgs.append(r)
|
pkgs.append(r)
|
||||||
|
|
||||||
s = ' '.join(f'"{x}"' for x in pkgs) # console string
|
s = ' '.join(f'"{x}"' for x in pkgs) # console string
|
||||||
@ -430,6 +475,30 @@ def check_yolo(verbose=True, device=''):
|
|||||||
LOGGER.info(f'Setup complete ✅ {s}')
|
LOGGER.info(f'Setup complete ✅ {s}')
|
||||||
|
|
||||||
|
|
||||||
|
def collect_system_info():
|
||||||
|
"""Collect and print relevant system information including OS, Python, RAM, CPU, and CUDA."""
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
from ultralytics.utils import ENVIRONMENT, is_git_dir
|
||||||
|
from ultralytics.utils.torch_utils import get_cpu_info
|
||||||
|
|
||||||
|
ram_info = psutil.virtual_memory().total / (1024 ** 3) # Convert bytes to GB
|
||||||
|
check_yolo()
|
||||||
|
LOGGER.info(f"\n{'OS':<20}{platform.platform()}\n"
|
||||||
|
f"{'Environment':<20}{ENVIRONMENT}\n"
|
||||||
|
f"{'Python':<20}{sys.version.split()[0]}\n"
|
||||||
|
f"{'Install':<20}{'git' if is_git_dir() else 'pip' if is_pip_package() else 'other'}\n"
|
||||||
|
f"{'RAM':<20}{ram_info:.2f} GB\n"
|
||||||
|
f"{'CPU':<20}{get_cpu_info()}\n"
|
||||||
|
f"{'CUDA':<20}{torch.version.cuda if torch and torch.cuda.is_available() else None}\n")
|
||||||
|
|
||||||
|
for r in parse_requirements():
|
||||||
|
current = version(r.name)
|
||||||
|
is_met = '✅ ' if check_version(current, r.specifier) else '❌ '
|
||||||
|
LOGGER.info(f'{r.name:<20}{is_met}{current}{r.specifier}')
|
||||||
|
|
||||||
|
|
||||||
def check_amp(model):
|
def check_amp(model):
|
||||||
"""
|
"""
|
||||||
This function checks the PyTorch Automatic Mixed Precision (AMP) functionality of a YOLOv8 model.
|
This function checks the PyTorch Automatic Mixed Precision (AMP) functionality of a YOLOv8 model.
|
||||||
|
@ -76,11 +76,11 @@ def select_device(device='', batch=0, newline=False, verbose=True):
|
|||||||
verbose (bool, optional): If True, logs the device information. Defaults to True.
|
verbose (bool, optional): If True, logs the device information. Defaults to True.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
torch.device: Selected device.
|
(torch.device): Selected device.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the specified device is not available or if the batch size is not a multiple of the number of
|
ValueError: If the specified device is not available or if the batch size is not a multiple of the number of
|
||||||
devices when using multiple GPUs.
|
devices when using multiple GPUs.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> select_device('cuda:0')
|
>>> select_device('cuda:0')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user