ultralytics 8.0.140__py3-none-any.whl → 8.0.141__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.

Potentially problematic release.


This version of ultralytics might be problematic. Click here for more details.

ultralytics/__init__.py CHANGED
@@ -1,13 +1,14 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- __version__ = '8.0.140'
3
+ __version__ = '8.0.141'
4
4
 
5
5
  from ultralytics.engine.model import YOLO
6
6
  from ultralytics.hub import start
7
7
  from ultralytics.models import RTDETR, SAM
8
8
  from ultralytics.models.fastsam import FastSAM
9
9
  from ultralytics.models.nas import NAS
10
+ from ultralytics.utils import SETTINGS as settings
10
11
  from ultralytics.utils.checks import check_yolo as checks
11
12
  from ultralytics.utils.downloads import download
12
13
 
13
- __all__ = '__version__', 'YOLO', 'NAS', 'SAM', 'FastSAM', 'RTDETR', 'checks', 'download', 'start' # allow simpler import
14
+ __all__ = '__version__', 'YOLO', 'NAS', 'SAM', 'FastSAM', 'RTDETR', 'checks', 'download', 'start', 'settings' # allow simpler import
@@ -9,9 +9,9 @@ from pathlib import Path
9
9
  from types import SimpleNamespace
10
10
  from typing import Dict, List, Union
11
11
 
12
- from ultralytics.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, ROOT, USER_CONFIG_DIR,
13
- IterableSimpleNamespace, __version__, checks, colorstr, deprecation_warn, get_settings,
14
- yaml_load, yaml_print)
12
+ from ultralytics.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, ROOT, SETTINGS, SETTINGS_YAML,
13
+ IterableSimpleNamespace, __version__, checks, colorstr, deprecation_warn, yaml_load,
14
+ yaml_print)
15
15
 
16
16
  # Define valid tasks and modes
17
17
  MODES = 'train', 'val', 'predict', 'export', 'track', 'benchmark'
@@ -28,7 +28,6 @@ TASK2METRIC = {
28
28
  'classify': 'metrics/accuracy_top1',
29
29
  'pose': 'metrics/mAP50-95(P)'}
30
30
 
31
-
32
31
  CLI_HELP_MSG = \
33
32
  f"""
34
33
  Arguments received: {str(['yolo'] + sys.argv[1:])}. Ultralytics 'yolo' commands use the following syntax:
@@ -111,7 +110,7 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, ove
111
110
  # Merge overrides
112
111
  if overrides:
113
112
  overrides = cfg2dict(overrides)
114
- check_cfg_mismatch(cfg, overrides)
113
+ check_dict_alignment(cfg, overrides)
115
114
  cfg = {**cfg, **overrides} # merge cfg and overrides dicts (prefer overrides)
116
115
 
117
116
  # Special handling for numeric project/name
@@ -147,9 +146,7 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, ove
147
146
 
148
147
 
149
148
  def _handle_deprecation(custom):
150
- """
151
- Hardcoded function to handle deprecated config keys
152
- """
149
+ """Hardcoded function to handle deprecated config keys"""
153
150
 
154
151
  for key in custom.copy().keys():
155
152
  if key == 'hide_labels':
@@ -165,7 +162,7 @@ def _handle_deprecation(custom):
165
162
  return custom
166
163
 
167
164
 
168
- def check_cfg_mismatch(base: Dict, custom: Dict, e=None):
165
+ def check_dict_alignment(base: Dict, custom: Dict, e=None):
169
166
  """
170
167
  This function checks for any mismatched keys between a custom configuration list and a base configuration list.
171
168
  If any mismatched keys are found, the function prints out similar keys from the base list and exits the program.
@@ -175,13 +172,13 @@ def check_cfg_mismatch(base: Dict, custom: Dict, e=None):
175
172
  base (dict): a dictionary of base configuration options
176
173
  """
177
174
  custom = _handle_deprecation(custom)
178
- base, custom = (set(x.keys()) for x in (base, custom))
179
- mismatched = [x for x in custom if x not in base]
175
+ base_keys, custom_keys = (set(x.keys()) for x in (base, custom))
176
+ mismatched = [k for k in custom_keys if k not in base_keys]
180
177
  if mismatched:
181
178
  string = ''
182
179
  for x in mismatched:
183
- matches = get_close_matches(x, base) # key list
184
- matches = [f'{k}={DEFAULT_CFG_DICT[k]}' if DEFAULT_CFG_DICT.get(k) is not None else k for k in matches]
180
+ matches = get_close_matches(x, base_keys) # key list
181
+ matches = [f'{k}={base[k]}' if base.get(k) is not None else k for k in matches]
185
182
  match_str = f'Similar arguments are i.e. {matches}.' if matches else ''
186
183
  string += f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}\n"
187
184
  raise SyntaxError(string + CLI_HELP_MSG) from e
@@ -251,12 +248,39 @@ def handle_yolo_settings(args: List[str]) -> None:
251
248
  Example:
252
249
  python my_script.py yolo settings reset
253
250
  """
