ultralytics 8.3.63__py3-none-any.whl → 8.3.65__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.
Files changed (44) hide show
  1. tests/test_exports.py +1 -1
  2. ultralytics/__init__.py +1 -1
  3. ultralytics/cfg/__init__.py +96 -88
  4. ultralytics/data/build.py +5 -1
  5. ultralytics/engine/exporter.py +50 -17
  6. ultralytics/engine/model.py +5 -5
  7. ultralytics/engine/predictor.py +16 -14
  8. ultralytics/engine/results.py +1 -1
  9. ultralytics/engine/trainer.py +2 -2
  10. ultralytics/engine/tuner.py +4 -3
  11. ultralytics/engine/validator.py +16 -14
  12. ultralytics/models/yolo/classify/predict.py +1 -1
  13. ultralytics/models/yolo/classify/train.py +1 -1
  14. ultralytics/models/yolo/classify/val.py +1 -1
  15. ultralytics/models/yolo/obb/predict.py +1 -1
  16. ultralytics/models/yolo/obb/train.py +1 -1
  17. ultralytics/models/yolo/obb/val.py +1 -1
  18. ultralytics/models/yolo/pose/predict.py +1 -1
  19. ultralytics/models/yolo/pose/train.py +1 -1
  20. ultralytics/models/yolo/pose/val.py +1 -1
  21. ultralytics/models/yolo/segment/predict.py +1 -1
  22. ultralytics/models/yolo/segment/train.py +1 -1
  23. ultralytics/models/yolo/segment/val.py +1 -1
  24. ultralytics/nn/autobackend.py +34 -4
  25. ultralytics/nn/modules/block.py +2 -2
  26. ultralytics/nn/tasks.py +57 -47
  27. ultralytics/solutions/ai_gym.py +1 -1
  28. ultralytics/solutions/heatmap.py +1 -1
  29. ultralytics/solutions/parking_management.py +1 -1
  30. ultralytics/solutions/solutions.py +1 -1
  31. ultralytics/trackers/utils/matching.py +2 -2
  32. ultralytics/utils/__init__.py +26 -2
  33. ultralytics/utils/benchmarks.py +25 -19
  34. ultralytics/utils/checks.py +24 -4
  35. ultralytics/utils/downloads.py +1 -1
  36. ultralytics/utils/instance.py +1 -1
  37. ultralytics/utils/loss.py +2 -2
  38. ultralytics/utils/tuner.py +6 -4
  39. {ultralytics-8.3.63.dist-info → ultralytics-8.3.65.dist-info}/METADATA +1 -2
  40. {ultralytics-8.3.63.dist-info → ultralytics-8.3.65.dist-info}/RECORD +44 -44
  41. {ultralytics-8.3.63.dist-info → ultralytics-8.3.65.dist-info}/LICENSE +0 -0
  42. {ultralytics-8.3.63.dist-info → ultralytics-8.3.65.dist-info}/WHEEL +0 -0
  43. {ultralytics-8.3.63.dist-info → ultralytics-8.3.65.dist-info}/entry_points.txt +0 -0
  44. {ultralytics-8.3.63.dist-info → ultralytics-8.3.65.dist-info}/top_level.txt +0 -0
@@ -20,7 +20,7 @@ class PoseValidator(DetectionValidator):
20
20
  ```python
21
21
  from ultralytics.models.yolo.pose import PoseValidator
22
22
 
23
- args = dict(model="yolov8n-pose.pt", data="coco8-pose.yaml")
23
+ args = dict(model="yolo11n-pose.pt", data="coco8-pose.yaml")
24
24
  validator = PoseValidator(args=args)
25
25
  validator()
26
26
  ```
@@ -14,7 +14,7 @@ class SegmentationPredictor(DetectionPredictor):
14
14
  from ultralytics.utils import ASSETS
15
15
  from ultralytics.models.yolo.segment import SegmentationPredictor
16
16
 
17
- args = dict(model="yolov8n-seg.pt", source=ASSETS)
17
+ args = dict(model="yolo11n-seg.pt", source=ASSETS)
18
18
  predictor = SegmentationPredictor(overrides=args)
19
19
  predictor.predict_cli()
20
20
  ```
@@ -16,7 +16,7 @@ class SegmentationTrainer(yolo.detect.DetectionTrainer):
16
16
  ```python
17
17
  from ultralytics.models.yolo.segment import SegmentationTrainer
18
18
 
19
- args = dict(model="yolov8n-seg.pt", data="coco8-seg.yaml", epochs=3)
19
+ args = dict(model="yolo11n-seg.pt", data="coco8-seg.yaml", epochs=3)
20
20
  trainer = SegmentationTrainer(overrides=args)
21
21
  trainer.train()
22
22
  ```
@@ -22,7 +22,7 @@ class SegmentationValidator(DetectionValidator):
22
22
  ```python
