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

Files changed (37) hide show
  1. tests/test_cli.py +4 -16
  2. ultralytics/__init__.py +3 -2
  3. ultralytics/cfg/__init__.py +4 -0
  4. ultralytics/data/augment.py +1 -1
  5. ultralytics/hub/google/__init__.py +3 -3
  6. ultralytics/models/__init__.py +2 -1
  7. ultralytics/models/fastsam/__init__.py +1 -2
  8. ultralytics/models/fastsam/model.py +18 -0
  9. ultralytics/models/fastsam/predict.py +116 -1
  10. ultralytics/models/sam/build.py +2 -2
  11. ultralytics/models/sam/model.py +10 -2
  12. ultralytics/models/sam/modules/decoders.py +1 -42
  13. ultralytics/models/sam/modules/encoders.py +3 -1
  14. ultralytics/models/sam/modules/sam.py +5 -7
  15. ultralytics/models/sam/modules/transformer.py +4 -3
  16. ultralytics/models/sam/predict.py +12 -6
  17. ultralytics/models/sam2/__init__.py +6 -0
  18. ultralytics/models/sam2/build.py +156 -0
  19. ultralytics/models/sam2/model.py +97 -0
  20. ultralytics/models/sam2/modules/__init__.py +1 -0
  21. ultralytics/models/sam2/modules/decoders.py +305 -0
  22. ultralytics/models/sam2/modules/encoders.py +332 -0
  23. ultralytics/models/sam2/modules/memory_attention.py +170 -0
  24. ultralytics/models/sam2/modules/sam2.py +804 -0
  25. ultralytics/models/sam2/modules/sam2_blocks.py +715 -0
  26. ultralytics/models/sam2/modules/utils.py +191 -0
  27. ultralytics/models/sam2/predict.py +182 -0
  28. ultralytics/nn/modules/transformer.py +5 -3
  29. ultralytics/utils/ops.py +1 -1
  30. ultralytics/utils/torch_utils.py +9 -6
  31. {ultralytics-8.2.68.dist-info → ultralytics-8.2.70.dist-info}/METADATA +1 -1
  32. {ultralytics-8.2.68.dist-info → ultralytics-8.2.70.dist-info}/RECORD +36 -26
  33. {ultralytics-8.2.68.dist-info → ultralytics-8.2.70.dist-info}/WHEEL +1 -1
  34. ultralytics/models/fastsam/prompt.py +0 -352
  35. {ultralytics-8.2.68.dist-info → ultralytics-8.2.70.dist-info}/LICENSE +0 -0
  36. {ultralytics-8.2.68.dist-info → ultralytics-8.2.70.dist-info}/entry_points.txt +0 -0
  37. {ultralytics-8.2.68.dist-info → ultralytics-8.2.70.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,191 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+
3
+ import torch
4
+ import torch.nn.functional as F
5
+
6
+
7
+ def select_closest_cond_frames(frame_idx, cond_frame_outputs, max_cond_frame_num):
8
+ """
9
+ Selects the closest conditioning frames to a given frame index.
10
+
11
+ Args:
12
+ frame_idx (int): Current frame index.
13
+ cond_frame_outputs (Dict[int, Any]): Dictionary of conditioning frame outputs keyed by frame indices.
14
+ max_cond_frame_num (int): Maximum number of conditioning frames to select.
15
+
16
+ Returns:
17
+ (Tuple[Dict[int, Any], Dict[int, Any]]): A tuple containing two dictionaries:
18
+ - selected_outputs: Selected items from cond_frame_outputs.
19
+ - unselected_outputs: Items not selected from cond_frame_outputs.
20
+
21
+ Examples:
22
+ >>> frame_idx = 5
23
+ >>> cond_frame_outputs = {1: 'a', 3: 'b', 7: 'c', 9: 'd'}
24
+ >>> max_cond_frame_num = 2
25
+ >>> selected, unselected = select_closest_cond_frames(frame_idx, cond_frame_outputs, max_cond_frame_num)
26
+ >>> print(selected)
27
+ {3: 'b', 7: 'c'}
28
+ >>> print(unselected)
29
+ {1: 'a', 9: 'd'}
30
+ """
31
+ if max_cond_frame_num == -1 or len(cond_frame_outputs) <= max_cond_frame_num:
32
+ selected_outputs = cond_frame_outputs
33
+ unselected_outputs = {}
34
+ else:
35
+ assert max_cond_frame_num >= 2, "we should allow using 2+ conditioning frames"
36
+ selected_outputs = {}
37
+
38
+ # the closest conditioning frame before `frame_idx` (if any)
39
+ idx_before = max((t for t in cond_frame_outputs if t < frame_idx), default=None)
40
+ if idx_before is not None:
41
+ selected_outputs[idx_before] = cond_frame_outputs[idx_before]
42
+
43
+ # the closest conditioning frame after `frame_idx` (if any)
44
+ idx_after = min((t for t in cond_frame_outputs if t >= frame_idx), default=None)
45
+ if idx_after is not None:
46
+ selected_outputs[idx_after] = cond_frame_outputs[idx_after]
47
+
48
+ # add other temporally closest conditioning frames until reaching a total
49
+ # of `max_cond_frame_num` conditioning frames.
50
+ num_remain = max_cond_frame_num - len(selected_outputs)
51
+ inds_remain = sorted(
52
+ (t for t in cond_frame_outputs if t not in selected_outputs),
53
+ key=lambda x: abs(x - frame_idx),
54
+ )[:num_remain]
55
+ selected_outputs.update((t, cond_frame_outputs[t]) for t in inds_remain)
56
+ unselected_outputs = {t: v for t, v in cond_frame_outputs.items() if t not in selected_outputs}
57
+
58
+ return selected_outputs, unselected_outputs
59
+
60
+
61
+ def get_1d_sine_pe(pos_inds, dim, temperature=10000):
62
+ """Generates 1D sinusoidal positional embeddings for given positions and dimensions."""
63
+ pe_dim = dim // 2
64
+ dim_t = torch.arange(pe_dim, dtype=torch.float32, device=pos_inds.device)
65
+ dim_t = temperature ** (2 * (dim_t // 2) / pe_dim)
66
+
67
+ pos_embed = pos_inds.unsqueeze(-1) / dim_t
68
+ pos_embed = torch.cat([pos_embed.sin(), pos_embed.cos()], dim=-1)
69
+ return pos_embed
70
+
71
+
72
+ def init_t_xy(end_x: int, end_y: int):
73
+ """Initializes 1D and 2D coordinate tensors for a grid of size end_x by end_y."""
74
+ t = torch.arange(end_x * end_y, dtype=torch.float32)
75
+ t_x = (t % end_x).float()
76
+ t_y = torch.div(t, end_x, rounding_mode="floor").float()
77
+ return t_x, t_y
78
+
79
+
80
+ def compute_axial_cis(dim: int, end_x: int, end_y: int, theta: float = 10000.0):
81
+ """Computes axial complex exponential positional encodings for 2D spatial positions."""
82
+ freqs_x = 1.0 / (theta ** (torch.arange(0, dim, 4)[: (dim // 4)].float() / dim))
83
+ freqs_y = 1.0 / (theta ** (torch.arange(0, dim, 4)[: (dim // 4)].float() / dim))
84
+
85
+ t_x, t_y = init_t_xy(end_x, end_y)
86
+ freqs_x = torch.outer(t_x, freqs_x)
87
+ freqs_y = torch.outer(t_y, freqs_y)
88
+ freqs_cis_x = torch.polar(torch.ones_like(freqs_x), freqs_x)
89
+ freqs_cis_y = torch.polar(torch.ones_like(freqs_y), freqs_y)
90
+ return torch.cat([freqs_cis_x, freqs_cis_y], dim=-1)
91
+
92
+
93
+ def reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor):
94
+ """Reshapes frequency tensor for broadcasting, ensuring compatibility with input tensor dimensions."""
95
+ ndim = x.ndim
96
+ assert 0 <= 1 < ndim
97
+ assert freqs_cis.shape == (x.shape[-2], x.shape[-1])
98
+ shape = [d if i >= ndim - 2 else 1 for i, d in enumerate(x.shape)]
99
+ return freqs_cis.view(*shape)
100
+
101
+
102
+ def apply_rotary_enc(
103
+ xq: torch.Tensor,
104
+ xk: torch.Tensor,
105
+ freqs_cis: torch.Tensor,
106
+ repeat_freqs_k: bool = False,
107
+ ):
108
+ """Applies rotary positional encoding to query and key tensors using complex-valued frequency components."""
109
+ xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2))
110
+ xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2)) if xk.shape[-2] != 0 else None
111
+ freqs_cis = reshape_for_broadcast(freqs_cis, xq_)
112
+ xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3)
113
+ if xk_ is None:
114
+ # no keys to rotate, due to dropout
115
+ return xq_out.type_as(xq).to(xq.device), xk
116
+ # repeat freqs along seq_len dim to match k seq_len
117
+ if repeat_freqs_k:
118
+ r = xk_.shape[-2] // xq_.shape[-2]
119
+ freqs_cis = freqs_cis.repeat(*([1] * (freqs_cis.ndim - 2)), r, 1)
120
+ xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3)
121
+ return xq_out.type_as(xq).to(xq.device), xk_out.type_as(xk).to(xk.device)
122
+
123
+
124
+ def window_partition(x, window_size):
125
+ """
126
+ Partitions input tensor into non-overlapping windows with padding if needed.
127
+
128
+ Args:
129
+ x (torch.Tensor): Input tensor with shape (B, H, W, C).
130
+ window_size (int): Size of each window.
131
+
132
+ Returns:
133
+ (Tuple[torch.Tensor, Tuple[int, int]]): A tuple containing:
134
+ - windows (torch.Tensor): Partitioned windows with shape (B * num_windows, window_size, window_size, C).
135
+ - (Hp, Wp) (Tuple[int, int]): Padded height and width before partition.
136
+
137
+ Examples:
138
+ >>> x = torch.randn(1, 16, 16, 3)
139
+ >>> windows, (Hp, Wp) = window_partition(x, window_size=4)
140
+ >>> print(windows.shape, Hp, Wp)
141
+ torch.Size([16, 4, 4, 3]) 16 16
142
+ """
143
+ B, H, W, C = x.shape
144
+
145
+ pad_h = (window_size - H % window_size) % window_size
146
+ pad_w = (window_size - W % window_size) % window_size
147
+ if pad_h > 0 or pad_w > 0:
148
+ x = F.pad(x, (0, 0, 0, pad_w, 0, pad_h))
149
+ Hp, Wp = H + pad_h, W + pad_w
150
+
151
+ x = x.view(B, Hp // window_size, window_size, Wp // window_size, window_size, C)
152
+ windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
153
+ return windows, (Hp, Wp)
154
+
155
+
156
+ def window_unpartition(windows, window_size, pad_hw, hw):
157
+ """
158
+ Unpartitions windowed sequences into original sequences and removes padding.
159
+
160
+ This function reverses the windowing process, reconstructing the original input from windowed segments
161
+ and removing any padding that was added during the windowing process.
162
+
163
+ Args:
164
+ windows (torch.Tensor): Input tensor of windowed sequences with shape (B * num_windows, window_size,
165
+ window_size, C), where B is the batch size, num_windows is the number of windows, window_size is
166
+ the size of each window, and C is the number of channels.
167
+ window_size (int): Size of each window.
168
+ pad_hw (Tuple[int, int]): Padded height and width (Hp, Wp) of the input before windowing.
169
+ hw (Tuple[int, int]): Original height and width (H, W) of the input before padding and windowing.
170
+
171
+ Returns:
172
+ (torch.Tensor): Unpartitioned sequences with shape (B, H, W, C), where B is the batch size, H and W
173
+ are the original height and width, and C is the number of channels.
174
+
175
+ Examples:
176
+ >>> windows = torch.rand(32, 8, 8, 64) # 32 windows of size 8x8 with 64 channels
177
+ >>> pad_hw = (16, 16) # Padded height and width
178
+ >>> hw = (15, 14) # Original height and width
179
+ >>> x = window_unpartition(windows, window_size=8, pad_hw=pad_hw, hw=hw)
180
+ >>> print(x.shape)
181
+ torch.Size([1, 15, 14, 64])
182
+ """
183
+ Hp, Wp = pad_hw
184
+ H, W = hw
185
+ B = windows.shape[0] // (Hp * Wp // window_size // window_size)
186
+ x = windows.view(B, Hp // window_size, Wp // window_size, window_size, window_size, -1)
187
+ x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, Hp, Wp, -1)
188
+
189
+ if Hp > H or Wp > W:
190
+ x = x[:, :H, :W, :].contiguous()
191
+ return x
@@ -0,0 +1,182 @@
1
+ # Ultralytics YOLO 🚀, AGPL-3.0 license
2
+
3
+ import torch
4
+
5
+ from ..sam.predict import Predictor
6
+ from .build import build_sam2
7
+
8
+
9
+ class SAM2Predictor(Predictor):
10
+ """
11
+ A predictor class for the Segment Anything Model 2 (SAM2), extending the base Predictor class.
12
+
13
+ This class provides an interface for model inference tailored to image segmentation tasks, leveraging SAM2's
14
+ advanced architecture and promptable segmentation capabilities. It facilitates flexible and real-time mask
15
+ generation, working with various types of prompts such as bounding boxes, points, and low-resolution masks.
16
+
17
+ Attributes:
18
+ cfg (Dict): Configuration dictionary specifying model and task-related parameters.
19
+ overrides (Dict): Dictionary containing values that override the default configuration.
20
+ _callbacks (Dict): Dictionary of user-defined callback functions to augment behavior.
21
+ args (namespace): Namespace to hold command-line arguments or other operational variables.
22
+ im (torch.Tensor): Preprocessed input image tensor.
23
+ features (torch.Tensor): Extracted image features used for inference.
24
+ prompts (Dict): Collection of various prompt types, such as bounding boxes and points.
25
+ segment_all (bool): Flag to control whether to segment all objects in the image or only specified ones.
26
+ model (torch.nn.Module): The loaded SAM2 model.
27
+ device (torch.device): The device (CPU or GPU) on which the model is loaded.
28
+ _bb_feat_sizes (List[Tuple[int, int]]): List of feature sizes for different backbone levels.
29
+
30
+ Methods:
31
+ get_model: Builds and returns the SAM2 model.
32
+ prompt_inference: Performs image segmentation inference based on various prompts.
33
+ set_image: Preprocesses and sets a single image for inference.
34
+ get_im_features: Extracts image features from the SAM2 image encoder.
35
+
36
+ Examples:
37
+ >>> predictor = SAM2Predictor(model='sam2_l.pt')
38
+ >>> predictor.set_image('path/to/image.jpg')
39
+ >>> masks, scores = predictor.prompt_inference(im=predictor.im, points=[[500, 375]], labels=[1])
40
+ >>> print(f"Generated {len(masks)} mask(s) with scores: {scores}")
41
+ """
42
+
43
+ _bb_feat_sizes = [
44
+ (256, 256),
45
+ (128, 128),
46
+ (64, 64),
47
+ ]
48
+
49
+ def get_model(self):
50
+ """Retrieves and initializes the Segment Anything Model (SAM) for image segmentation tasks."""
51
+ return build_sam2(self.args.model)
52
+
53
+ def prompt_inference(
54
+ self,
55
+ im,
56
+ bboxes=None,
57
+ points=None,
58
+ labels=None,
59
+ masks=None,
60
+ multimask_output=False,
61
+ img_idx=-1,
62
+ ):
63
+ """
64
+ Performs image segmentation inference based on various prompts using SAM2 architecture.
65
+
66
+ Args:
67
+ im (torch.Tensor): Preprocessed input image tensor with shape (N, C, H, W).
68
+ bboxes (np.ndarray | List | None): Bounding boxes in XYXY format with shape (N, 4).
69
+ points (np.ndarray | List | None): Points indicating object locations with shape (N, 2), in pixels.
70
+ labels (np.ndarray | List | None): Labels for point prompts with shape (N,). 1 = foreground, 0 = background.
71
+ masks (np.ndarray | None): Low-resolution masks from previous predictions with shape (N, H, W).
72
+ multimask_output (bool): Flag to return multiple masks for ambiguous prompts.
73
+ img_idx (int): Index of the image in the batch to process.
74
+
75
+ Returns:
76
+ (tuple): Tuple containing:
77
+ - np.ndarray: Output masks with shape (C, H, W), where C is the number of generated masks.
78
+ - np.ndarray: Quality scores for each mask, with length C.
79
+ - np.ndarray: Low-resolution logits with shape (C, 256, 256) for subsequent inference.
80
+
81
+ Examples:
82
+ >>> predictor = SAM2Predictor(cfg)
83
+ >>> image = torch.rand(1, 3, 640, 640)
84
+ >>> bboxes = [[100, 100, 200, 200]]
85
+ >>> masks, scores, logits = predictor.prompt_inference(image, bboxes=bboxes)
86
+ """
87
+ features = self.get_im_features(im) if self.features is None else self.features
88
+
89
+ src_shape, dst_shape = self.batch[1][0].shape[:2], im.shape[2:]
90
+ r = 1.0 if self.segment_all else min(dst_shape[0] / src_shape[0], dst_shape[1] / src_shape[1])
91
+ # Transform input prompts
92
+ if points is not None:
93
+ points = torch.as_tensor(points, dtype=torch.float32, device=self.device)
94
+ points = points[None] if points.ndim == 1 else points
95
+ # Assuming labels are all positive if users don't pass labels.
96
+ if labels is None:
97
+ labels = torch.ones(points.shape[0])
98
+ labels = torch.as_tensor(labels, dtype=torch.int32, device=self.device)
99
+ points *= r
100
+ # (N, 2) --> (N, 1, 2), (N, ) --> (N, 1)
101
+ points, labels = points[:, None], labels[:, None]
102
+ if bboxes is not None:
103
+ bboxes = torch.as_tensor(bboxes, dtype=torch.float32, device=self.device)
104
+ bboxes = bboxes[None] if bboxes.ndim == 1 else bboxes
105
+ bboxes *= r
106
+ if masks is not None:
107
+ masks = torch.as_tensor(masks, dtype=torch.float32, device=self.device).unsqueeze(1)
108
+
109
+ points = (points, labels) if points is not None else None
110
+ # TODO: Embed prompts
111
+ # if bboxes is not None:
112
+ # box_coords = bboxes.reshape(-1, 2, 2)
113
+ # box_labels = torch.tensor([[2, 3]], dtype=torch.int, device=bboxes.device)
114
+ # box_labels = box_labels.repeat(bboxes.size(0), 1)
115
+ # # we merge "boxes" and "points" into a single "concat_points" input (where
116
+ # # boxes are added at the beginning) to sam_prompt_encoder
117
+ # if concat_points is not None:
118
+ # concat_coords = torch.cat([box_coords, concat_points[0]], dim=1)
119
+ # concat_labels = torch.cat([box_labels, concat_points[1]], dim=1)
120
+ # concat_points = (concat_coords, concat_labels)
121
+ # else:
122
+ # concat_points = (box_coords, box_labels)
123
+
124
+ sparse_embeddings, dense_embeddings = self.model.sam_prompt_encoder(
125
+ points=points,
126
+ boxes=bboxes,
127
+ masks=masks,
128
+ )
129
+ # Predict masks
130
+ batched_mode = points is not None and points[0].shape[0] > 1 # multi object prediction
131
+ high_res_features = [feat_level[img_idx].unsqueeze(0) for feat_level in features["high_res_feats"]]
132
+ pred_masks, pred_scores, _, _ = self.model.sam_mask_decoder(
133
+ image_embeddings=features["image_embed"][img_idx].unsqueeze(0),
134
+ image_pe=self.model.sam_prompt_encoder.get_dense_pe(),
135
+ sparse_prompt_embeddings=sparse_embeddings,
136
+ dense_prompt_embeddings=dense_embeddings,
137
+ multimask_output=multimask_output,
138
+ repeat_image=batched_mode,
139
+ high_res_features=high_res_features,
140
+ )
141
+ # (N, d, H, W) --> (N*d, H, W), (N, d) --> (N*d, )
142
+ # `d` could be 1 or 3 depends on `multimask_output`.
143
+ return pred_masks.flatten(0, 1), pred_scores.flatten(0, 1)
144
+
145
+ def set_image(self, image):
146
+ """
147
+ Preprocesses and sets a single image for inference.
148
+
149
+ This function sets up the model if not already initialized, configures the data source to the specified image,
150
+ and preprocesses the image for feature extraction. Only one image can be set at a time.
151
+
152
+ Args:
153
+ image (str | np.ndarray): Image file path as a string, or a numpy array image read by cv2.
154
+
155
+ Raises:
156
+ AssertionError: If more than one image is set.
157
+
158
+ Examples:
159
+ >>> predictor = SAM2Predictor()
160
+ >>> predictor.set_image("path/to/image.jpg")
161
+ >>> predictor.set_image(np.array([...])) # Using a numpy array
162
+ """
163
+ if self.model is None:
164
+ self.setup_model(model=None)
165
+ self.setup_source(image)
166
+ assert len(self.dataset) == 1, "`set_image` only supports setting one image!"
167
+ for batch in self.dataset:
168
+ im = self.preprocess(batch[1])
169
+ self.features = self.get_im_features(im)
170
+ break
171
+
172
+ def get_im_features(self, im):
173
+ """Extracts and processes image features using SAM2's image encoder for subsequent segmentation tasks."""
174
+ backbone_out = self.model.forward_image(im)
175
+ _, vision_feats, _, _ = self.model._prepare_backbone_features(backbone_out)
176
+ if self.model.directly_add_no_mem_embed:
177
+ vision_feats[-1] = vision_feats[-1] + self.model.no_mem_embed
178
+ feats = [
179
+ feat.permute(1, 2, 0).view(1, -1, *feat_size)
180
+ for feat, feat_size in zip(vision_feats[::-1], self._bb_feat_sizes[::-1])
181
+ ][::-1]
182
+ return {"image_embed": feats[-1], "high_res_feats": feats[:-1]}
@@ -174,18 +174,20 @@ class MLPBlock(nn.Module):
174
174
  class MLP(nn.Module):
175
175
  """Implements a simple multi-layer perceptron (also called FFN)."""
176
176
 
177
- def __init__(self, input_dim, hidden_dim, output_dim, num_layers):
177
+ def __init__(self, input_dim, hidden_dim, output_dim, num_layers, act=nn.ReLU, sigmoid=False):
178
178
  """Initialize the MLP with specified input, hidden, output dimensions and number of layers."""
179
179
  super().__init__()
180
180
  self.num_layers = num_layers
181
181
  h = [hidden_dim] * (num_layers - 1)
182
182
  self.layers = nn.ModuleList(nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim]))
183
+ self.sigmoid = sigmoid
184
+ self.act = act()
183
185
 
184
186
  def forward(self, x):
185
187
  """Forward pass for the entire MLP."""
186
188
  for i, layer in enumerate(self.layers):
187
- x = F.relu(layer(x)) if i < self.num_layers - 1 else layer(x)
188
- return x
189
+ x = self.act(layer(x)) if i < self.num_layers - 1 else layer(x)
190
+ return x.sigmoid() if self.sigmoid else x
189
191
 
190
192
 
191
193
  class LayerNorm2d(nn.Module):
ultralytics/utils/ops.py CHANGED
@@ -363,7 +363,7 @@ def scale_image(masks, im0_shape, ratio_pad=None):
363
363
  ratio_pad (tuple): the ratio of the padding to the original image.
364
364
 
365
365
  Returns:
366
- masks (torch.Tensor): The masks that are being returned.
366
+ masks (np.ndarray): The masks that are being returned with shape [h, w, num].
367
367
  """
368
368
  # Rescale coordinates (xyxy) from im1_shape to im0_shape
369
369
  im1_shape = masks.shape
@@ -1,5 +1,5 @@
1
1
  # Ultralytics YOLO 🚀, AGPL-3.0 license
2
-
2
+ import contextlib
3
3
  import gc
4
4
  import math
5
5
  import os
@@ -101,12 +101,15 @@ def autocast(enabled: bool, device: str = "cuda"):
101
101
 
102
102
  def get_cpu_info():
103
103
  """Return a string with system CPU information, i.e. 'Apple M2'."""
104
- import cpuinfo # pip install py-cpuinfo
104
+ with contextlib.suppress(Exception):
105
+ import cpuinfo # pip install py-cpuinfo
106
+
107
+ k = "brand_raw", "hardware_raw", "arch_string_raw" # keys sorted by preference (not all keys always available)
108
+ info = cpuinfo.get_cpu_info() # info dict
109
+ string = info.get(k[0] if k[0] in info else k[1] if k[1] in info else k[2], "unknown")
110
+ return string.replace("(R)", "").replace("CPU ", "").replace("@ ", "")
105
111
 
106
- k = "brand_raw", "hardware_raw", "arch_string_raw" # info keys sorted by preference (not all keys always available)
107
- info = cpuinfo.get_cpu_info() # info dict
108
- string = info.get(k[0] if k[0] in info else k[1] if k[1] in info else k[2], "unknown")
109
- return string.replace("(R)", "").replace("CPU ", "").replace("@ ", "")
112
+ return "unknown"
110
113
 
111
114
 
112
115
  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.2.68
3
+ Version: 8.2.70
4
4
  Summary: Ultralytics YOLOv8 for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification.
5
5
  Author: Glenn Jocher, Ayush Chaurasia, Jing Qiu
6
6
  Maintainer: Glenn Jocher, Ayush Chaurasia, Jing Qiu
@@ -1,6 +1,6 @@
1
1
  tests/__init__.py,sha256=9evx3lOdKZeY1iWXvH-FkMkgf8jLucWICoabzeD6aYg,626
2
2
  tests/conftest.py,sha256=3ZtD4VlMKK5jVJwIPCrNAcG63vywJzdLq7U2AfYR2VI,2919
3
- tests/test_cli.py,sha256=KOEdoSwIwyZ_qFn02XdSy2CxtLdJsz7XnXVWmn7oc0s,5129
3
+ tests/test_cli.py,sha256=PqZVSKBjLeHwQzh_hVKucQibqTFtP-2ZS6ndZRpqUDI,4654
4
4
  tests/test_cuda.py,sha256=uD-ddNEcBMFQmQ9iE4fIGh0EIcGwEoDEUNVCEHicaWE,5133
5
5
  tests/test_engine.py,sha256=xW-UT9_9xZp-7-hSnbJgMw_ezTk6NqTOIiA59XZDmxA,4934
6
6
  tests/test_explorer.py,sha256=NcxSJeB6FxwkN09hQl7nnQL--HjfHB_WcZk0mEmBNHI,2215
@@ -8,10 +8,10 @@ tests/test_exports.py,sha256=Uezf3OatpPHlo5qoPw-2kqkZxuMCF9L4XF2riD4vmII,8225
8
8
  tests/test_integrations.py,sha256=xglcfMPjfVh346PV8WTpk6tBxraCXEFJEQyyJMr5tyU,6064
9
9
  tests/test_python.py,sha256=cLK8dyRf_4H_znFIm-krnOFMydwkxKlVZvHwl9vbck8,21780
10
10
  tests/test_solutions.py,sha256=EACnPXbeJe2aVTOKfqMk5jclKKCWCVgFEzjpR6y7Sh8,3304
11
- ultralytics/__init__.py,sha256=kFbWHacl29mp-kVoUKfsiqYWu9a_pbJU0q7y0xeg7uE,694
11
+ ultralytics/__init__.py,sha256=owseSmNdGVrMsFY8JStrJkvvK1SHmePnfOJ7BC6hzb0,712
12
12
  ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
13
13
  ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
14
- ultralytics/cfg/__init__.py,sha256=fD3Llw12sIkJo4g667t6b051je9nEpwdBLGgbbVEzHY,32973
14
+ ultralytics/cfg/__init__.py,sha256=7ce3_bhi7pDw5ZAbSqYR6e3_IYD2JCLCy7fkl5d1WyI,33064
15
15
  ultralytics/cfg/default.yaml,sha256=xRKVF-Z9E3imXTU9OCK94kj3jGgYoo67VJQwuYlHiUU,8228
16
16
  ultralytics/cfg/datasets/Argoverse.yaml,sha256=FyeuJT5CHq_9d4hlfAf0kpZlnbUMO0S--UJ1yIqcdKk,3134
17
17
  ultralytics/cfg/datasets/DOTAv1.5.yaml,sha256=QVfp_Qp-4rukuicaB4qx86NxSHM8Mrzym8l_fIDo8gw,1195
@@ -84,7 +84,7 @@ ultralytics/cfg/trackers/botsort.yaml,sha256=YrPmj18p1UU40kJH5NRdL_4S8f7knggkk_q
84
84
  ultralytics/cfg/trackers/bytetrack.yaml,sha256=QvHmtuwulK4X6j3T5VEqtCm0sbWWBUVmWPcCcM20qe0,688
85
85
  ultralytics/data/__init__.py,sha256=VGe-ATG7j35F4A4r8Jmzffjlhve4JAJPgRa5ahKTU18,616
86
86
  ultralytics/data/annotator.py,sha256=1Hyu6ubrBL8KmRrt1keGn-K4XTqQdAVyIwTsQiBtzLU,2489
87
- ultralytics/data/augment.py,sha256=iYkTgHkmYZByMCgmdarX2M6xihKsJN1SXC9g7vaUETE,119314
87
+ ultralytics/data/augment.py,sha256=ExU4khJfJ_TeczkJRLNUDscN57SJvAjnm-reouJcxGI,119309
88
88
  ultralytics/data/base.py,sha256=C3teLnw97ZTbpJHT9P7yYWosAKocMzgJjRe1rxgfpls,13524
89
89
  ultralytics/data/build.py,sha256=AfMmz0sHIYmwry_90tEJFRk_kz0S3SolScVXqYHiT08,7261
90
90
  ultralytics/data/converter.py,sha256=7640xKuf7LPeoTwoCvgbIXM5xbzyq72Hu2Rf2lrgjRY,17554
@@ -109,12 +109,11 @@ ultralytics/hub/__init__.py,sha256=93bqI8x8-MfDYdKkQVduuocUiQj3WGnk1nIk0li08zA,5
109
109
  ultralytics/hub/auth.py,sha256=FID58NE6fh7Op_B45QOpWBw1qoBN0ponL16uvyb2dZ8,5399
110
110
  ultralytics/hub/session.py,sha256=UF_aVwyxnbP-OzpzKXGGhi4i6KGWjjhoj5Qsn46dFpE,16257
111
111
  ultralytics/hub/utils.py,sha256=tXfM3QbXBcf4Y6StgHI1pktT4OM7Ic9eF3xiBFHGlhY,9721
112
- ultralytics/hub/google/__init__.py,sha256=0jjs294Kd1iEdRUGgoqIGUrUNzDFtSwV_M8H9_BQoGU,7512
113
- ultralytics/models/__init__.py,sha256=TT9iLCL_n9Y80dcUq0Fo-p-GRZCSU2vrWXM3CoMwqqE,265
114
- ultralytics/models/fastsam/__init__.py,sha256=0dt65jZ_5b7Q-mdXN8MSEkgnFRA0FIwlel_LS2RaOlU,254
115
- ultralytics/models/fastsam/model.py,sha256=c7GGwaa9AXssJFwrcuytFHpPOlgSrS3n0utyf4JSL2o,1055
116
- ultralytics/models/fastsam/predict.py,sha256=_bOSU75qLK1XESxl-XW1SOxriCaX7nsvl5x4exG_c4Q,1324
117
- ultralytics/models/fastsam/prompt.py,sha256=4d9e1fEuGpTPWRfu3rG6HT8Bc0rtqJtRpNrlHkmkKcY,15860
112
+ ultralytics/hub/google/__init__.py,sha256=qyvvpGP-4NAtrn7GLqfqxP_aWuRP1T0OvJYafWKvL2Q,7512
113
+ ultralytics/models/__init__.py,sha256=AlVStwxv5pMrYaPL8dLhu4sY2c2JgqmuK__RlEDKrEo,296
114
+ ultralytics/models/fastsam/__init__.py,sha256=W0rRSJM3vdxcsneuiN6_ajkUw86k6-opUKdLxVhKOoQ,203
115
+ ultralytics/models/fastsam/model.py,sha256=r5VZj-KLKaqZtEKTZxQik8vQI2N9uOF4xpV_gA-P8h0,2101
116
+ ultralytics/models/fastsam/predict.py,sha256=z5j2IMwf4MURuROKeqNXW1WvOSj91UdJa7dLRqN_OFc,7370
118
117
  ultralytics/models/fastsam/utils.py,sha256=dCSm6l5yua_PTT5aNvyOvn1Q0h42Ta_NovO7sTbsBxM,715
119
118
  ultralytics/models/fastsam/val.py,sha256=ILKmw3U8FYmmQsO9wk9-bJ9Pyp_ZthJM36b61L75s3Y,1967
120
119
  ultralytics/models/nas/__init__.py,sha256=d6-WTrYLXvbPs58ebA0-583ODi-VyzXc-t4aGIDQK6M,179
@@ -128,15 +127,26 @@ ultralytics/models/rtdetr/train.py,sha256=20AFYVW9NPxw0-cp-sRdIovWidFL0IIhJRv2oZ
128
127
  ultralytics/models/rtdetr/val.py,sha256=4QQArdaGEY8rJsJuvyJ032f8GGVGdV2jURHK2EdMxyk,5566
129
128
  ultralytics/models/sam/__init__.py,sha256=9A1iyfPN_ncqq3TMExe_-uPoARjEX3psoHEI1xMG2VE,144
130
129
  ultralytics/models/sam/amg.py,sha256=He2c4nIoZ__F_pL18rRl278R8iBjWXBM2Z_vxfuVOkk,7971
131
- ultralytics/models/sam/build.py,sha256=-i-vj0egQ2idBZUf3Xf-H89QeToM3ky0HTxKP_KEXTs,4944
132
- ultralytics/models/sam/model.py,sha256=dkEhqJEZFuSoKubMaAjUx1U9Np49AII3nBScdH8rMBI,4707
133
- ultralytics/models/sam/predict.py,sha256=hachjdcJ175v_oOUPmu_jG_VSe2wCbpLpi4qymUJV34,23575
130
+ ultralytics/models/sam/build.py,sha256=BSpRgDIQb-kgxaQtSq0C7Zb2UsqkfkFRmErC_bzKYIg,4954
131
+ ultralytics/models/sam/model.py,sha256=MVO7WqF41Sq1-qbsN8O8Fophe8anYVY67yp17Sudp0k,4979
132
+ ultralytics/models/sam/predict.py,sha256=GoR8xCwt3VJdBX5wUUhJ-3qY87LoG-R1eG8SziTDLP0,23755
134
133
  ultralytics/models/sam/modules/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
135
- ultralytics/models/sam/modules/decoders.py,sha256=7NWnBNupxGYvH0S1N0R6NBHxdVFRUrrnL9EqAw09J4E,7816
136
- ultralytics/models/sam/modules/encoders.py,sha256=pRNZHzt2J2xD_D0Btu8pk4DcItfr6dRr9rcRfxoZZhU,24746
137
- ultralytics/models/sam/modules/sam.py,sha256=zC4l4kcrIQD_ekczjl2l6dgaABqqjROZxQ-FDb-itt0,2783
134
+ ultralytics/models/sam/modules/decoders.py,sha256=SkVdfsFwy8g4rOJYXi2rWg2zI5HEttsQJi6E4Uwxs9o,6307
135
+ ultralytics/models/sam/modules/encoders.py,sha256=JHot5dRyr_d3wAzz7jgc_SOWOWibWKRWOt-IGBXPhW8,24894
136
+ ultralytics/models/sam/modules/sam.py,sha256=lyB-edOBr85gACTaVqG0WiSIS4FyohTtLqkNMKDwVM0,2695
138
137
  ultralytics/models/sam/modules/tiny_encoder.py,sha256=rAY9JuyxUpFivFUUPVjK2aUYlsXEZ0JGKVoEWDGf0Eo,29228
139
- ultralytics/models/sam/modules/transformer.py,sha256=VINZMb4xkx4IHAbJdhCq2XLDvaFBMup7RGC16DLS7OY,11164
138
+ ultralytics/models/sam/modules/transformer.py,sha256=a2jsS_J76MvrIKIERb_0flliYFMjpBbwVL4UnsNnoyE,11232
139
+ ultralytics/models/sam2/__init__.py,sha256=_xqQHLZTLgEdK278YETYR-Fts2hsvXP5q9ddUbuuFvc,154
140
+ ultralytics/models/sam2/build.py,sha256=m6hv82VKn3Lct_7nztUqdzJzCV9Nbr5mvqpI8nkReQM,5422
141
+ ultralytics/models/sam2/model.py,sha256=PS-eV78DVNrGZmUq7L7gJHgrGjxnySM1TTHkwfrQM7E,3408
142
+ ultralytics/models/sam2/predict.py,sha256=gvKf6qcStFiT9SLzo8Ol25suIh-QRVcOcdbyeuM2ORw,8894
143
+ ultralytics/models/sam2/modules/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
144
+ ultralytics/models/sam2/modules/decoders.py,sha256=t4SR-0g3HQstk-agiapCsVYTMZBFc2vz24zfgBwZUkw,15376
145
+ ultralytics/models/sam2/modules/encoders.py,sha256=0VRK2wdl0vZzKA3528_j-Vyn4Iy8XlNHp2ftQRn-aGE,13313
146
+ ultralytics/models/sam2/modules/memory_attention.py,sha256=4zdvm8_ANM0r8QSN_xBGi9l-9Ugjt3gxBsHv2cHczjc,6214
147
+ ultralytics/models/sam2/modules/sam2.py,sha256=CgCBrfjhKDHI2n8iM6AIJmXeCEgf2_qUz7rzZT31fB0,44255
148
+ ultralytics/models/sam2/modules/sam2_blocks.py,sha256=7HmuZTFw8VVdAVDsIStWByxyUHBqytnfgvQMaCNr1GU,28379
149
+ ultralytics/models/sam2/modules/utils.py,sha256=2H5C3sjBnYoPuoJqflH3AmGeBJoKrhHea136jgwIq_I,8320
140
150
  ultralytics/models/utils/__init__.py,sha256=mHtJuK4hwF8cuV-VHDc7tp6u6D1gHz2Z7JI8grmQDTs,42
141
151
  ultralytics/models/utils/loss.py,sha256=PmlKDe4xQTiYkPSCdNUabxJC7bh43zGxiKVIxsXBVGE,15135
142
152
  ultralytics/models/utils/ops.py,sha256=sAeD_koytXDzHibIvQLLAx3vOpGdhdAiQhMiNFUnn5U,13255
@@ -173,7 +183,7 @@ ultralytics/nn/modules/activation.py,sha256=RS0DRDm9r56tojN79X8UBVtiktde9Wasw7GI
173
183
  ultralytics/nn/modules/block.py,sha256=jLXQerl4nXfr4MEGMp9S3YgdTqOJzas1GBxryyXyLV0,34582
174
184
  ultralytics/nn/modules/conv.py,sha256=Ywe87IhuaS22mR2JJ9xjnW8Sb-m7WTjxuqIxV_Dv8lI,12722
175
185
  ultralytics/nn/modules/head.py,sha256=vlp3rMa54kjiuPqP32_RdgOb9KrHItiJx0ih1SFzQec,26853
176
- ultralytics/nn/modules/transformer.py,sha256=AxD9uURpCl-EqvXe3DiG6JW-pBzB16G-AahLdZ7yayo,17909
186
+ ultralytics/nn/modules/transformer.py,sha256=8ux2-0ObrafMTYCLucLLVmqk9XWz74bwmWtJGDmgF6Q,18028
177
187
  ultralytics/nn/modules/utils.py,sha256=779QnnKp9v8jv251ESduTXJ0ol8HkIOLbGQWwEGQjhU,3196
178
188
  ultralytics/solutions/__init__.py,sha256=O_G9jh34NnFsHKSA8zcJH0CHtg1Q01JEiRWGwX3vGJY,631
179
189
  ultralytics/solutions/ai_gym.py,sha256=KQdx0RP9t9y1MqYMVlYUSn09SVJSUwKvgxPri_DhczM,4721
@@ -205,11 +215,11 @@ ultralytics/utils/files.py,sha256=TVfY0Wi5IsUc4YdsDzC0dAg-jAP5exYvwqB3VmXhDLY,67
205
215
  ultralytics/utils/instance.py,sha256=5daM5nkxBv9hr5QzyII8zmuFj24hHuNtcr4EMCHAtpY,15654
206
216
  ultralytics/utils/loss.py,sha256=mDHGmF-gjggAUVhI1dkCm7TtfZHCwz25XKm4M2xJKLs,33916
207
217
  ultralytics/utils/metrics.py,sha256=UXMhBnTtMcpTANxmQqcYkVnj8NeAt39gZez0g6jbrW0,53786
208
- ultralytics/utils/ops.py,sha256=CQeMDVV4f9QWvYPNvNJu7GJAW2-XG93D7ee7yFY0vsI,32688
218
+ ultralytics/utils/ops.py,sha256=WJHyjyTH8xl5bRkBX0JB3K1sHAGONHx_joubUewE0A8,32709
209
219
  ultralytics/utils/patches.py,sha256=Oo3DkP7MbXnNGvPfoFSocAkVvaPh9kwMT_9RQUfjVhI,3594
210
220
  ultralytics/utils/plotting.py,sha256=5HRfiG2dklWZJheTxGTy0gFRk39utHcZbMJl7j2hnMI,55522
211
221
  ultralytics/utils/tal.py,sha256=hia39MhWPFpDWOTAXC_5vz-9cUdiRHZs-UcTnxD4Dlo,16112
212
- ultralytics/utils/torch_utils.py,sha256=ClXfUpTKFkwD3Zfnjk9YnK0gsA-7YmvEasTDiVN9Wvw,28880
222
+ ultralytics/utils/torch_utils.py,sha256=oQx_wywbx8ATOQ0qdKzCmw3iztRCK4ogUSp5W1qSrGc,28975
213
223
  ultralytics/utils/triton.py,sha256=gg1finxno_tY2Ge9PMhmu7PI9wvoFZoiicdT4Bhqv3w,3936
214
224
  ultralytics/utils/tuner.py,sha256=49KAadKZsUeCpwIm5Sn0grb0RPcMNI8vHGLwroDEJNI,6171
215
225
  ultralytics/utils/callbacks/__init__.py,sha256=YrWqC3BVVaTLob4iCPR6I36mUxIUOpPJW7B_LjT78Qw,214
@@ -223,9 +233,9 @@ ultralytics/utils/callbacks/neptune.py,sha256=5Z3ua5YBTUS56FH8VQKQG1aaIo9fH8GEyz
223
233
  ultralytics/utils/callbacks/raytune.py,sha256=ODVYzy-CoM4Uge0zjkh3Hnh9nF2M0vhDrSenXnvcizw,705
224
234
  ultralytics/utils/callbacks/tensorboard.py,sha256=QEgOVhUqY9akOs5TJIwz1Rvn6l32xWLpOxlwEyWF0B8,4136
225
235
  ultralytics/utils/callbacks/wb.py,sha256=9-fjQIdLjr3b73DTE3rHO171KvbH1VweJ-bmbv-rqTw,6747
226
- ultralytics-8.2.68.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
227
- ultralytics-8.2.68.dist-info/METADATA,sha256=Sbvvwn9ey5INu9Iqb5yZz8KtyC4zc56D7ItK9LW1TJ0,41337
228
- ultralytics-8.2.68.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
229
- ultralytics-8.2.68.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
230
- ultralytics-8.2.68.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
231
- ultralytics-8.2.68.dist-info/RECORD,,
236
+ ultralytics-8.2.70.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
237
+ ultralytics-8.2.70.dist-info/METADATA,sha256=iFuejsEFhTo3f9kraOP7gc1ZS1i8VvfY1DBr2RCLbwA,41337
238
+ ultralytics-8.2.70.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
239
+ ultralytics-8.2.70.dist-info/entry_points.txt,sha256=YM_wiKyTe9yRrsEfqvYolNO5ngwfoL4-NwgKzc8_7sI,93
240
+ ultralytics-8.2.70.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
241
+ ultralytics-8.2.70.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.1.0)
2
+ Generator: setuptools (72.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5