254
- path = USER_CONFIG_DIR / 'settings.yaml' # get SETTINGS YAML file path
255
- if any(args) and args[0] == 'reset':
256
- path.unlink() # delete the settings file
257
- get_settings() # create new settings
258
- LOGGER.info('Settings reset successfully') # inform the user that settings have been reset
259
- yaml_print(path) # print the current settings
251
+ if any(args):
252
+ if args[0] == 'reset':
253
+ SETTINGS_YAML.unlink() # delete the settings file
254
+ SETTINGS.reset() # create new settings
255
+ LOGGER.info('Settings reset successfully') # inform the user that settings have been reset
256
+ else:
257
+ new = dict(parse_key_value_pair(a) for a in args)
258
+ check_dict_alignment(SETTINGS, new)
259
+ SETTINGS.update(new)
260
+
261
+ yaml_print(SETTINGS_YAML) # print the current settings
262
+
263
+
264
+ def parse_key_value_pair(pair):
265
+ """Parse one 'key=value' pair and return key and value."""
266
+ re.sub(r' *= *', '=', pair) # remove spaces around equals sign
267
+ k, v = pair.split('=', 1) # split on first '=' sign
268
+ assert v, f"missing '{k}' value"
269
+ return k, smart_value(v)
270
+
271
+
272
+ def smart_value(v):
273
+ """Convert a string to an underlying type such as int, float, bool, etc."""
274
+ if v.lower() == 'none':
275
+ return None
276
+ elif v.lower() == 'true':
277
+ return True
278
+ elif v.lower() == 'false':
279
+ return False
280
+ else:
281
+ with contextlib.suppress(Exception):
282
+ return eval(v)
283
+ return v
260
284
 
261
285
 
262
286
  def entrypoint(debug=''):
@@ -305,25 +329,14 @@ def entrypoint(debug=''):
305
329
  a = a[:-1]
306
330
  if '=' in a:
307
331
  try:
308
- re.sub(r' *= *', '=', a) # remove spaces around equals sign
309
- k, v = a.split('=', 1) # split on first '=' sign
310
- assert v, f"missing '{k}' value"
332
+ k, v = parse_key_value_pair(a)
311
333
  if k == 'cfg': # custom.yaml passed
312
334
  LOGGER.info(f'Overriding {DEFAULT_CFG_PATH} with {v}')
313
335
  overrides = {k: val for k, val in yaml_load(checks.check_yaml(v)).items() if k != 'cfg'}
314
336
  else:
315
- if v.lower() == 'none':
316
- v = None
317
- elif v.lower() == 'true':
318
- v = True
319
- elif v.lower() == 'false':
320
- v = False
321
- else:
322
- with contextlib.suppress(Exception):
323
- v = eval(v)
324
337
  overrides[k] = v
325
338
  except (NameError, SyntaxError, ValueError, AssertionError) as e:
326
- check_cfg_mismatch(full_args_dict, {a: ''}, e)
339
+ check_dict_alignment(full_args_dict, {a: ''}, e)
327
340
 
328
341
  elif a in TASKS:
329
342
  overrides['task'] = a
@@ -338,13 +351,13 @@ def entrypoint(debug=''):
338
351
  raise SyntaxError(f"'{colorstr('red', 'bold', a)}' is a valid YOLO argument but is missing an '=' sign "
339
352
  f"to set its value, i.e. try '{a}={DEFAULT_CFG_DICT[a]}'\n{CLI_HELP_MSG}")
340
353
  else:
341
- check_cfg_mismatch(full_args_dict, {a: ''})
354
+ check_dict_alignment(full_args_dict, {a: ''})
342
355
 
343
356
  # Check keys
344
- check_cfg_mismatch(full_args_dict, overrides)
357
+ check_dict_alignment(full_args_dict, overrides)
345
358
 
346
359
  # Mode
347
- mode = overrides.get('mode', None)
360
+ mode = overrides.get('mode')
348
361
  if mode is None:
349
362
  mode = DEFAULT_CFG.mode or 'predict'
350
363
  LOGGER.warning(f"WARNING ⚠️ 'mode' is missing. Valid modes are {MODES}. Using default 'mode={mode}'.")
ultralytics/hub/auth.py CHANGED
@@ -3,7 +3,7 @@
3
3
  import requests
4
4
 
5
5
  from ultralytics.hub.utils import HUB_API_ROOT, PREFIX, request_with_credentials
6
- from ultralytics.utils import LOGGER, SETTINGS, emojis, is_colab, set_settings
6
+ from ultralytics.utils import LOGGER, SETTINGS, emojis, is_colab
7
7
 
8
8
  API_KEY_URL = 'https://hub.ultralytics.com/settings?tab=api+keys'
9
9
 
@@ -45,7 +45,7 @@ class Auth:
45
45
 
46
46
  # Update SETTINGS with the new API key after successful authentication
47
47
  if success:
48
- set_settings({'api_key': self.api_key})
48
+ SETTINGS.update({'api_key': self.api_key})
49
49
  # Log that the new login was successful
50
50
  if verbose:
51
51
  LOGGER.info(f'{PREFIX}New authentication successful ✅')
ultralytics/nn/tasks.py CHANGED
@@ -699,10 +699,12 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
699
699
  args = [ch[f]]
700
700
  elif m is Concat:
701
701
  c2 = sum(ch[x] for x in f)
702
- elif m in (Detect, Segment, Pose, RTDETRDecoder):
702
+ elif m in (Detect, Segment, Pose):
703
703
  args.append([ch[x] for x in f])
704
704
  if m is Segment:
