DDP, Comet, URLError fixes, improved error handling (#658)
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tungway1990 <68179274+Tungway1990@users.noreply.github.com>
This commit is contained in:
@ -6,7 +6,7 @@ try:
|
||||
import clearml
|
||||
from clearml import Task
|
||||
|
||||
assert hasattr(clearml, '__version__')
|
||||
assert clearml.__version__ # verify package is not directory
|
||||
except (ImportError, AssertionError):
|
||||
clearml = None
|
||||
|
||||
|
@ -5,7 +5,7 @@ from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params
|
||||
try:
|
||||
import comet_ml
|
||||
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
except ImportError:
|
||||
comet_ml = None
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ def on_fit_epoch_end(trainer):
|
||||
|
||||
def on_train_end(trainer):
|
||||
experiment = comet_ml.get_global_experiment()
|
||||
experiment.log_model("YOLOv8", file_or_folder=trainer.best, file_name="best.pt", overwrite=True)
|
||||
experiment.log_model("YOLOv8", file_or_folder=str(trainer.best), file_name="best.pt", overwrite=True)
|
||||
|
||||
|
||||
callbacks = {
|
||||
|
@ -18,8 +18,8 @@ import psutil
|
||||
import torch
|
||||
from IPython import display
|
||||
|
||||
from ultralytics.yolo.utils import (AUTOINSTALL, FONT, LOGGER, ROOT, USER_CONFIG_DIR, TryExcept, colorstr, emojis,
|
||||
is_colab, is_docker, is_jupyter)
|
||||
from ultralytics.yolo.utils import (AUTOINSTALL, FONT, LOGGER, ROOT, USER_CONFIG_DIR, TryExcept, colorstr, downloads,
|
||||
emojis, is_colab, is_docker, is_jupyter)
|
||||
|
||||
|
||||
def is_ascii(s) -> bool:
|
||||
@ -123,9 +123,7 @@ def check_font(font: str = FONT, progress: bool = False) -> None:
|
||||
# Check if font file exists at the source or destination path
|
||||
if not font.exists() and not file.exists():
|
||||
# Download font file
|
||||
url = f'https://ultralytics.com/assets/{font.name}'
|
||||
LOGGER.info(f'Downloading {url} to {file}...')
|
||||
torch.hub.download_url_to_file(url, str(file), progress=progress)
|
||||
downloads.safe_download(file=file, url=f'https://ultralytics.com/assets/{font.name}', progress=progress)
|
||||
|
||||
|
||||
def check_online() -> bool:
|
||||
@ -215,9 +213,7 @@ def check_file(file, suffix=''):
|
||||
if Path(file).is_file():
|
||||
LOGGER.info(f'Found {url} locally at {file}') # file already exists
|
||||
else:
|
||||
LOGGER.info(f'Downloading {url} to {file}...')
|
||||
torch.hub.download_url_to_file(url, file)
|
||||
assert Path(file).exists() and Path(file).stat().st_size > 0, f'File download failed: {url}' # check
|
||||
downloads.safe_download(file=file, url=url)
|
||||
return file
|
||||
else: # search
|
||||
files = []
|
||||
|
@ -12,16 +12,16 @@ from zipfile import ZipFile
|
||||
import requests
|
||||
import torch
|
||||
|
||||
from ultralytics.yolo.utils import LOGGER, SETTINGS
|
||||
from ultralytics.yolo.utils import LOGGER
|
||||
|
||||
|
||||
def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''):
|
||||
def safe_download(file, url, url2=None, min_bytes=1E0, error_msg='', progress=True):
|
||||
# Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes
|
||||
file = Path(file)
|
||||
assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}"
|
||||
try: # url1
|
||||
LOGGER.info(f'Downloading {url} to {file}...')
|
||||
torch.hub.download_url_to_file(url, str(file), progress=LOGGER.level <= logging.INFO)
|
||||
torch.hub.download_url_to_file(url, str(file), progress=progress and LOGGER.level <= logging.INFO)
|
||||
assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check
|
||||
except Exception as e: # url2
|
||||
if file.exists():
|
||||
@ -32,7 +32,7 @@ def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''):
|
||||
if not file.exists() or file.stat().st_size < min_bytes: # check
|
||||
if file.exists():
|
||||
file.unlink() # remove partial downloads
|
||||
LOGGER.info(f"ERROR: {assert_msg}\n{error_msg}")
|
||||
LOGGER.warning(f"ERROR: {assert_msg}\n{error_msg}")
|
||||
LOGGER.info('')
|
||||
|
||||
|
||||
@ -49,6 +49,7 @@ def is_url(url, check=True):
|
||||
|
||||
def attempt_download(file, repo='ultralytics/assets', release='v0.0.0'):
|
||||
# Attempt file download from GitHub release assets if not found locally. release = 'latest', 'v6.2', etc.
|
||||
from ultralytics.yolo.utils import SETTINGS
|
||||
|
||||
def github_assets(repository, version='latest'):
|
||||
# Return GitHub repo tag and assets (i.e. ['yolov8n.pt', 'yolov5m.pt', ...])
|
||||
@ -76,7 +77,6 @@ def attempt_download(file, repo='ultralytics/assets', release='v0.0.0'):
|
||||
return file
|
||||
|
||||
# GitHub assets
|
||||
assets = [f'yolov5{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default
|
||||
assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default
|
||||
try:
|
||||
tag, assets = github_assets(repo, release)
|
||||
@ -110,13 +110,12 @@ def download(url, dir=Path.cwd(), unzip=True, delete=True, curl=False, threads=1
|
||||
f = dir / Path(url).name
|
||||
LOGGER.info(f'Downloading {url} to {f}...')
|
||||
for i in range(retry + 1):
|
||||
if curl:
|
||||
s = 'sS' if threads > 1 else '' # silent
|
||||
r = os.system(
|
||||
f'curl -# -{s}L "{url}" -o "{f}" --retry 9 -C -') # curl download with retry, continue
|
||||
if curl: # curl download with retry, continue
|
||||
s = 'sS' * (threads > 1) # silent
|
||||
r = os.system(f'curl -# -{s}L "{url}" -o "{f}" --retry 9 -C -')
|
||||
success = r == 0
|
||||
else:
|
||||
torch.hub.download_url_to_file(url, f, progress=threads == 1) # torch download
|
||||
else: # torch download
|
||||
torch.hub.download_url_to_file(url, f, progress=threads == 1)
|
||||
success = f.is_file()
|
||||
if success:
|
||||
break
|
||||
|
@ -67,9 +67,19 @@ def select_device(device='', batch=0, newline=False):
|
||||
if cpu or mps:
|
||||
os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False
|
||||
elif device: # non-cpu device requested
|
||||
visible = os.environ.get('CUDA_VISIBLE_DEVICES', None)
|
||||
os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - must be before assert is_available()
|
||||
if not (torch.cuda.is_available() and torch.cuda.device_count() >= len(device.replace(',', ''))):
|
||||
raise ValueError(f"Invalid CUDA 'device={device}' requested, use 'device=cpu' or pass valid CUDA device(s)")
|
||||
LOGGER.info(s)
|
||||
install = "See https://pytorch.org/get-started/locally/ for up-to-date torch install instructions if no " \
|
||||
"CUDA devices are seen by torch.\n" if torch.cuda.device_count() == 0 else ""
|
||||
raise ValueError(f"Invalid CUDA 'device={device}' requested."
|
||||
f" Use 'device=cpu' or pass valid CUDA device(s) if available,"
|
||||
f" i.e. 'device=0' or 'device=0,1,2,3' for Multi-GPU.\n"
|
||||
f"\ntorch.cuda.is_available(): {torch.cuda.is_available()}"
|
||||
f"\ntorch.cuda.device_count(): {torch.cuda.device_count()}"
|
||||
f"\nos.environ['CUDA_VISIBLE_DEVICES']: {visible}\n"
|
||||
f"{install}")
|
||||
|
||||
if not cpu and not mps and torch.cuda.is_available(): # prefer GPU if available
|
||||
devices = device.split(',') if device else '0' # range(torch.cuda.device_count()) # i.e. 0,1,6,7
|
||||
|
Reference in New Issue
Block a user