diff --git a/docker/Dockerfile b/docker/Dockerfile
index c49534bc..61f43abe 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -16,6 +16,10 @@ RUN TZ=Etc/UTC apt install -y tzdata
 RUN apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg
 # RUN alias python=python3
 
+# Security updates
+# https://security.snyk.io/vuln/SNYK-UBUNTU1804-OPENSSL-3314796
+RUN apt upgrade --no-install-recommends -y openssl
+
 # Create working directory
 RUN mkdir -p /usr/src/ultralytics
 WORKDIR /usr/src/ultralytics
diff --git a/docs/cfg.md b/docs/cfg.md
index c5eca3a5..1b73abbd 100644
--- a/docs/cfg.md
+++ b/docs/cfg.md
@@ -75,6 +75,7 @@ task.
 | batch           | 16     | number of images per batch (-1 for AutoBatch)                                  |
 | imgsz           | 640    | size of input images as integer or w,h                                         |
 | save            | True   | save train checkpoints and predict results                                     |
+| save_period     | -1     | Save checkpoint every x epochs (disabled if < 1)                               |
 | cache           | False  | True/ram, disk or False. Use cache for data loading                            |
 | device          | null   | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu           |
 | workers         | 8      | number of worker threads for data loading (per RANK if DDP)                    |
diff --git a/docs/reference/ops.md b/docs/reference/ops.md
index ab0d46ee..8c4f1b75 100644
--- a/docs/reference/ops.md
+++ b/docs/reference/ops.md
@@ -2,7 +2,7 @@ This module contains optimized deep learning related operations used in the Ultr
 
 ## Non-max suppression
 
-:::ultralytics.ops.non_max_suppression
+:::ultralytics.yolo.utils.ops.non_max_suppression
 handler: python
 options:
 show_source: false
@@ -11,7 +11,7 @@ show_root_toc_entry: false
 
 ## Scale boxes
 
-:::ultralytics.ops.scale_boxes
+:::ultralytics.yolo.utils.ops.scale_boxes
 handler: python
 options:
 show_source: false
@@ -20,7 +20,7 @@ show_root_toc_entry: false
 
 ## Scale image
 
-:::ultralytics.ops.scale_image
+:::ultralytics.yolo.utils.ops.scale_image
 handler: python
 options:
 show_source: false
@@ -29,7 +29,7 @@ show_root_toc_entry: false
 
 ## clip boxes
 
-:::ultralytics.ops.clip_boxes
+:::ultralytics.yolo.utils.ops.clip_boxes
 handler: python
 options:
 show_source: false
@@ -40,7 +40,7 @@ show_root_toc_entry: false
 
 ## xyxy2xywh
 
-:::ultralytics.ops.xyxy2xywh
+:::ultralytics.yolo.utils.ops.xyxy2xywh
 handler: python
 options:
 show_source: false
@@ -49,7 +49,7 @@ show_root_toc_entry: false
 
 ## xywh2xyxy
 
-:::ultralytics.ops.xywh2xyxy
+:::ultralytics.yolo.utils.ops.xywh2xyxy
 handler: python
 options:
 show_source: false
@@ -58,7 +58,7 @@ show_root_toc_entry: false
 
 ## xywhn2xyxy
 
-:::ultralytics.ops.xywhn2xyxy
+:::ultralytics.yolo.utils.ops.xywhn2xyxy
 handler: python
 options:
 show_source: false
@@ -67,7 +67,7 @@ show_root_toc_entry: false
 
 ## xyxy2xywhn
 
-:::ultralytics.ops.xyxy2xywhn
+:::ultralytics.yolo.utils.ops.xyxy2xywhn
 handler: python
 options:
 show_source: false
@@ -76,7 +76,7 @@ show_root_toc_entry: false
 
 ## xyn2xy
 
-:::ultralytics.ops.xyn2xy
+:::ultralytics.yolo.utils.ops.xyn2xy
 handler: python
 options:
 show_source: false
@@ -85,7 +85,7 @@ show_root_toc_entry: false
 
 ## xywh2ltwh
 
-:::ultralytics.ops.xywh2ltwh
+:::ultralytics.yolo.utils.ops.xywh2ltwh
 handler: python
 options:
 show_source: false
@@ -94,7 +94,7 @@ show_root_toc_entry: false
 
 ## xyxy2ltwh
 
-:::ultralytics.ops.xyxy2ltwh
+:::ultralytics.yolo.utils.ops.xyxy2ltwh
 handler: python
 options:
 show_source: false
@@ -103,7 +103,7 @@ show_root_toc_entry: false
 
 ## ltwh2xywh
 
-:::ultralytics.ops.ltwh2xywh
+:::ultralytics.yolo.utils.ops.ltwh2xywh
 handler: python
 options:
 show_source: false
@@ -112,7 +112,7 @@ show_root_toc_entry: false
 
 ## ltwh2xyxy
 