705
705
  args[2] = make_divisible(min(args[2], max_channels) * width, 8)
706
+ elif m is RTDETRDecoder: # special case, channels arg must be passed in index 1
707
+ args.insert(1, [ch[x] for x in f])
706
708
  else:
707
709
  c2 = ch[f]
708
710
 
@@ -713,62 +713,105 @@ def set_sentry():
713
713
  logging.getLogger(logger).setLevel(logging.CRITICAL)
714
714
 
715
715
 
716
- def get_settings(file=SETTINGS_YAML, version='0.0.3'):
716
+ def update_dict_recursive(d, u):
717
717
  """
718
- Loads a global Ultralytics settings YAML file or creates one with default values if it does not exist.
718
+ Recursively updates the dictionary `d` with the key-value pairs from the dictionary `u` without overwriting
719
+ entire sub-dictionaries. Note that function recursion is intended and not a problem, as this allows for updating
720
+ nested dictionaries at any arbitrary depth.
719
721
 
720
722
  Args:
721
- file (Path): Path to the Ultralytics settings YAML file. Defaults to 'settings.yaml' in the USER_CONFIG_DIR.
722
- version (str): Settings version. If min settings version not met, new default settings will be saved.
723
+ d (dict): The dictionary to be updated.
724
+ u (dict): The dictionary to update `d` with.
723
725
 
724
726
  Returns:
725
- (dict): Dictionary of settings key-value pairs.
727
+ (dict): The recursively updated dictionary.
726
728
  """
727
- import hashlib
729
+ for k, v in u.items():
730
+ d[k] = update_dict_recursive(d.get(k, {}), v) if isinstance(v, dict) else v
731
+ return d
728
732
 
729
- from ultralytics.utils.checks import check_version
730
- from ultralytics.utils.torch_utils import torch_distributed_zero_first
731
733
 
732
- git_dir = get_git_dir()
733
- root = git_dir or Path()
734
- datasets_root = (root.parent if git_dir and is_dir_writeable(root.parent) else root).resolve()
735
- defaults = {
736
- 'datasets_dir': str(datasets_root / 'datasets'), # default datasets directory.
737
- 'weights_dir': str(root / 'weights'), # default weights directory.
738
- 'runs_dir': str(root / 'runs'), # default runs directory.
739
- 'uuid': hashlib.sha256(str(uuid.getnode()).encode()).hexdigest(), # SHA-256 anonymized UUID hash
740
- 'sync': True, # sync analytics to help with YOLO development
741
- 'api_key': '', # Ultralytics HUB API key (https://hub.ultralytics.com/)
742
- 'settings_version': version} # Ultralytics settings version
743
-
744
- with torch_distributed_zero_first(RANK):
745
- if not file.exists():
746
- yaml_save(file, defaults)
747
- settings = yaml_load(file)
748
-
749
- # Check that settings keys and types match defaults
750
- correct = \
751
- settings \
752
- and settings.keys() == defaults.keys() \
753
- and all(type(a) == type(b) for a, b in zip(settings.values(), defaults.values())) \
754
- and check_version(settings['settings_version'], version)
755
- if not correct:
756
- LOGGER.warning('WARNING ⚠️ Ultralytics settings reset to defaults. This is normal and may be due to a '
757
- 'recent ultralytics package update, but may have overwritten previous settings. '
758
- f"\nView and update settings with 'yolo settings' or at '{file}'")
759
- settings = defaults # merge **defaults with **settings (prefer **settings)
760
- yaml_save(file, settings) # save updated defaults
761
-
762
- return settings
734
+ class SettingsManager(dict):
735
+ """
736
+ Manages Ultralytics settings stored in a YAML file.
763
737
 
738
+ Args:
739
+ file (str | Path): Path to the Ultralytics settings YAML file. Default is USER_CONFIG_DIR / 'settings.yaml'.
740
+ version (str): Settings version. In case of local version mismatch, new default settings will be saved.
741
+ """
742
+
743
+ def __init__(self, file=SETTINGS_YAML, version='0.0.4'):
744
+ import copy
745
+ import hashlib
746
+
747
+ from ultralytics.utils.checks import check_version
748
+ from ultralytics.utils.torch_utils import torch_distributed_zero_first
749
+
750
+ git_dir = get_git_dir()
751
+ root = git_dir or Path()
752
+ datasets_root = (root.parent if git_dir and is_dir_writeable(root.parent) else root).resolve()
753
+
754
+ self.file = Path(file)
755
+ self.version = version
756
+ self.defaults = {
757
+ 'settings_version': version,
758
+ 'datasets_dir': str(datasets_root / 'datasets'),
759
+ 'weights_dir': str(root / 'weights'),
760
+ 'runs_dir': str(root / 'runs'),
761
+ 'uuid': hashlib.sha256(str(uuid.getnode()).encode()).hexdigest(),
762
+ 'sync': True,
763
+ 'api_key': '',
764
+ 'clearml': True, # integrations
765
+ 'comet': True,
766
+ 'dvc': True,
767
+ 'hub': True,
768
+ 'mlflow': True,
769
+ 'neptune': True,
770
+ 'raytune': True,
771
+ 'tensorboard': True,
772
+ 'wandb': True}
773
+
774
+ super().__init__(copy.deepcopy(self.defaults))
775
+
776
+ with torch_distributed_zero_first(RANK):
777
+ if not self.file.exists():
778
+ self.save()
779
+
780
+ self.load()
781
+ correct_keys = self.keys() == self.defaults.keys()
782
+ correct_types = all(type(a) == type(b) for a, b in zip(self.values(), self.defaults.values()))
783
+ correct_version = check_version(self['settings_version'], self.version)
784
+ if not (correct_keys and correct_types and correct_version):
785
+ LOGGER.warning(
786
+ 'WARNING ⚠️ Ultralytics settings reset to default values. This may be due to a possible problem '
787
+ 'with your settings or a recent ultralytics package update. '
788
+ f"\nView settings with 'yolo settings' or at '{self.file}'"
789
+ "\nUpdate settings with 'yolo settings key=value', i.e. 'yolo settings runs_dir=path/to/dir'.")
790
+ self.reset()
791
+
792
+ def load(self):
793
+ """Loads settings from the YAML file."""
794
+ self.update(yaml_load(self.file))
795
+
796
+ def save(self):
797
+ """Saves the current settings to the YAML file."""
798
+ yaml_save(self.file, dict(self))
799
+
800
+ def update(self, *args, **kwargs):
801
+ """Updates a setting value in the current settings and saves the settings."""
802
+ new = dict(*args, **kwargs)
803
+ if any(isinstance(v, dict) for v in new.values()):
804
+ update_dict_recursive(self, new)
805
+ else:
806
+ # super().update(*args, **kwargs)
807
+ super().update(new)
808
+ self.save()
764
809
 