23
23
  from ultralytics.models.yolo.segment import SegmentationValidator
24
24
 
25
- args = dict(model="yolov8n-seg.pt", data="coco8-seg.yaml")
25
+ args = dict(model="yolo11n-seg.pt", data="coco8-seg.yaml")
26
26
  validator = SegmentationValidator(args=args)
27
27
  validator()
28
28
  ```
@@ -13,8 +13,8 @@ import torch
13
13
  import torch.nn as nn
14
14
  from PIL import Image
15
15
 
16
- from ultralytics.utils import ARM64, IS_JETSON, IS_RASPBERRYPI, LINUX, LOGGER, ROOT, yaml_load
17
- from ultralytics.utils.checks import check_requirements, check_suffix, check_version, check_yaml
16
+ from ultralytics.utils import ARM64, IS_JETSON, IS_RASPBERRYPI, LINUX, LOGGER, PYTHON_VERSION, ROOT, yaml_load
17
+ from ultralytics.utils.checks import check_requirements, check_suffix, check_version, check_yaml, is_rockchip
18
18
  from ultralytics.utils.downloads import attempt_download_asset, is_url
19
19
 
20
20
 
@@ -60,7 +60,7 @@ class AutoBackend(nn.Module):
60
60
 
61
61
  Supported Formats and Naming Conventions:
62
62
  | Format | File Suffix |
63
- |-----------------------|-------------------|
63
+ | --------------------- | ----------------- |
64
64
  | PyTorch | *.pt |
65
65
  | TorchScript | *.torchscript |
66
66
  | ONNX Runtime | *.onnx |
@@ -75,6 +75,8 @@ class AutoBackend(nn.Module):
75
75
  | PaddlePaddle | *_paddle_model/ |
76
76
  | MNN | *.mnn |
77
77
  | NCNN | *_ncnn_model/ |
78
+ | IMX | *_imx_model/ |
79
+ | RKNN | *_rknn_model/ |
78
80
 
79
81
  This class offers dynamic backend switching capabilities based on the input model format, making it easier to deploy
80
82
  models across various platforms.
@@ -124,10 +126,11 @@ class AutoBackend(nn.Module):
124
126
  mnn,
125
127
  ncnn,
126
128
  imx,
129
+ rknn,
127
130
  triton,
128
131
  ) = self._model_type(w)
129
132
  fp16 &= pt or jit or onnx or xml or engine or nn_module or triton # FP16
130
- nhwc = coreml or saved_model or pb or tflite or edgetpu # BHWC formats (vs torch BCWH)
133
+ nhwc = coreml or saved_model or pb or tflite or edgetpu or rknn # BHWC formats (vs torch BCWH)
131
134
  stride = 32 # default stride
132
135
  model, metadata, task = None, None, None
133
136
 
@@ -262,6 +265,11 @@ class AutoBackend(nn.Module):
262
265
  # TensorRT
263
266
  elif engine:
264
267
  LOGGER.info(f"Loading {w} for TensorRT inference...")
268
+
269
+ if IS_JETSON and PYTHON_VERSION <= "3.8.0":
270
+ # fix error: `np.bool` was a deprecated alias for the builtin `bool` for JetPack 4 with Python <= 3.8.0
271
+ check_requirements("numpy==1.23.5")
272
+
265
273
  try:
266
274
  import tensorrt as trt # noqa https://developer.nvidia.com/nvidia-tensorrt-download
267
275
  except ImportError:
@@ -461,6 +469,22 @@ class AutoBackend(nn.Module):
461
469
  model = TritonRemoteModel(w)
462
470
  metadata = model.metadata
463
471
 
472
+ # RKNN
473
+ elif rknn:
474
+ if not is_rockchip():
475
+ raise OSError("RKNN inference is only supported on Rockchip devices.")
476
+ LOGGER.info(f"Loading {w} for RKNN inference...")
477
+ check_requirements("rknn-toolkit-lite2")
478
+ from rknnlite.api import RKNNLite
479
+
480
+ w = Path(w)
481
+ if not w.is_file(): # if not *.rknn
482
+ w = next(w.rglob("*.rknn")) # get *.rknn file from *_rknn_model dir
483
+ rknn_model = RKNNLite()
484
+ rknn_model.load_rknn(w)
485
+ ret = rknn_model.init_runtime()
486
+ metadata = Path(w).parent / "metadata.yaml"
487
+
464
488
  # Any other format (unsupported)
465
489
  else:
466
490
  from ultralytics.engine.exporter import export_formats
@@ -647,6 +671,12 @@ class AutoBackend(nn.Module):
647
671
  im = im.cpu().numpy() # torch to numpy
648
672
  y = self.model(im)
649
673
 
674
+ # RKNN
675
+ elif self.rknn:
676
+ im = (im.cpu().numpy() * 255).astype("uint8")
677
+ im = im if isinstance(im, (list, tuple)) else [im]
678
+ y = self.rknn_model.inference(inputs=im)
679
+
650
680
  # TensorFlow (SavedModel, GraphDef, Lite, Edge TPU)
651
681
  else:
652
682
  im = im.cpu().numpy()
@@ -1139,10 +1139,10 @@ class TorchVision(nn.Module):
1139
1139
  else:
1140
1140
  self.m = torchvision.models.__dict__[model](pretrained=bool(weights))
1141
1141
  if unwrap:
1142
- layers = list(self.m.children())[:-truncate]
1142
+ layers = list(self.m.children())
1143
1143
  if isinstance(layers[0], nn.Sequential): # Second-level for some models like EfficientNet, Swin
1144
1144
  layers = [*list(layers[0].children()), *layers[1:]]
1145
- self.m = nn.Sequential(*layers)
1145
+ self.m = nn.Sequential(*(layers[:-truncate] if truncate else layers))
1146
1146
  self.split = split
1147
1147
  else:
1148
1148
  self.split = False
ultralytics/nn/tasks.py CHANGED
@@ -296,10 +296,10 @@ class BaseModel(nn.Module):
296
296
 
297
297
 
298
298
  class DetectionModel(BaseModel):
299
- """YOLOv8 detection model."""
299
+ """YOLO detection model."""
300
300
 
301
- def __init__(self, cfg="yolov8n.yaml", ch=3, nc=None, verbose=True): # model, input channels, number of classes
302
- """Initialize the YOLOv8 detection model with the given config and parameters."""
301
+ def __init__(self, cfg="yolo11n.yaml", ch=3, nc=None, verbose=True): # model, input channels, number of classes
302
+ """Initialize the YOLO detection model with the given config and parameters."""
303
303
  super().__init__()
304
304
  self.yaml = cfg if isinstance(cfg, dict) else yaml_model_load(cfg) # cfg dict
305
305
  if self.yaml["backbone"][0][2] == "Silence":
@@ -388,10 +388,10 @@ class DetectionModel(BaseModel):
388
388
 
389
389
 
390
390
  class OBBModel(DetectionModel):
391
- """YOLOv8 Oriented Bounding Box (OBB) model."""
391
+ """YOLO Oriented Bounding Box (OBB) model."""
392
392
 
393
- def __init__(self, cfg="yolov8n-obb.yaml", ch=3, nc=None, verbose=True):
394
- """Initialize YOLOv8 OBB model with given config and parameters."""
393
+ def __init__(self, cfg="yolo11n-obb.yaml", ch=3, nc=None, verbose=True):
394
+ """Initialize YOLO OBB model with given config and parameters."""
395
395
  super().__init__(cfg=cfg, ch=ch, nc=nc, verbose=verbose)
396
396
 
397
397
  def init_criterion(self):
@@ -400,9 +400,9 @@ class OBBModel(DetectionModel):
400
400
 
401
401
 
402
402
  class SegmentationModel(DetectionModel):
403
- """YOLOv8 segmentation model."""
403
+ """YOLO segmentation model."""
404
404
 
405
- def __init__(self, cfg="yolov8n-seg.yaml", ch=3, nc=None, verbose=True):
405
+ def __init__(self, cfg="yolo11n-seg.yaml", ch=3, nc=None, verbose=True):
406
406
  """Initialize YOLOv8 segmentation model with given config and parameters."""
407
407
  super().__init__(cfg=cfg, ch=ch, nc=nc, verbose=verbose)
408
408
 
@@ -412,9 +412,9 @@ class SegmentationModel(DetectionModel):
412
412
 
413
413
 
414
414
  class PoseModel(DetectionModel):
415
- """YOLOv8 pose model."""
415
+ """YOLO pose model."""
416
416
 
417
- def __init__(self, cfg="yolov8n-pose.yaml", ch=3, nc=None, data_kpt_shape=(None, None), verbose=True):
417
+ def __init__(self, cfg="yolo11n-pose.yaml", ch=3, nc=None, data_kpt_shape=(None, None), verbose=True):
418
418
  """Initialize YOLOv8 Pose model."""
419
419
  if not isinstance(cfg, dict):
420
420
  cfg = yaml_model_load(cfg) # load model YAML
@@ -429,9 +429,9 @@ class PoseModel(DetectionModel):
429
429
 
430
430
 
431
431
  class ClassificationModel(BaseModel):
432
- """YOLOv8 classification model."""
432
+ """YOLO classification model."""
433
433
 
434
- def __init__(self, cfg="yolov8n-cls.yaml", ch=3, nc=None, verbose=True):
434
+ def __init__(self, cfg="yolo11n-cls.yaml", ch=3, nc=None, verbose=True):
435
435
  """Init ClassificationModel with YAML, channels, number of classes, verbose flag."""
436
436
  super().__init__()
437
437
  self._from_yaml(cfg, ch, nc, verbose)
@@ -842,14 +842,14 @@ def torch_safe_load(weight, safe_only=False):
842
842
  f"with https://github.com/ultralytics/yolov5.\nThis model is NOT forwards compatible with "
843
843
  f"YOLOv8 at https://github.com/ultralytics/ultralytics."
844
844
  f"\nRecommend fixes are to train a new model using the latest 'ultralytics' package or to "
845
- f"run a command with an official Ultralytics model, i.e. 'yolo predict model=yolov8n.pt'"
845
+ f"run a command with an official Ultralytics model, i.e. 'yolo predict model=yolo11n.pt'"
846
846
  )
847
847
  ) from e
848
848
  LOGGER.warning(
849
849
  f"WARNING ⚠️ {weight} appears to require '{e.name}', which is not in Ultralytics requirements."
850
850
  f"\nAutoInstall will run now for '{e.name}' but this feature will be removed in the future."
851
851
  f"\nRecommend fixes are to train a new model using the latest 'ultralytics' package or to "
852
- f"run a command with an official Ultralytics model, i.e. 'yolo predict model=yolov8n.pt'"
852
+ f"run a command with an official Ultralytics model, i.e. 'yolo predict model=yolo11n.pt'"
853
853
  )
854
854
  check_requirements(e.name) # install missing module
855
855
  ckpt = torch.load(file, map_location="cpu")
@@ -954,14 +954,8 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
954
954
  LOGGER.info(f"\n{'':>3}{'from':>20}{'n':>3}{'params':>10} {'module':<45}{'arguments':<30}")
955
955
  ch = [ch]
956
956
  layers, save, c2 = [], [], ch[-1] # layers, savelist, ch out
957
- for i, (f, n, m, args) in enumerate(d["backbone"] + d["head"]): # from, number, module, args
958
- m = getattr(torch.nn, m[3:]) if "nn." in m else globals()[m] # get module
959
- for j, a in enumerate(args):
960
- if isinstance(a, str):
961
- with contextlib.suppress(ValueError):
962
- args[j] = locals()[a] if a in locals() else ast.literal_eval(a)
963
- n = n_ = max(round(n * depth), 1) if n > 1 else n # depth gain
964
- if m in {
957
+ base_modules = frozenset(
958
+ {
965
959
  Classify,
966
960
  Conv,
967
961
  ConvTranspose,
@@ -995,33 +989,49 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
995
989
  PSA,
996
990
  SCDown,
997
991
  C2fCIB,
998
- }:
992
+ }
993
+ )
994
+ repeat_modules = frozenset( # modules with 'repeat' arguments
995
+ {
996
+ BottleneckCSP,
997
+ C1,
998
+ C2,
999
+ C2f,
1000
+ C3k2,
1001
+ C2fAttn,
1002
+ C3,
1003
+ C3TR,
1004
+ C3Ghost,
1005
+ C3x,
1006
+ RepC3,
1007
+ C2fPSA,
1008
+ C2fCIB,
1009
+ C2PSA,
1010
+ }
1011
+ )
1012
+ for i, (f, n, m, args) in enumerate(d["backbone"] + d["head"]): # from, number, module, args
1013
+ m = (
1014
+ getattr(torch.nn, m[3:])
1015
+ if "nn." in m
1016
+ else getattr(__import__("torchvision").ops, m[16:])
1017
+ if "torchvision.ops." in m
1018
+ else globals()[m]
1019
+ ) # get module
1020
+ for j, a in enumerate(args):
1021
+ if isinstance(a, str):
1022
+ with contextlib.suppress(ValueError):
1023
+ args[j] = locals()[a] if a in locals() else ast.literal_eval(a)
1024
+ n = n_ = max(round(n * depth), 1) if n > 1 else n # depth gain
1025
+ if m in base_modules:
999
1026
  c1, c2 = ch[f], args[0]
1000
1027
  if c2 != nc: # if c2 not equal to number of classes (i.e. for Classify() output)
1001
1028
  c2 = make_divisible(min(c2, max_channels) * width, 8)
1002
- if m is C2fAttn:
1003
- args[1] = make_divisible(min(args[1], max_channels // 2) * width, 8) # embed channels
1004
- args[2] = int(
1005
- max(round(min(args[2], max_channels // 2 // 32)) * width, 1) if args[2] > 1 else args[2]
1006
- ) # num heads
1029
+ if m is C2fAttn: # set 1) embed channels and 2) num heads
1030
+ args[1] = make_divisible(min(args[1], max_channels // 2) * width, 8)
1031
+ args[2] = int(max(round(min(args[2], max_channels // 2 // 32)) * width, 1) if args[2] > 1 else args[2])
1007
1032
 
1008
1033
  args = [c1, c2, *args[1:]]
1009
- if m in {
1010
- BottleneckCSP,
1011
- C1,
1012
- C2,
1013
- C2f,
1014
- C3k2,
1015
- C2fAttn,
1016
- C3,
1017
- C3TR,
1018
- C3Ghost,
1019
- C3x,
1020
- RepC3,
1021
- C2fPSA,
1022
- C2fCIB,
1023
- C2PSA,
1024
- }:
1034
+ if m in repeat_modules:
1025
1035
  args.insert(2, n) # number of repeats
1026
1036
  n = 1
1027
1037
  if m is C3k2: # for M/L/X sizes
@@ -1030,7 +1040,7 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
1030
1040
  args[3] = True
1031
1041
  elif m is AIFI:
1032
1042
  args = [ch[f], *args]
1033
- elif m in {HGStem, HGBlock}:
1043
+ elif m in frozenset({HGStem, HGBlock}):
1034
1044
  c1, cm, c2 = ch[f], args[0], args[1]
1035
1045
  args = [c1, cm, c2, *args[2:]]
1036
1046
  if m is HGBlock:
@@ -1042,7 +1052,7 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
1042
1052
  args = [ch[f]]
1043
1053
  elif m is Concat:
1044
1054
  c2 = sum(ch[x] for x in f)
1045
- elif m in {Detect, WorldDetect, Segment, Pose, OBB, ImagePoolingAttn, v10Detect}:
1055
+ elif m in frozenset({Detect, WorldDetect, Segment, Pose, OBB, ImagePoolingAttn, v10Detect}):
1046
1056
  args.append([ch[x] for x in f])
1047
1057
  if m is Segment:
1048
1058
  args[2] = make_divisible(min(args[2], max_channels) * width, 8)
@@ -1050,7 +1060,7 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
1050
1060
  m.legacy = legacy
1051
1061
  elif m is RTDETRDecoder: # special case, channels arg must be passed in index 1
1052
1062
  args.insert(1, [ch[x] for x in f])
1053
- elif m in {CBLinear, TorchVision, Index}:
1063
+ elif m in frozenset({CBLinear, TorchVision, Index}):
1054
1064
  c2 = args[0]
1055
1065
  c1 = ch[f]
1056
1066
  args = [c1, c2, *args[1:]]
@@ -25,7 +25,7 @@ class AIGym(BaseSolution):
25
25
  monitor: Processes a frame to detect poses, calculate angles, and count repetitions.
26
26
 
27
27
  Examples:
28
- >>> gym = AIGym(model="yolov8n-pose.pt")
28
+ >>> gym = AIGym(model="yolo11n-pose.pt")
29
29
  >>> image = cv2.imread("gym_scene.jpg")
30
30
  >>> processed_image = gym.monitor(image)
31
31
  >>> cv2.imshow("Processed Image", processed_image)
@@ -26,7 +26,7 @@ class Heatmap(ObjectCounter):
26
26
 
27
27
  Examples:
28
28
  >>> from ultralytics.solutions import Heatmap
29
- >>> heatmap = Heatmap(model="yolov8n.pt", colormap=cv2.COLORMAP_JET)
29
+ >>> heatmap = Heatmap(model="yolo11n.pt", colormap=cv2.COLORMAP_JET)
30
30
  >>> frame = cv2.imread("frame.jpg")
31
31
  >>> processed_frame = heatmap.generate_heatmap(frame)
32
32
  """
@@ -178,7 +178,7 @@ class ParkingManagement(BaseSolution):
178
178
 
179
179
  Examples:
180
180
  >>> from ultralytics.solutions import ParkingManagement
181
- >>> parking_manager = ParkingManagement(model="yolov8n.pt", json_file="parking_regions.json")
181
+ >>> parking_manager = ParkingManagement(model="yolo11n.pt", json_file="parking_regions.json")
182
182
  >>> print(f"Occupied spaces: {parking_manager.pr_info['Occupancy']}")
183
183
  >>> print(f"Available spaces: {parking_manager.pr_info['Available']}")
184
184
  """
@@ -35,7 +35,7 @@ class BaseSolution:
35
35
  display_output: Display the results of processing, including showing frames or saving results.
36
36
 
37
37
  Examples:
38
- >>> solution = BaseSolution(model="yolov8n.pt", region=[(0, 0), (100, 0), (100, 100), (0, 100)])
38
+ >>> solution = BaseSolution(model="yolo11n.pt", region=[(0, 0), (100, 0), (100, 100), (0, 100)])
39
39
  >>> solution.initialize_region()
40
40
  >>> image = cv2.imread("image.jpg")
41
41
  >>> solution.extract_tracks(image)
@@ -55,8 +55,8 @@ def linear_assignment(cost_matrix: np.ndarray, thresh: float, use_lap: bool = Tr
55
55
  unmatched_a = list(np.arange(cost_matrix.shape[0]))
56
56
  unmatched_b = list(np.arange(cost_matrix.shape[1]))
57
57
  else:
58
- unmatched_a = list(set(np.arange(cost_matrix.shape[0])) - set(matches[:, 0]))
59
- unmatched_b = list(set(np.arange(cost_matrix.shape[1])) - set(matches[:, 1]))
58
+ unmatched_a = list(frozenset(np.arange(cost_matrix.shape[0])) - frozenset(matches[:, 0]))
59
+ unmatched_b = list(frozenset(np.arange(cost_matrix.shape[1])) - frozenset(matches[:, 1]))
60
60
 
61
61
  return matches, unmatched_a, unmatched_b
62
62
 
@@ -51,6 +51,20 @@ PYTHON_VERSION = platform.python_version()
51
51
  TORCH_VERSION = torch.__version__
52
52
  TORCHVISION_VERSION = importlib.metadata.version("torchvision") # faster than importing torchvision
53
53
  IS_VSCODE = os.environ.get("TERM_PROGRAM", False) == "vscode"
54
+ RKNN_CHIPS = frozenset(
55
+ {
56
+ "rk3588",
57
+ "rk3576",
58
+ "rk3566",
59
+ "rk3568",
60
+ "rk3562",
61
+ "rv1103",
62
+ "rv1106",
63
+ "rv1103b",
64
+ "rv1106b",
65
+ "rk2118",
66
+ }
67
+ ) # Rockchip processors available for export
54
68
  HELP_MSG = """
55
69
  Examples for running Ultralytics:
56
70
 
@@ -577,6 +591,16 @@ def is_jupyter():
577
591
  return IS_COLAB or IS_KAGGLE
578
592
 
579
593
 
594
+ def is_runpod():
595
+ """
596
+ Check if the current script is running inside a RunPod container.
597
+
598
+ Returns:
599
+ (bool): True if running in RunPod, False otherwise.
600
+ """
601
+ return "RUNPOD_POD_ID" in os.environ
602
+
603
+
580
604
  def is_docker() -> bool:
581
605
  """
582
606
  Determine if the script is running inside a Docker container.
@@ -1042,7 +1066,7 @@ def set_sentry():
1042
1066
  auto_enabling_integrations=False,
1043
1067
  traces_sample_rate=1.0,
1044
1068
  release=__version__,
1045
- environment="production", # 'dev' or 'production'
1069
+ environment="runpod" if is_runpod() else "production",
1046
1070
  before_send=before_send,
1047
1071
  ignore_errors=[KeyboardInterrupt, FileNotFoundError],
1048
1072
  )
@@ -1217,7 +1241,7 @@ class SettingsManager(JSONDict):
1217
1241
 
1218
1242
  def _validate_settings(self):
1219
1243
  """Validate the current settings and reset if necessary."""
1220
- correct_keys = set(self.keys()) == set(self.defaults.keys())
1244
+ correct_keys = frozenset(self.keys()) == frozenset(self.defaults.keys())
1221
1245
  correct_types = all(isinstance(self.get(k), type(v)) for k, v in self.defaults.items())
1222
1246
  correct_version = self.get("settings_version", "") == self.version
1223
1247
 
@@ -4,25 +4,26 @@ Benchmark a YOLO model formats for speed and accuracy.
4
4
 
5
5
  Usage:
6
6
  from ultralytics.utils.benchmarks import ProfileModels, benchmark
7
- ProfileModels(['yolov8n.yaml', 'yolov8s.yaml']).profile()
8
- benchmark(model='yolov8n.pt', imgsz=160)
7
+ ProfileModels(['yolo11n.yaml', 'yolov8s.yaml']).profile()
8
+ benchmark(model='yolo11n.pt', imgsz=160)
9
9
 
10
10
  Format | `format=argument` | Model
11
11
  --- | --- | ---
12
- PyTorch | - | yolov8n.pt
13
- TorchScript | `torchscript` | yolov8n.torchscript
14
- ONNX | `onnx` | yolov8n.onnx
15
- OpenVINO | `openvino` | yolov8n_openvino_model/
16
- TensorRT | `engine` | yolov8n.engine
17
- CoreML | `coreml` | yolov8n.mlpackage
18
- TensorFlow SavedModel | `saved_model` | yolov8n_saved_model/
19
- TensorFlow GraphDef | `pb` | yolov8n.pb
20
- TensorFlow Lite | `tflite` | yolov8n.tflite
21
- TensorFlow Edge TPU | `edgetpu` | yolov8n_edgetpu.tflite
22
- TensorFlow.js | `tfjs` | yolov8n_web_model/
23
- PaddlePaddle | `paddle` | yolov8n_paddle_model/
24
- MNN | `mnn` | yolov8n.mnn
25
- NCNN | `ncnn` | yolov8n_ncnn_model/
12
+ PyTorch | - | yolo11n.pt
13
+ TorchScript | `torchscript` | yolo11n.torchscript
14
+ ONNX | `onnx` | yolo11n.onnx
15
+ OpenVINO | `openvino` | yolo11n_openvino_model/
16
+ TensorRT | `engine` | yolo11n.engine
17
+ CoreML | `coreml` | yolo11n.mlpackage
18
+ TensorFlow SavedModel | `saved_model` | yolo11n_saved_model/
19
+ TensorFlow GraphDef | `pb` | yolo11n.pb
20
+ TensorFlow Lite | `tflite` | yolo11n.tflite
21
+ TensorFlow Edge TPU | `edgetpu` | yolo11n_edgetpu.tflite
22
+ TensorFlow.js | `tfjs` | yolo11n_web_model/
23
+ PaddlePaddle | `paddle` | yolo11n_paddle_model/
24
+ MNN | `mnn` | yolo11n.mnn
25
+ NCNN | `ncnn` | yolo11n_ncnn_model/
26
+ RKNN | `rknn` | yolo11n_rknn_model/
26
27
  """
27
28
 
28
29
  import glob
@@ -41,7 +42,7 @@ from ultralytics import YOLO, YOLOWorld
41
42
  from ultralytics.cfg import TASK2DATA, TASK2METRIC
42
43
  from ultralytics.engine.exporter import export_formats
43
44
  from ultralytics.utils import ARM64, ASSETS, IS_JETSON, IS_RASPBERRYPI, LINUX, LOGGER, MACOS, TQDM, WEIGHTS_DIR
44
- from ultralytics.utils.checks import IS_PYTHON_3_12, check_requirements, check_yolo
45
+ from ultralytics.utils.checks import IS_PYTHON_3_12, check_requirements, check_yolo, is_rockchip
45
46
  from ultralytics.utils.downloads import safe_download
46
47
  from ultralytics.utils.files import file_size
47
48
  from ultralytics.utils.torch_utils import get_cpu_info, select_device
@@ -121,6 +122,11 @@ def benchmark(
121
122
  assert not isinstance(model, YOLOWorld), "YOLOWorldv2 IMX exports not supported"
122
123
  assert model.task == "detect", "IMX only supported for detection task"
123
124
  assert "C2f" in model.__str__(), "IMX only supported for YOLOv8"
125
+ if i == 15: # RKNN
126
+ assert not isinstance(model, YOLOWorld), "YOLOWorldv2 RKNN exports not supported yet"
127
+ assert not is_end2end, "End-to-end models not supported by RKNN yet"
128
+ assert LINUX, "RKNN only supported on Linux"
129
+ assert not is_rockchip(), "RKNN Inference only supported on Rockchip devices"
124
130
  if "cpu" in device.type:
125
131
  assert cpu, "inference not supported on CPU"
126
132
  if "cuda" in device.type:
@@ -334,7 +340,7 @@ class ProfileModels:
334
340
  Examples:
335
341
  Profile models and print results
336
342
  >>> from ultralytics.utils.benchmarks import ProfileModels
337
- >>> profiler = ProfileModels(["yolov8n.yaml", "yolov8s.yaml"], imgsz=640)
343
+ >>> profiler = ProfileModels(["yolo11n.yaml", "yolov8s.yaml"], imgsz=640)
338
344
  >>> profiler.profile()
339
345
  """
340
346
 
@@ -368,7 +374,7 @@ class ProfileModels:
368
374
  Examples:
369
375
  Initialize and profile models
370
376
  >>> from ultralytics.utils.benchmarks import ProfileModels
371
- >>> profiler = ProfileModels(["yolov8n.yaml", "yolov8s.yaml"], imgsz=640)
377
+ >>> profiler = ProfileModels(["yolo11n.yaml", "yolov8s.yaml"], imgsz=640)
372
378
  >>> profiler.profile()
373
379
  """
374
380
  self.paths = paths
@@ -19,6 +19,7 @@ import requests
19
19
  import torch
20
20
 
21
21
  from ultralytics.utils import (
22
+ ARM64,
22
23
  ASSETS,
23
24
  AUTOINSTALL,
24
25
  IS_COLAB,
@@ -30,6 +31,7 @@ from ultralytics.utils import (
30
31
  MACOS,
31
32
  ONLINE,
32
33
  PYTHON_VERSION,
34
+ RKNN_CHIPS,
33
35
  ROOT,
34
36
  TORCHVISION_VERSION,
35
37
  USER_CONFIG_DIR,
@@ -487,10 +489,10 @@ def check_yolov5u_filename(file: str, verbose: bool = True):
487
489
  return file
488
490
 
489
491
 
490
- def check_model_file_from_stem(model="yolov8n"):
492
+ def check_model_file_from_stem(model="yolo11n"):
491
493
  """Return a model filename from a valid model stem."""
492
494
  if model and not Path(model).suffix and Path(model).stem in downloads.GITHUB_ASSETS_STEMS:
493
- return Path(model).with_suffix(".pt") # add suffix, i.e. yolov8n -> yolov8n.pt
495
+ return Path(model).with_suffix(".pt") # add suffix, i.e. yolo11n -> yolo11n.pt
494
496
  else:
495
497
  return model
496
498
 
@@ -782,20 +784,38 @@ def cuda_is_available() -> bool:
782
784
  return cuda_device_count() > 0
783
785
 
784
786
 
787
+ def is_rockchip():
788
+ """Check if the current environment is running on a Rockchip SoC."""
789
+ if LINUX and ARM64:
790
+ try:
791
+ with open("/proc/device-tree/compatible") as f:
792
+ dev_str = f.read()
793
+ *_, soc = dev_str.split(",")
794
+ if soc.replace("\x00", "") in RKNN_CHIPS:
795
+ return True
796
+ except OSError:
797
+ return False
798
+ else:
799
+ return False
800
+
801
+
785
802
  def is_sudo_available() -> bool:
786
803
  """
787
804
  Check if the sudo command is available in the environment.
788
805
 
789
806
  Returns:
790
- bool: True if the sudo command is available, False otherwise.
807
+ (bool): True if the sudo command is available, False otherwise.
791
808
  """
792
809
  if WINDOWS:
793
810
  return False
794
- return subprocess.run(["sudo", "--version"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0
811
+ cmd = "sudo --version"
812
+ return subprocess.run(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0
795
813
 
796
814
 
797
815
  # Run checks and define constants
798
816
  check_python("3.8", hard=False, verbose=True) # check python version
799
817
  check_torchvision() # check torch-torchvision compatibility
818
+
819
+ # Define constants
800
820
  IS_PYTHON_MINIMUM_3_10 = check_python("3.10", hard=False)
801
821
  IS_PYTHON_3_12 = PYTHON_VERSION.startswith("3.12")
@@ -405,7 +405,7 @@ def get_github_assets(repo="ultralytics/assets", version="latest", retry=False):
405
405
  LOGGER.warning(f"⚠️ GitHub assets check failure for {url}: {r.status_code} {r.reason}")
406
406
  return "", []
407
407
  data = r.json()
408
- return data["tag_name"], [x["name"] for x in data["assets"]] # tag, assets i.e. ['yolov8n.pt', 'yolov8s.pt', ...]
408
+ return data["tag_name"], [x["name"] for x in data["assets"]] # tag, assets i.e. ['yolo11n.pt', 'yolov8s.pt', ...]
409
409
 
410
410
 
411
411
  def attempt_download_asset(file, repo="ultralytics/assets", release="v8.3.0", **kwargs):
@@ -407,7 +407,7 @@ class Instances:
407
407
 
408
408
  cat_boxes = np.concatenate([ins.bboxes for ins in instances_list], axis=axis)
409
409
  seg_len = [b.segments.shape[1] for b in instances_list]
410
- if len(set(seg_len)) > 1: # resample segments if there's different length
410
+ if len(frozenset(seg_len)) > 1: # resample segments if there's different length
411
411
  max_len = max(seg_len)
412
412
  cat_segments = np.concatenate(
413
413
  [
ultralytics/utils/loss.py CHANGED
@@ -297,7 +297,7 @@ class v8SegmentationLoss(v8DetectionLoss):
297
297
  raise TypeError(
298
298
  "ERROR ❌ segment dataset incorrectly formatted or not a segment dataset.\n"
299
299
  "This error can occur when incorrectly training a 'segment' model on a 'detect' dataset, "
300
- "i.e. 'yolo train model=yolov8n-seg.pt data=coco8.yaml'.\nVerify your dataset is a "
300
+ "i.e. 'yolo train model=yolo11n-seg.pt data=coco8.yaml'.\nVerify your dataset is a "
301
301
  "correctly formatted 'segment' dataset using 'data=coco8-seg.yaml' "
302
302
  "as an example.\nSee https://docs.ultralytics.com/datasets/segment/ for help."
303
303
  ) from e
@@ -666,7 +666,7 @@ class v8OBBLoss(v8DetectionLoss):
666
666
  raise TypeError(
667
667
  "ERROR ❌ OBB dataset incorrectly formatted or not a OBB dataset.\n"
668
668
  "This error can occur when incorrectly training a 'OBB' model on a 'detect' dataset, "
669
- "i.e. 'yolo train model=yolov8n-obb.pt data=dota8.yaml'.\nVerify your dataset is a "
669
+ "i.e. 'yolo train model=yolo11n-obb.pt data=dota8.yaml'.\nVerify your dataset is a "
670
670
  "correctly formatted 'OBB' dataset using 'data=dota8.yaml' "
671
671
  "as an example.\nSee https://docs.ultralytics.com/datasets/obb/ for help."
672
672
  ) from e