-:::ultralytics.ops.ltwh2xyxy
+:::ultralytics.yolo.utils.ops.ltwh2xyxy
 handler: python
 options:
 show_source: false
@@ -121,7 +121,7 @@ show_root_toc_entry: false
 
 ## segment2box
 
-:::ultralytics.ops.segment2box
+:::ultralytics.yolo.utils.ops.segment2box
 handler: python
 options:
 show_source: false
@@ -132,7 +132,7 @@ show_root_toc_entry: false
 
 ## resample_segments
 
-:::ultralytics.ops.resample_segments
+:::ultralytics.yolo.utils.ops.resample_segments
 handler: python
 options:
 show_source: false
@@ -141,7 +141,7 @@ show_root_toc_entry: false
 
 ## crop_mask
 
-:::ultralytics.ops.crop_mask
+:::ultralytics.yolo.utils.ops.crop_mask
 handler: python
 options:
 show_source: false
@@ -150,7 +150,7 @@ show_root_toc_entry: false
 
 ## process_mask_upsample
 
-:::ultralytics.ops.process_mask_upsample
+:::ultralytics.yolo.utils.ops.process_mask_upsample
 handler: python
 options:
 show_source: false
@@ -159,7 +159,7 @@ show_root_toc_entry: false
 
 ## process_mask
 
-:::ultralytics.ops.process_mask
+:::ultralytics.yolo.utils.ops.process_mask
 handler: python
 options:
 show_source: false
@@ -168,7 +168,7 @@ show_root_toc_entry: false
 
 ## process_mask_native
 
-:::ultralytics.ops.process_mask_native
+:::ultralytics.yolo.utils.ops.process_mask_native
 handler: python
 options:
 show_source: false
@@ -177,7 +177,7 @@ show_root_toc_entry: false
 
 ## scale_segments
 
-:::ultralytics.ops.scale_segments
+:::ultralytics.yolo.utils.ops.scale_segments
 handler: python
 options:
 show_source: false
@@ -186,7 +186,7 @@ show_root_toc_entry: false
 
 ## masks2segments
 
-:::ultralytics.ops.masks2segments
+:::ultralytics.yolo.utils.ops.masks2segments
 handler: python
 options:
 show_source: false
@@ -195,7 +195,7 @@ show_root_toc_entry: false
 
 ## clip_segments
 
-:::ultralytics.ops.clip_segments
+:::ultralytics.yolo.utils.ops.clip_segments
 handler: python
 options:
 show_source: false
diff --git a/mkdocs.yml b/mkdocs.yml
index d19a4744..2117aa8c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -1,11 +1,12 @@
-site_name: Ultralytics YOLOv8 Docs
+site_name: YOLOv8 Docs
 repo_url: https://github.com/ultralytics/ultralytics
 edit_uri: https://github.com/ultralytics/ultralytics/tree/main/docs
 repo_name: ultralytics/ultralytics
+remote_name: https://github.com/ultralytics/docs
 
 theme:
   name: "material"
-  logo: https://github.com/ultralytics/assets/raw/main/logo/Ultralytics-logomark-white.png
+  logo: https://github.com/ultralytics/assets/raw/main/logo/Ultralytics_Logotype_Reverse.svg
   favicon: https://github.com/ultralytics/assets/raw/main/logo/favicon-yolo.ico
   font:
     text: Roboto
diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py
index db41f823..d9bdbec5 100644
--- a/ultralytics/__init__.py
+++ b/ultralytics/__init__.py
@@ -1,6 +1,6 @@
 # Ultralytics YOLO 🚀, GPL-3.0 license
 
-__version__ = "8.0.33"
+__version__ = "8.0.34"
 
 from ultralytics.yolo.engine.model import YOLO
 from ultralytics.yolo.utils.checks import check_yolo as checks
diff --git a/ultralytics/hub/__init__.py b/ultralytics/hub/__init__.py
index 6e7e8fbf..935c84aa 100644
--- a/ultralytics/hub/__init__.py
+++ b/ultralytics/hub/__init__.py
@@ -7,7 +7,7 @@ from ultralytics.hub.session import HubTrainingSession
 from ultralytics.hub.utils import split_key
 from ultralytics.yolo.engine.exporter import export_formats
 from ultralytics.yolo.engine.model import YOLO
-from ultralytics.yolo.utils import LOGGER, emojis, PREFIX
+from ultralytics.yolo.utils import LOGGER, PREFIX, emojis
 
 # Define all export formats
 EXPORT_FORMATS = list(export_formats()['Argument'][1:]) + ["ultralytics_tflite", "ultralytics_coreml"]
diff --git a/ultralytics/hub/session.py b/ultralytics/hub/session.py
index f6e87855..94e0a548 100644
--- a/ultralytics/hub/session.py
+++ b/ultralytics/hub/session.py
@@ -7,9 +7,8 @@ from time import sleep, time
 
 import requests
 