765
- def set_settings(kwargs, file=SETTINGS_YAML):
766
- """
767
- Function that runs on a first-time ultralytics package installation to set up global settings and create necessary
768
- directories.
769
- """
770
- SETTINGS.update(kwargs)
771
- yaml_save(file, SETTINGS)
810
+ def reset(self):
811
+ """Resets the settings to default and saves them."""
812
+ self.clear()
813
+ self.update(self.defaults)
814
+ self.save()
772
815
 
773
816
 
774
817
  def deprecation_warn(arg, new_arg, version=None):
@@ -794,7 +837,7 @@ def url2file(url):
794
837
 
795
838
  # Check first-install steps
796
839
  PREFIX = colorstr('Ultralytics: ')
797
- SETTINGS = get_settings()
840
+ SETTINGS = SettingsManager() # initialize settings
798
841
  DATASETS_DIR = Path(SETTINGS['datasets_dir']) # global datasets directory
799
842
  ENVIRONMENT = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \
800
843
  'Docker' if is_docker() else platform.system()
@@ -5,7 +5,7 @@ import re
5
5
  import matplotlib.image as mpimg
6
6
  import matplotlib.pyplot as plt
7
7
 
8
- from ultralytics.utils import LOGGER, TESTS_RUNNING
8
+ from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING
9
9
  from ultralytics.utils.torch_utils import model_info_for_loggers
10
10
 
11
11
  try:
@@ -16,6 +16,7 @@ try:
16
16
 
17
17
  assert hasattr(clearml, '__version__') # verify package is not directory
18
18
  assert not TESTS_RUNNING # do not log pytest
19
+ assert SETTINGS['clearml'] is True # verify integration is enabled
19
20
  except (ImportError, AssertionError):
20
21
  clearml = None
21
22
 
@@ -3,7 +3,7 @@
3
3
  import os
4
4
  from pathlib import Path
5
5
 
6
- from ultralytics.utils import LOGGER, RANK, TESTS_RUNNING, ops
6
+ from ultralytics.utils import LOGGER, RANK, SETTINGS, TESTS_RUNNING, ops
7
7
  from ultralytics.utils.torch_utils import model_info_for_loggers
8
8
 
9
9
  try:
@@ -11,6 +11,7 @@ try:
11
11
 
12
12
  assert not TESTS_RUNNING # do not log pytest
13
13
  assert hasattr(comet_ml, '__version__') # verify package is not directory
14
+ assert SETTINGS['comet'] is True # verify integration is enabled
14
15
  except (ImportError, AssertionError):
15
16
  comet_ml = None
16
17
 
@@ -3,7 +3,7 @@ import os
3
3
 
4
4
  import pkg_resources as pkg
5
5
 
6
- from ultralytics.utils import LOGGER, TESTS_RUNNING
6
+ from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING
7
7
  from ultralytics.utils.torch_utils import model_info_for_loggers
8
8
 
9
9
  try:
@@ -12,6 +12,7 @@ try:
12
12
  import dvclive
13
13
 
14
14
  assert not TESTS_RUNNING # do not log pytest
15
+ assert SETTINGS['dvc'] is True # verify integration is enabled
15
16
 
16
17
  ver = version('dvclive')
17
18
  if pkg.parse_version(ver) < pkg.parse_version('2.11.0'):
@@ -4,7 +4,7 @@ import json
4
4
  from time import time
5
5
 
6
6
  from ultralytics.hub.utils import PREFIX, events
7
- from ultralytics.utils import LOGGER
7
+ from ultralytics.utils import LOGGER, SETTINGS
8
8
  from ultralytics.utils.torch_utils import model_info_for_loggers
9
9
 
10
10
 