-from ultralytics import __version__
 from ultralytics.hub.utils import HUB_API_ROOT, check_dataset_disk_space, smart_request
-from ultralytics.yolo.utils import is_colab, threaded, LOGGER, emojis, PREFIX
+from ultralytics.yolo.utils import LOGGER, PREFIX, __version__, emojis, is_colab, threaded
 from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params
 
 AGENT_NAME = f"python-{__version__}-colab" if is_colab() else f"python-{__version__}-local"
diff --git a/ultralytics/hub/utils.py b/ultralytics/hub/utils.py
index f2cff500..2e2e04b4 100644
--- a/ultralytics/hub/utils.py
+++ b/ultralytics/hub/utils.py
@@ -11,9 +11,10 @@ from random import random
 
 import requests
 
-from ultralytics.yolo.utils import (DEFAULT_CFG_DICT, LOGGER, RANK, SETTINGS, TryExcept, colorstr, emojis,
-                                    get_git_origin_url, is_colab, is_docker, is_git_dir, is_github_actions_ci,
-                                    is_jupyter, is_kaggle, is_pip_package, is_pytest_running)
+from ultralytics.yolo.utils import (DEFAULT_CFG_DICT, ENVIRONMENT, LOGGER, RANK, SETTINGS, TryExcept, __version__,
+                                    colorstr, emojis, get_git_origin_url, is_git_dir, is_github_actions_ci,
+                                    is_pip_package, is_pytest_running)
+from ultralytics.yolo.utils.checks import check_online
 
 PREFIX = colorstr('Ultralytics: ')
 HELP_MSG = 'If this issue persists please visit https://github.com/ultralytics/hub/issues for assistance.'
@@ -143,9 +144,6 @@ class Traces:
         """
         Initialize Traces for error tracking and reporting if tests are not currently running.
         """
-        from ultralytics import __version__
-        env = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \
-            'Docker' if is_docker() else platform.system()
         self.rate_limit = 3.0  # rate limit (seconds)
         self.t = 0.0  # rate limit timer (seconds)
         self.metadata = {
@@ -153,9 +151,10 @@ class Traces:
             "install": 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other',
             "python": platform.python_version(),
             "release": __version__,
-            "environment": env}
+            "environment": ENVIRONMENT}
         self.enabled = SETTINGS['sync'] and \
                        RANK in {-1, 0} and \
+                       check_online() and \
                        not is_pytest_running() and \
                        not is_github_actions_ci() and \
                        (is_pip_package() or get_git_origin_url() == "https://github.com/ultralytics/ultralytics.git")
@@ -186,6 +185,7 @@ class Traces:
                           headers=None,
                           code=3,
                           retry=0,
+                          timeout=1.0,
                           verbose=False)
 
 
diff --git a/ultralytics/models/v8/seg/yolov8l-seg.yaml b/ultralytics/models/v8/seg/yolov8l-seg.yaml
index 235dc761..72bf0088 100644
--- a/ultralytics/models/v8/seg/yolov8l-seg.yaml
+++ b/ultralytics/models/v8/seg/yolov8l-seg.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [512]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [512]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Segment, [nc, 32, 256]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/seg/yolov8m-seg.yaml b/ultralytics/models/v8/seg/yolov8m-seg.yaml
index 17c07f6b..7e742275 100644
--- a/ultralytics/models/v8/seg/yolov8m-seg.yaml
+++ b/ultralytics/models/v8/seg/yolov8m-seg.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [768]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [768]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Segment, [nc, 32, 256]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/seg/yolov8n-seg.yaml b/ultralytics/models/v8/seg/yolov8n-seg.yaml
index ffecc9d9..5f39e101 100644
--- a/ultralytics/models/v8/seg/yolov8n-seg.yaml
+++ b/ultralytics/models/v8/seg/yolov8n-seg.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [1024]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Segment, [nc, 32, 256]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/seg/yolov8s-seg.yaml b/ultralytics/models/v8/seg/yolov8s-seg.yaml
index dc828a1c..27946164 100644
--- a/ultralytics/models/v8/seg/yolov8s-seg.yaml
+++ b/ultralytics/models/v8/seg/yolov8s-seg.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [1024]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Segment, [nc, 32, 256]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/seg/yolov8x-seg.yaml b/ultralytics/models/v8/seg/yolov8x-seg.yaml
index 0572283c..3edb030b 100644
--- a/ultralytics/models/v8/seg/yolov8x-seg.yaml
+++ b/ultralytics/models/v8/seg/yolov8x-seg.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [512]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [512]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Segment, [nc, 32, 256]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/yolov8l.yaml b/ultralytics/models/v8/yolov8l.yaml
index 9ec170c3..afbe4c69 100644
--- a/ultralytics/models/v8/yolov8l.yaml
+++ b/ultralytics/models/v8/yolov8l.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [512]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [512]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/yolov8m.yaml b/ultralytics/models/v8/yolov8m.yaml
index f97cf052..a17763c6 100644
--- a/ultralytics/models/v8/yolov8m.yaml
+++ b/ultralytics/models/v8/yolov8m.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [768]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [768]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/yolov8n.yaml b/ultralytics/models/v8/yolov8n.yaml
index 83cf0801..2519b402 100644
--- a/ultralytics/models/v8/yolov8n.yaml
+++ b/ultralytics/models/v8/yolov8n.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [1024]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/yolov8s.yaml b/ultralytics/models/v8/yolov8s.yaml
index 0c96d945..79056545 100644
--- a/ultralytics/models/v8/yolov8s.yaml
+++ b/ultralytics/models/v8/yolov8s.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [1024]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/models/v8/yolov8x.yaml b/ultralytics/models/v8/yolov8x.yaml
index 20e4070d..d254523c 100644
--- a/ultralytics/models/v8/yolov8x.yaml
+++ b/ultralytics/models/v8/yolov8x.yaml
@@ -23,18 +23,18 @@ backbone:
 head:
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
-  - [-1, 3, C2f, [512]]  # 13
+  - [-1, 3, C2f, [512]]  # 12
 
   - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
   - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
-  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)
+  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)
 
   - [-1, 1, Conv, [256, 3, 2]]
   - [[-1, 12], 1, Concat, [1]]  # cat head P4
-  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)
+  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)
 
   - [-1, 1, Conv, [512, 3, 2]]
   - [[-1, 9], 1, Concat, [1]]  # cat head P5
-  - [-1, 3, C2f, [512]]  # 23 (P5/32-large)
+  - [-1, 3, C2f, [512]]  # 21 (P5/32-large)
 
   - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
diff --git a/ultralytics/yolo/cfg/__init__.py b/ultralytics/yolo/cfg/__init__.py
index 34fd6f01..ec55e6d9 100644
--- a/ultralytics/yolo/cfg/__init__.py
+++ b/ultralytics/yolo/cfg/__init__.py
@@ -8,9 +8,9 @@ from pathlib import Path
 from types import SimpleNamespace
 from typing import Dict, List, Union
 
-from ultralytics import __version__
 from ultralytics.yolo.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, PREFIX, ROOT,
-                                    USER_CONFIG_DIR, IterableSimpleNamespace, colorstr, emojis, yaml_load, yaml_print)
+                                    USER_CONFIG_DIR, IterableSimpleNamespace, __version__, colorstr, emojis, yaml_load,
+                                    yaml_print)
 from ultralytics.yolo.utils.checks import check_yolo
 
 CLI_HELP_MSG = \
@@ -25,13 +25,13 @@ CLI_HELP_MSG = \
                     See all ARGS at https://docs.ultralytics.com/cfg or with 'yolo cfg'
 
     1. Train a detection model for 10 epochs with an initial learning_rate of 0.01
-        yolo detect train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01
+        yolo train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01
 
     2. Predict a YouTube video using a pretrained segmentation model at image size 320:
-        yolo segment predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320
+        yolo predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320
 
     3. Val a pretrained detection model at batch-size 1 and image size 640:
-        yolo detect val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640
+        yolo val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640
 
     4. Export a YOLOv8n classification model to ONNX format at image size 224 by 128 (no TASK required)
         yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128
@@ -56,7 +56,7 @@ CFG_FRACTION_KEYS = {
     'mixup', 'copy_paste', 'conf', 'iou'}
 CFG_INT_KEYS = {
     'epochs', 'patience', 'batch', 'workers', 'seed', 'close_mosaic', 'mask_ratio', 'max_det', 'vid_stride',
-    'line_thickness', 'workspace', 'nbs'}
+    'line_thickness', 'workspace', 'nbs', 'save_period'}
 CFG_BOOL_KEYS = {
     'save', 'exist_ok', 'pretrained', 'verbose', 'deterministic', 'single_cls', 'image_weights', 'rect', 'cos_lr',
     'overlap_mask', 'val', 'save_json', 'save_hybrid', 'half', 'dnn', 'plots', 'show', 'save_txt', 'save_conf',
@@ -131,7 +131,7 @@ def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG, override
     return IterableSimpleNamespace(**cfg)
 
 
-def check_cfg_mismatch(base: Dict, custom: Dict):
+def check_cfg_mismatch(base: Dict, custom: Dict, e=None):
     """
     This function checks for any mismatched keys between a custom configuration list and a base configuration list.
     If any mismatched keys are found, the function prints out similar keys from the base list and exits the program.
@@ -143,12 +143,12 @@ def check_cfg_mismatch(base: Dict, custom: Dict):
     base, custom = (set(x.keys()) for x in (base, custom))
     mismatched = [x for x in custom if x not in base]
     if mismatched:
+        string = ''
         for x in mismatched:
-            matches = get_close_matches(x, base, 3, 0.6)
-            match_str = f"Similar arguments are {matches}." if matches else 'There are no similar arguments.'
-            LOGGER.warning(f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}")
-        LOGGER.warning(CLI_HELP_MSG)
-        sys.exit()
+            matches = get_close_matches(x, base)
+            match_str = f"Similar arguments are {matches}." if matches else ''
+            string += f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}\n"
+        raise SyntaxError(string + CLI_HELP_MSG) from e
 
 
 def merge_equals_args(args: List[str]) -> List[str]:
@@ -178,10 +178,6 @@ def merge_equals_args(args: List[str]) -> List[str]:
     return new_args
 
 
-def argument_error(arg):
-    return SyntaxError(f"'{arg}' is not a valid YOLO argument.\n{CLI_HELP_MSG}")
-
-
 def entrypoint(debug=''):
     """
     This function is the ultralytics package entrypoint, it's responsible for parsing the command line arguments passed
@@ -212,6 +208,7 @@ def entrypoint(debug=''):
         'settings': lambda: yaml_print(USER_CONFIG_DIR / 'settings.yaml'),
         'cfg': lambda: yaml_print(DEFAULT_CFG_PATH),
         'copy-cfg': copy_default_cfg}