@@ -84,4 +84,4 @@ callbacks = {
84
84
  'on_train_start': on_train_start,
85
85
  'on_val_start': on_val_start,
86
86
  'on_predict_start': on_predict_start,
87
- 'on_export_start': on_export_start}
87
+ 'on_export_start': on_export_start} if SETTINGS['hub'] is True else {} # verify enabled
@@ -4,13 +4,14 @@ import os
4
4
  import re
5
5
  from pathlib import Path
6
6
 
7
- from ultralytics.utils import LOGGER, TESTS_RUNNING, colorstr
7
+ from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING, colorstr
8
8
 
9
9
  try:
10
10
  import mlflow
11
11
 
12
12
  assert not TESTS_RUNNING # do not log pytest
13
13
  assert hasattr(mlflow, '__version__') # verify package is not directory
14
+ assert SETTINGS['mlflow'] is True # verify integration is enabled
14
15
  except (ImportError, AssertionError):
15
16
  mlflow = None
16
17
 
@@ -3,7 +3,7 @@
3
3
  import matplotlib.image as mpimg
4
4
  import matplotlib.pyplot as plt
5
5
 
6
- from ultralytics.utils import LOGGER, TESTS_RUNNING
6
+ from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING
7
7
  from ultralytics.utils.torch_utils import model_info_for_loggers
8
8
 
9
9
  try:
@@ -12,6 +12,7 @@ try:
12
12
 
13
13
  assert not TESTS_RUNNING # do not log pytest
14
14
  assert hasattr(neptune, '__version__')
15
+ assert SETTINGS['neptune'] is True # verify integration is enabled
15
16
  except (ImportError, AssertionError):
16
17
  neptune = None
17
18
 
@@ -1,9 +1,13 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
+ from ultralytics.utils import SETTINGS
4
+
3
5
  try:
4
6
  import ray
5
7
  from ray import tune
6
8
  from ray.air import session
9
+
10
+ assert SETTINGS['raytune'] is True # verify integration is enabled
7
11
  except (ImportError, AssertionError):
8
12
  tune = None
9
13
 
@@ -1,11 +1,12 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
2
 
3
- from ultralytics.utils import LOGGER, TESTS_RUNNING, colorstr
3
+ from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING, colorstr
4
4
 
5
5
  try:
6
6
  from torch.utils.tensorboard import SummaryWriter
7
7
 
8
8
  assert not TESTS_RUNNING # do not log pytest
9
+ assert SETTINGS['tensorboard'] is True # verify integration is enabled
9
10
 
10
11
  # TypeError for handling 'Descriptors cannot not be created directly.' protobuf errors in Windows
11
12
  except (ImportError, AssertionError, TypeError):
@@ -1,5 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
- from ultralytics.utils import TESTS_RUNNING
2
+ from ultralytics.utils import SETTINGS, TESTS_RUNNING
3
3
  from ultralytics.utils.torch_utils import model_info_for_loggers
4
4
 
5
5
  try:
@@ -7,6 +7,7 @@ try:
7
7
 
8
8
  assert hasattr(wb, '__version__')
9
9
  assert not TESTS_RUNNING # do not log pytest
10
+ assert SETTINGS['wandb'] is True # verify integration is enabled
10
11
  except (ImportError, AssertionError):
11
12
  wb = None
12
13
 
@@ -16,7 +17,7 @@ _processed_plots = {}
16
17
  def _log_plots(plots, step):
17
18
  for name, params in plots.items():
18
19
  timestamp = params['timestamp']
19
- if _processed_plots.get(name, None) != timestamp:
20
+ if _processed_plots.get(name) != timestamp:
20
21
  wb.run.log({name.stem: wb.Image(str(name))}, step=step)
21
22
  _processed_plots[name] = timestamp
22
23
 
@@ -38,7 +38,7 @@ def spaces_in_path(path):
38
38
  path (str | Path): The original path.
39
39
 
40
40
  Yields:
41
- Path: Temporary path with spaces replaced by underscores if spaces were present, otherwise the original path.
41
+ (Path): Temporary path with spaces replaced by underscores if spaces were present, otherwise the original path.
42
42
 
43
43
  Examples:
44
44
  with spaces_in_path('/path/with spaces') as new_path:
@@ -1,5 +1,4 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
-
3
2
  import math
4
3
  import os
5
4
  import platform
@@ -57,7 +56,11 @@ def get_cpu_info():
57
56
  """Return a string with system CPU information, i.e. 'Apple M2'."""
58
57
  check_requirements('py-cpuinfo')
59
58
  import cpuinfo # noqa
60
- return cpuinfo.get_cpu_info()['brand_raw'].replace('(R)', '').replace('CPU ', '').replace('@ ', '')
59
+
60
+ k = 'brand_raw', 'hardware_raw', 'arch_string_raw' # info keys sorted by preference (not all keys always available)
61
+ info = cpuinfo.get_cpu_info() # info dict
62
+ string = info.get(k[0] if k[0] in info else k[1] if k[1] in info else k[2], 'unknown')
63
+ return string.replace('(R)', '').replace('CPU ', '').replace('@ ', '')
61
64
 
62
65
 
63
66
  def select_device(device='', batch=0, newline=False, verbose=True):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ultralytics
3
- Version: 8.0.140
3
+ Version: 8.0.141
4
4
  Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Home-page: https://github.com/ultralytics/ultralytics