+    FULL_ARGS_DICT = {**DEFAULT_CFG_DICT, **{k: None for k in tasks}, **{k: None for k in modes}, **special}
     special = {**special, **{f'-{k}': v for k, v in special.items()}, **{f'--{k}': v for k, v in special.items()}}
 
     overrides = {}  # basic overrides, i.e. imgsz=320
@@ -236,7 +233,7 @@ def entrypoint(debug=''):
                             v = eval(v)
                     overrides[k] = v
             except (NameError, SyntaxError, ValueError, AssertionError) as e:
-                raise argument_error(a) from e
+                check_cfg_mismatch(FULL_ARGS_DICT, {a: ""}, e)
 
         elif a in tasks:
             overrides['task'] = a
@@ -251,7 +248,7 @@ def entrypoint(debug=''):
             raise SyntaxError(f"'{colorstr('red', 'bold', a)}' is a valid YOLO argument but is missing an '=' sign "
                               f"to set its value, i.e. try '{a}={DEFAULT_CFG_DICT[a]}'\n{CLI_HELP_MSG}")
         else:
-            raise argument_error(a)
+            check_cfg_mismatch(FULL_ARGS_DICT, {a: ""})
 
     # Defaults
     task2model = dict(detect='yolov8n.pt', segment='yolov8n-seg.pt', classify='yolov8n-cls.pt')
diff --git a/ultralytics/yolo/cfg/default.yaml b/ultralytics/yolo/cfg/default.yaml
index 6c0a7cd8..54af7e4c 100644
--- a/ultralytics/yolo/cfg/default.yaml
+++ b/ultralytics/yolo/cfg/default.yaml
@@ -12,6 +12,7 @@ patience: 50  # epochs to wait for no observable improvement for early stopping
 batch: 16  # number of images per batch (-1 for AutoBatch)
 imgsz: 640  # size of input images as integer or w,h
 save: True  # save train checkpoints and predict results
+save_period: -1 # Save checkpoint every x epochs (disabled if < 1)
 cache: False  # True/ram, disk or False. Use cache for data loading
 device:  # device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu
 workers: 8  # number of worker threads for data loading (per RANK if DDP)
diff --git a/ultralytics/yolo/data/dataloaders/stream_loaders.py b/ultralytics/yolo/data/dataloaders/stream_loaders.py
index a242eff2..d9735b90 100644
--- a/ultralytics/yolo/data/dataloaders/stream_loaders.py
+++ b/ultralytics/yolo/data/dataloaders/stream_loaders.py
@@ -291,7 +291,7 @@ class LoadPilAndNumpy:
         self.mode = 'image'
         # generate fake paths
         self.paths = [f"image{i}.jpg" for i in range(len(self.im0))]
-        self.bs = 1
+        self.bs = len(self.im0)
 
     @staticmethod
     def _single_check(im):
diff --git a/ultralytics/yolo/data/dataloaders/v5loader.py b/ultralytics/yolo/data/dataloaders/v5loader.py
index 37c15074..b27e6134 100644
--- a/ultralytics/yolo/data/dataloaders/v5loader.py
+++ b/ultralytics/yolo/data/dataloaders/v5loader.py
@@ -34,6 +34,7 @@ from ultralytics.yolo.utils.checks import check_requirements, check_yaml
 from ultralytics.yolo.utils.downloads import unzip_file
 from ultralytics.yolo.utils.ops import clean_str, segments2boxes, xyn2xy, xywh2xyxy, xywhn2xyxy, xyxy2xywhn
 from ultralytics.yolo.utils.torch_utils import torch_distributed_zero_first
+
 from .v5augmentations import (Albumentations, augment_hsv, classify_albumentations, classify_transforms, copy_paste,
                               letterbox, mixup, random_perspective)
 
diff --git a/ultralytics/yolo/data/dataset.py b/ultralytics/yolo/data/dataset.py
index fc58f6c4..5f981207 100644
--- a/ultralytics/yolo/data/dataset.py
+++ b/ultralytics/yolo/data/dataset.py
@@ -85,7 +85,6 @@ class YOLODataset(BaseDataset):
         x["results"] = nf, nm, ne, nc, len(self.im_files)
         x["msgs"] = msgs  # warnings
         x["version"] = self.cache_version  # cache version
-        self.im_files = [lb["im_file"] for lb in x["labels"]]  # update im_files
         if is_dir_writeable(path.parent):
             np.save(str(path), x)  # save cache for next time
             path.with_suffix(".cache.npy").rename(path)  # remove .npy suffix
@@ -117,6 +116,7 @@ class YOLODataset(BaseDataset):
         # Read cache
         [cache.pop(k) for k in ("hash", "version", "msgs")]  # remove items
         labels = cache["labels"]
+        self.im_files = [lb["im_file"] for lb in labels]  # update im_files
 
         # Check if the dataset is all boxes or all segments
         len_cls = sum(len(lb["cls"]) for lb in labels)
diff --git a/ultralytics/yolo/engine/exporter.py b/ultralytics/yolo/engine/exporter.py
index 760312f3..053ba52d 100644
--- a/ultralytics/yolo/engine/exporter.py
+++ b/ultralytics/yolo/engine/exporter.py
@@ -64,14 +64,13 @@ import numpy as np
 import pandas as pd
 import torch
 
-import ultralytics
 from ultralytics.nn.autobackend import check_class_names
 from ultralytics.nn.modules import Detect, Segment
 from ultralytics.nn.tasks import DetectionModel, SegmentationModel
 from ultralytics.yolo.cfg import get_cfg
 from ultralytics.yolo.data.dataloaders.stream_loaders import LoadImages
-from ultralytics.yolo.data.utils import check_det_dataset, IMAGENET_MEAN, IMAGENET_STD
-from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, callbacks, colorstr, get_default_args, yaml_save
+from ultralytics.yolo.data.utils import IMAGENET_MEAN, IMAGENET_STD, check_det_dataset
+from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, __version__, callbacks, colorstr, get_default_args, yaml_save
 from ultralytics.yolo.utils.checks import check_imgsz, check_requirements, check_version, check_yaml
 from ultralytics.yolo.utils.files import file_size
 from ultralytics.yolo.utils.ops import Profile
@@ -209,7 +208,7 @@ class Exporter:
             'description': f"Ultralytics {self.pretty_name} model trained on {self.model.args['data']}",
             'author': 'Ultralytics',
             'license': 'GPL-3.0 https://ultralytics.com/license',
-            'version': ultralytics.__version__,
+            'version': __version__,
             'stride': int(max(model.stride)),
             'names': model.names}  # model metadata
 
diff --git a/ultralytics/yolo/engine/model.py b/ultralytics/yolo/engine/model.py
index 7ae9bf75..7b0e61fd 100644
--- a/ultralytics/yolo/engine/model.py
+++ b/ultralytics/yolo/engine/model.py
@@ -1,16 +1,17 @@
 # Ultralytics YOLO 🚀, GPL-3.0 license
 
+import sys
 from pathlib import Path
 from typing import List
 
-import sys
 from ultralytics import yolo  # noqa
 from ultralytics.nn.tasks import (ClassificationModel, DetectionModel, SegmentationModel, attempt_load_one_weight,
                                   guess_model_task)
 from ultralytics.yolo.cfg import get_cfg
 from ultralytics.yolo.engine.exporter import Exporter
 from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, RANK, callbacks, yaml_load
-from ultralytics.yolo.utils.checks import check_yaml, check_imgsz
+from ultralytics.yolo.utils.checks import check_imgsz, check_yaml
+from ultralytics.yolo.utils.downloads import GITHUB_ASSET_STEMS
 from ultralytics.yolo.utils.torch_utils import smart_inference_mode
 
 # Map head to model, trainer, validator, and predictor classes
@@ -58,10 +59,13 @@ class YOLO:
         # Load or create new YOLO model
         load_methods = {'.pt': self._load, '.yaml': self._new}
         suffix = Path(model).suffix
+        if not suffix and Path(model).stem in GITHUB_ASSET_STEMS:
+            model, suffix = Path(model).with_suffix('.pt'), '.pt'  # add suffix, i.e. yolov8n -> yolov8n.pt
         if suffix in load_methods:
             {'.pt': self._load, '.yaml': self._new}[suffix](model)
         else:
-            raise NotImplementedError(f"'{suffix}' model loading not implemented")
+            raise NotImplementedError(f"'{suffix}' models not supported. Try a *.pt and *.yaml model, "
+                                      "i.e. model='yolov8n.pt' or model='yolov8n.yaml'")
 
     def __call__(self, source=None, stream=False, **kwargs):
         return self.predict(source, stream, **kwargs)
diff --git a/ultralytics/yolo/engine/trainer.py b/ultralytics/yolo/engine/trainer.py
index 3724d6ae..0a81e6d8 100644
--- a/ultralytics/yolo/engine/trainer.py
+++ b/ultralytics/yolo/engine/trainer.py
@@ -20,12 +20,11 @@ from torch.nn.parallel import DistributedDataParallel as DDP
 from torch.optim import lr_scheduler
 from tqdm import tqdm
 
-from ultralytics import __version__
 from ultralytics.nn.tasks import attempt_load_one_weight, attempt_load_weights
 from ultralytics.yolo.cfg import get_cfg
 from ultralytics.yolo.data.utils import check_cls_dataset, check_det_dataset
-from ultralytics.yolo.utils import (DEFAULT_CFG, LOGGER, RANK, SETTINGS, TQDM_BAR_FORMAT, callbacks, colorstr, emojis,
-                                    yaml_save)
+from ultralytics.yolo.utils import (DEFAULT_CFG, LOGGER, RANK, SETTINGS, TQDM_BAR_FORMAT, __version__, callbacks,
+                                    colorstr, emojis, yaml_save)
 from ultralytics.yolo.utils.autobatch import check_train_batch_size
 from ultralytics.yolo.utils.checks import check_file, check_imgsz, print_args
 from ultralytics.yolo.utils.dist import ddp_cleanup, generate_ddp_command
@@ -51,6 +50,7 @@ class BaseTrainer:
         wdir (Path): Directory to save weights.
         last (Path): Path to last checkpoint.
         best (Path): Path to best checkpoint.
+        save_period (int): Save checkpoint every x epochs (disabled if < 1).
         batch_size (int): Batch size for training.
         epochs (int): Number of epochs to train for.
         start_epoch (int): Starting epoch for training.
@@ -101,6 +101,7 @@ class BaseTrainer:
             self.args.save_dir = str(self.save_dir)
             yaml_save(self.save_dir / 'args.yaml', vars(self.args))  # save run args
         self.last, self.best = self.wdir / 'last.pt', self.wdir / 'best.pt'  # checkpoint paths
+        self.save_period = self.args.save_period
 
         self.batch_size = self.args.batch
         self.epochs = self.args.epochs
@@ -392,6 +393,8 @@ class BaseTrainer:
         torch.save(ckpt, self.last)
         if self.best_fitness == self.fitness:
             torch.save(ckpt, self.best)
+        if (self.epoch > 0) and (self.save_period > 0) and (self.epoch % self.save_period == 0):
+            torch.save(ckpt, self.wdir / f'epoch{self.epoch}.pt')
         del ckpt
 
     def get_dataset(self, data):
diff --git a/ultralytics/yolo/utils/__init__.py b/ultralytics/yolo/utils/__init__.py
index de59e9d9..2309764b 100644
--- a/ultralytics/yolo/utils/__init__.py
+++ b/ultralytics/yolo/utils/__init__.py
@@ -22,6 +22,8 @@ import requests
 import torch
 import yaml
 
+from ultralytics import __version__
+
 # Constants
 FILE = Path(__file__).resolve()
 ROOT = FILE.parents[2]  # YOLO
@@ -520,30 +522,27 @@ def set_sentry():
         if 'exc_info' in hint:
             exc_type, exc_value, tb = hint['exc_info']
             if exc_type in (KeyboardInterrupt, FileNotFoundError) \
-                    or 'out of memory' in str(exc_value) \
-                    or not sys.argv[0].endswith('yolo'):
+                    or 'out of memory' in str(exc_value):
                 return None  # do not send event
 
-        env = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \
-            'Docker' if is_docker() else platform.system()
         event['tags'] = {
             "sys_argv": sys.argv[0],
             "sys_argv_name": Path(sys.argv[0]).name,
             "install": 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other',
-            "os": env}
+            "os": ENVIRONMENT}
         return event
 
     if SETTINGS['sync'] and \
             RANK in {-1, 0} and \
-            sys.argv[0].endswith('yolo') and \
+            Path(sys.argv[0]).name == 'yolo' and \
             not is_pytest_running() and \
             not is_github_actions_ci() and \
             ((is_pip_package() and not is_git_dir()) or
              (get_git_origin_url() == "https://github.com/ultralytics/ultralytics.git" and get_git_branch() == "main")):
 
         import hashlib
+
         import sentry_sdk  # noqa