6
6
  Author: Ultralytics
@@ -293,14 +293,14 @@ We love your input! YOLOv5 and YOLOv8 would not be possible without help from ou
293
293
 
294
294
  ## <div align="center">License</div>
295
295
 
296
- YOLOv8 is available under two different licenses:
296
+ Ultralytics offers two licensing options to accommodate diverse use cases:
297
297
 
298
- - **AGPL-3.0 License**: See [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) file for details.
299
- - **Enterprise License**: Provides greater flexibility for commercial product development without the open-source requirements of AGPL-3.0. Typical use cases are embedding Ultralytics software and AI models in commercial products and applications. Request an Enterprise License at [Ultralytics Licensing](https://ultralytics.com/license).
298
+ - **AGPL-3.0 License**: This [OSI-approved](https://opensource.org/licenses/) open-source license is ideal for students and enthusiasts, promoting open collaboration and knowledge sharing. See the [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) file for more details.
299
+ - **Enterprise License**: Designed for commercial use, this license permits seamless integration of Ultralytics software and AI models into commercial goods and services, bypassing the open-source requirements of AGPL-3.0. If your scenario involves embedding our solutions into a commercial offering, reach out through [Ultralytics Licensing](https://ultralytics.com/license).
300
300
 
301
301
  ## <div align="center">Contact</div>
302
302
 
303
- For YOLOv8 bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues), and join our [Discord](https://discord.gg/2wNGbc6g9X) community for questions and discussions!
303
+ For Ultralytics bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues), and join our [Discord](https://discord.gg/2wNGbc6g9X) community for questions and discussions!
304
304
 
305
305
  <br>
306
306
  <div align="center">
@@ -1,7 +1,7 @@
1
- ultralytics/__init__.py,sha256=YJhYP7C-VsH3wyBT1ziOQ01QR97R8VorxKJRAhge0oI,503
1
+ ultralytics/__init__.py,sha256=U-OCUvx7Q2HRyZJ3sWLTp_lNlwiDNhda_CqgFiCwQz0,566
2
2
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
3
3
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
4
- ultralytics/cfg/__init__.py,sha256=K8AxCRGrpruq1S2XBCIy-418DgRknAZBsKVvqtKfGXE,18495
4
+ ultralytics/cfg/__init__.py,sha256=fhKmI6UCAru_EridNH8XN4ELdfxFjkE4ANJ8DRAb5sY,18735
5
5
  ultralytics/cfg/default.yaml,sha256=_nJYep5yHIiuwuYY3NKSs8nFefZ6kCU8LW7gCga3EYU,7173
6
6
  ultralytics/cfg/datasets/Argoverse.yaml,sha256=xy-l2NIncWoYxgQA1s1kbhBGOdP2BM6m-Fmg5XUtfw4,2746
7
7
  ultralytics/cfg/datasets/GlobalWheat2020.yaml,sha256=Wd9spwO4HV48REvgqDUX-kM5a8rxceFalxkcvWDnJZI,1981
@@ -54,7 +54,7 @@ ultralytics/engine/results.py,sha256=8VrYNEm_NOYLOKi7YmVISPBfkVlWMs5U-UvOIWK4ag0
54
54
  ultralytics/engine/trainer.py,sha256=KjOsNyZqnoClRM9NSLQLnJXnYstUr-F2AJxsPJgUFxI,31186
55
55
  ultralytics/engine/validator.py,sha256=wxMCz5TsAzh8v5o9c0EMJd4BLWOdS2jbWWql5i4X9sY,11754
56
56
  ultralytics/hub/__init__.py,sha256=6Bqn7WzlD78tVMUpFKCtIpNljRld1qUIjkMjOJFa8xk,4393
57
- ultralytics/hub/auth.py,sha256=nLtR8L4UdCF7Je_NN5jhLj4LoawsC5FRlOReQG8QPzs,5204
57
+ ultralytics/hub/auth.py,sha256=hZqPHQvtgndksDjV8a_BSVIpVkHyssibH8drIzhDdrc,5193
58
58
  ultralytics/hub/session.py,sha256=buKfWcZpU7B9mR8JUvYmjlbref6jSBk5jCcl36NucwM,8469
59
59
  ultralytics/hub/utils.py,sha256=wNcvkqi8mvccD40XqGAGiAB3ODpVgTn1RT4acFasEzw,9425
60
60
  ultralytics/models/__init__.py,sha256=UCT3Y8zazSjXuQrVw0LLrbkO8Itbp6SxaB6Zy5YApCU,99
@@ -106,7 +106,7 @@ ultralytics/models/yolo/segment/train.py,sha256=KBCZHIGmoEbZVxk-f1ZT7Cvyu361ikje
106
106
  ultralytics/models/yolo/segment/val.py,sha256=2__tkWxUAGAh4zu6TqMzkgXkXcfs_F-fcCEEOJL-M0g,12890
107
107
  ultralytics/nn/__init__.py,sha256=7T_GW3YsPg1kA-74UklF2UcabcRyttRZYrCOXiNnJqU,555
108
108
  ultralytics/nn/autobackend.py,sha256=HfD2uKr0nFi5g4H-S8h3Q-zoU60qqskCYioWsPUMb8g,26042
109
- ultralytics/nn/tasks.py,sha256=WTRrSOnvqrEjIyX-AS6XU1uDb7Z36xu8xmg5pe7t6sg,35890
109
+ ultralytics/nn/tasks.py,sha256=ooiQ2KTnTt0F8geqf7yPjhk0MJhHtnDThz_SXaWVDR4,36011
110
110
  ultralytics/nn/modules/__init__.py,sha256=cOPs3TyJ14E_hTMrj6Jt2anRmz7h-kAn7J6o4wJH2dM,1587
111
111
  ultralytics/nn/modules/block.py,sha256=RR5EQzEdb2UKCYqRh-73GuKAmaIgTSMgMP6KbvOzxPI,11841
112
112
  ultralytics/nn/modules/conv.py,sha256=HRlTrzCeEbnuMBxhsCJN1H99EC7lbTMgGvkW7RHOtMM,11647
@@ -122,14 +122,14 @@ ultralytics/trackers/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
122
122
  ultralytics/trackers/utils/gmc.py,sha256=vzuRF6yBwN17ZlCqWXFc_SJuVhfbfCIsWOgPRI_SF1c,12209
123
123
  ultralytics/trackers/utils/kalman_filter.py,sha256=gMc4gDKo_dkMiL-Zkt-U7mTxjK_z4A_njJwk0rBBSOc,18420
124
124
  ultralytics/trackers/utils/matching.py,sha256=N-qZsjmhk6_JfNpwhjX9MTkBZ9Rm-_q1gZjpIVoy7WM,8749
125
- ultralytics/utils/__init__.py,sha256=4mgCfh3yn8218Qo139Rh8YqUDTpUQ-NU9sQ-ZQIt2aE,28969
125
+ ultralytics/utils/__init__.py,sha256=G6rR-umGGMOjzYZFE-su2lIyH5ZyrYAnprlYxBOAr9k,30200
126
126
  ultralytics/utils/autobatch.py,sha256=gX1mFbPhKhGYzqLqmvMJVRHRRMIit9tbEkA5bcUY-PA,3864
127
127
  ultralytics/utils/benchmarks.py,sha256=jysbfakz4--uRWWcAxFtB8dW6fqW8fM57nAJ93XVZOA,15964
128
128
  ultralytics/utils/checks.py,sha256=Nj5rz_rkTgCehUIQqInhx-RCpyHDCPkFhgQ8rE6xZvw,19224
129
129
  ultralytics/utils/dist.py,sha256=C-C6eTOFuFV391juWMx-8ldFDty0dOS7W7eS-6vdOjU,2591
130
130
  ultralytics/utils/downloads.py,sha256=DrmB69W9BR8r565grjOFHtIyYYim1isetGqdws7m0cI,12818
131
131
  ultralytics/utils/errors.py,sha256=cfSux6tp3fVLtkv4bShfHyZHPncbo3jbQsRR-zUDcoU,312
132
- ultralytics/utils/files.py,sha256=krhkdRnRsjZJJ6mczftb5fy2OoiNUIPcmqLmfacyFMw,5448
132
+ ultralytics/utils/files.py,sha256=PFHeKx0HzmyR5wZSYzhxq_X9HHGwwNuEV5PhvKouw_0,5450
133
133
  ultralytics/utils/instance.py,sha256=iGxITi9ydxom1GB-VjVuUbIY4jgCax3aiWwY_uXoRIQ,14645
134
134
  ultralytics/utils/loss.py,sha256=yfQ0cE35lY5GF7V-0bP4QPOqzGWIjJBBnoF-AweBQak,19144
135
135
  ultralytics/utils/metrics.py,sha256=3GOKuVUkAPo1fLHtOBawAeq4trVyqlQy8hV8isPdTY4,42325
@@ -137,28 +137,28 @@ ultralytics/utils/ops.py,sha256=Iecy95EclptUHN2dvBVrxHh0mincbpNGP75HZj0PdfE,2921
137
137
  ultralytics/utils/patches.py,sha256=L0Bm8ma7BVyuO8hW-XDTBzL06GBJ9tl2ov4cAfGOh60,1246
138
138
  ultralytics/utils/plotting.py,sha256=AYdvMh8I1jYCeo1kGl9cUu-a5jVfVBhX-yVMgZ_a6_Q,24845
139
139
  ultralytics/utils/tal.py,sha256=BFovrLm0m5_Pv-hFzYMAD3oonS1MvDqdy51f_Cx6Aq8,13645
140
- ultralytics/utils/torch_utils.py,sha256=Npd7yKI080iTIj5Kbhzx4h_lLxsdI-ZnrNPDnroQ5cE,22897
140
+ ultralytics/utils/torch_utils.py,sha256=sOg0CrlqkTU0Ukn5EbEYfPzAmMa8Xw7s_LuK7A8Jc6U,23127
141
141
  ultralytics/utils/tuner.py,sha256=oHtPYVTtum8As2cwclcsjBd5H_x_dNFiaUzFyMG1XhI,5403
142
142
  ultralytics/utils/callbacks/__init__.py,sha256=nhrnMPpPDb5fgqw42w8e7fC5TjEPC-jp04dpQtaQtkU,214
143
143
  ultralytics/utils/callbacks/base.py,sha256=VpiMIW9qiyncMq9cLRmm5WGr38On0LVTK2XNDmliEbE,5593
144
- ultralytics/utils/callbacks/clearml.py,sha256=h2RUE_8LYNEjyIrvBvH4s-8P7O6xl1Rt3oNA9TPIDyI,5892
145
- ultralytics/utils/callbacks/comet.py,sha256=Cg_gvHCr6DzKJVQcmje8uyBhz6BgVC_oEIvTxzFb97Q,13035
146
- ultralytics/utils/callbacks/dvc.py,sha256=L4poEZzo7yiKpyLP-rGAqv6WLGfIaQ0PVn6lkfTmKJU,4308
147
- ultralytics/utils/callbacks/hub.py,sha256=E8jeNm5NUlqNFbrAXuH-LsXaZ6c9q8pidgbG4Kx1Hlo,3300
148
- ultralytics/utils/callbacks/mlflow.py,sha256=5HIs3huFx1dDG2cur8URE96uHI7Bwk8FieA4k6X5w9U,2620
149
- ultralytics/utils/callbacks/neptune.py,sha256=dd38HQOoTFXOlLFxyL_I5ZHGf3rkhLlCKqs_Cs7mxuc,3669
150
- ultralytics/utils/callbacks/raytune.py,sha256=wHdhqCDtK1GbDQTixpxJPzS8NWtEkXpkdIlhQmEZdHg,495
151
- ultralytics/utils/callbacks/tensorboard.py,sha256=GMi6m20qe-3jP9Qyzy8Avo3Uf-WlOf4YxTqZgC0Qta4,1630
152
- ultralytics/utils/callbacks/wb.py,sha256=ZbqxhL80UbHtUgif4nYup0VY70TgRQWaLtUIaT781t0,2178
144
+ ultralytics/utils/callbacks/clearml.py,sha256=izRkp9wZvFUskG6ofYV_vcuPNSAYqiQSJc5USeEuurI,5974
145
+ ultralytics/utils/callbacks/comet.py,sha256=jDfK-ntD9ShFJJNAXiB0Ra8SHKuKxSJWidftQrlojt4,13115
146
+ ultralytics/utils/callbacks/dvc.py,sha256=8cRgEYyom8844U2tb_Te_YGfdme6C_I1XzkGbw9ysvc,4386
147
+ ultralytics/utils/callbacks/hub.py,sha256=UZkEJzNQ05bOJXCJJzBveTA-SbYNnT2LT6zFtov9hh0,3363
148
+ ultralytics/utils/callbacks/mlflow.py,sha256=o4xiScF0TJNFBuC3EhO3XRtOd3gd7GZi9ISLfNBPhfE,2701
149
+ ultralytics/utils/callbacks/neptune.py,sha256=fr5vf9kXLTwcL41Ag9B_Paxf9SZsWTm4u6ninvKCQxY,3751
150
+ ultralytics/utils/callbacks/raytune.py,sha256=ckLwRlgkmwoEieNDoL3TFCf-4by5hWNHj5AiJ5v9GGg,608
151
+ ultralytics/utils/callbacks/tensorboard.py,sha256=z3ho0BLxEfc0K0YdiCYbYaMlo-jCTbixCm1cHHYYD_A,1716
152
+ ultralytics/utils/callbacks/wb.py,sha256=CKnErGwfNTvfGc0RhaAy5Ax9hwy3Ijl97_SNzFM9jy0,2252
153
153
  ultralytics/yolo/__init__.py,sha256=iPyUTxLglm5hj3cN6AvcZDLESMExho7eV8jD7pMYEDE,94
154
154
  ultralytics/yolo/cfg/__init__.py,sha256=i2_j4OZ1-IaQqAWkFJgf4uDH18cMs8t-J6T-fQGnP7Q,373
155
155
  ultralytics/yolo/data/__init__.py,sha256=yf8vCgHeoINeZBjKOT_SmCJozgAcoUEUHsKfVNHKCI0,823
156
156
  ultralytics/yolo/engine/__init__.py,sha256=TAHs06pR9q32XhqRfnS7bk_n7JCZMoJD9LlcySx-7M8,385
157
157
  ultralytics/yolo/utils/__init__.py,sha256=GK4bnt8wEbsJPJ5MTQGwR_6W4Nr8OdAaFHimCQ4YcSQ,647
158
158
  ultralytics/yolo/v8/__init__.py,sha256=cPnEgfUp79LakWJRJhwMMWSMba31TpiNXUDe2dugHCI,387
159
- ultralytics-8.0.140.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
160
- ultralytics-8.0.140.dist-info/METADATA,sha256=KFbrPSrHob7DVKw-10UcLghummJ-a8S5xaBnZLn-f2E,27531
161
- ultralytics-8.0.140.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
162
- ultralytics-8.0.140.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
163
- ultralytics-8.0.140.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
164
- ultralytics-8.0.140.dist-info/RECORD,,
159
+ ultralytics-8.0.141.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
160
+ ultralytics-8.0.141.dist-info/METADATA,sha256=iaQDOPIztXbgeEcg0xSEOML0D9UqS33Jy-kkS-q9F1A,27773
161
+ ultralytics-8.0.141.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
162
+ ultralytics-8.0.141.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
163
+ ultralytics-8.0.141.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
164
+ ultralytics-8.0.141.dist-info/RECORD,,