-        from ultralytics import __version__
 
         sentry_sdk.init(
             dsn="https://f805855f03bb4363bc1e16cb7d87b654@o4504521589325824.ingest.sentry.io/4504521592406016",
@@ -572,6 +571,7 @@ def get_settings(file=USER_CONFIG_DIR / 'settings.yaml', version='0.0.2'):
         dict: Dictionary of settings key-value pairs.
     """
     import hashlib
+
     from ultralytics.yolo.utils.checks import check_version
     from ultralytics.yolo.utils.torch_utils import torch_distributed_zero_first
 
@@ -628,4 +628,6 @@ if platform.system() == 'Windows':
 PREFIX = colorstr("Ultralytics: ")
 SETTINGS = get_settings()
 DATASETS_DIR = Path(SETTINGS['datasets_dir'])  # global datasets directory
+ENVIRONMENT = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \
+    'Docker' if is_docker() else platform.system()
 set_sentry()
diff --git a/ultralytics/yolo/utils/checks.py b/ultralytics/yolo/utils/checks.py
index 0bb8e619..9a03fc1b 100644
--- a/ultralytics/yolo/utils/checks.py
+++ b/ultralytics/yolo/utils/checks.py
@@ -155,7 +155,7 @@ def check_online() -> bool:
         bool: True if connection is successful, False otherwise.
     """
     import socket
-    with contextlib.suppress(subprocess.CalledProcessError):
+    with contextlib.suppress(Exception):
         host = socket.gethostbyname("www.github.com")
         socket.create_connection((host, 80), timeout=2)
         return True
diff --git a/ultralytics/yolo/utils/downloads.py b/ultralytics/yolo/utils/downloads.py
index ff2df8a2..d80bb197 100644
--- a/ultralytics/yolo/utils/downloads.py
+++ b/ultralytics/yolo/utils/downloads.py
@@ -6,7 +6,7 @@ from itertools import repeat
 from multiprocessing.pool import ThreadPool
 from pathlib import Path
 from urllib import parse, request
-from zipfile import ZipFile, is_zipfile, BadZipFile
+from zipfile import BadZipFile, ZipFile, is_zipfile
 
 import requests
 import torch
@@ -14,6 +14,11 @@ from tqdm import tqdm
 
 from ultralytics.yolo.utils import LOGGER
 
+GITHUB_ASSET_NAMES = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] + \
+                     [f'yolov5{size}u.pt' for size in 'nsmlx'] + \
+                     [f'yolov3{size}u.pt' for size in ('', '-spp', '-tiny')]
+GITHUB_ASSET_STEMS = [Path(k).stem for k in GITHUB_ASSET_NAMES]
+
 
 def is_url(url, check=True):
     # Check if string is URL and check if URL exists
@@ -158,9 +163,7 @@ def attempt_download_asset(file, repo='ultralytics/assets', release='v0.0.0'):
             return file
 
         # GitHub assets
-        assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] + \
-                 [f'yolov5{size}u.pt' for size in 'nsmlx'] + \
-                 [f'yolov3{size}u.pt' for size in ('', '-spp', '-tiny')]
+        assets = GITHUB_ASSET_NAMES
         try:
             tag, assets = github_assets(repo, release)
         except Exception:
diff --git a/ultralytics/yolo/utils/torch_utils.py b/ultralytics/yolo/utils/torch_utils.py
index 9cf5839e..0f0114ce 100644
--- a/ultralytics/yolo/utils/torch_utils.py
+++ b/ultralytics/yolo/utils/torch_utils.py
@@ -17,7 +17,7 @@ import torch.nn as nn
 import torch.nn.functional as F
 from torch.nn.parallel import DistributedDataParallel as DDP
 
-from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER
+from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, __version__
 from ultralytics.yolo.utils.checks import check_version
 
 LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1))  # https://pytorch.org/docs/stable/elastic/run.html
@@ -61,7 +61,6 @@ def DDP_model(model):
 
 def select_device(device='', batch=0, newline=False):
     # device = None or 'cpu' or 0 or '0' or '0,1,2,3'
-    from ultralytics import __version__
     s = f"Ultralytics YOLOv{__version__} 🚀 Python-{platform.python_version()} torch-{torch.__version__} "
     device = str(device).lower()
     for remove in 'cuda:', 'none', '(', ')', '[', ']', "'", ' ':
diff --git a/ultralytics/yolo/v8/classify/train.py b/ultralytics/yolo/v8/classify/train.py
index b35c8685..2a149d16 100644
--- a/ultralytics/yolo/v8/classify/train.py
+++ b/ultralytics/yolo/v8/classify/train.py
@@ -8,7 +8,7 @@ from ultralytics.yolo import v8
 from ultralytics.yolo.data import build_classification_dataloader
 from ultralytics.yolo.engine.trainer import BaseTrainer
 from ultralytics.yolo.utils import DEFAULT_CFG
-from ultralytics.yolo.utils.torch_utils import strip_optimizer, is_parallel
+from ultralytics.yolo.utils.torch_utils import is_parallel, strip_optimizer
 
 
 class ClassificationTrainer(BaseTrainer):