11"""
2- SAMModelLoaderMEC – Load SAM2/SAM2.1/SAM3 (or original SAM) checkpoints.
2+ SAMModelLoaderMEC – Load SAM2.1 / SAM3 checkpoints.
33
44Supports:
5- - SAM2 / SAM2.1 via official sam2 package (pip install SAM-2)
6- - SAM3 via sam2 package (uses SAM2 infrastructure)
7- - Original SAM (vit_h/l/b) via segment_anything package
5+ - SAM 2.1 via official sam2 package (pip install SAM-2)
6+ - SAM 3 via sam2 package (uses SAM2 infrastructure)
87 - .safetensors / .pt / .pth checkpoint formats
98 - Optional CPU-offload to save VRAM
109 - Automatic model type detection from filename
1110 - Auto-download from HuggingFace Hub when model not found locally
11+
12+ NOTE: Legacy SAM 1 (vit_h/l/b) and the original SAM 2.0 line are no
13+ longer supported; only SAM 2.1 and SAM 3 are exposed.
1214"""
1315
1416import os
@@ -90,19 +92,18 @@ def restore_device(sam_wrapper):
9092
9193# ── Official SAM2 config mapping for build_sam2 ──────────────────────
9294# Keys match filename stems; values are config paths for the official
93- # sam2 package (pip install SAM-2).
95+ # sam2 package (pip install SAM-2). Only SAM 2.1 configs are exposed —
96+ # SAM 2.0 has been removed from the supported model set.
9497SAM2_CONFIGS = {
95- "sam2_hiera_tiny" : "configs/sam2/sam2_hiera_t.yaml" ,
96- "sam2_hiera_small" : "configs/sam2/sam2_hiera_s.yaml" ,
97- "sam2_hiera_base" : "configs/sam2/sam2_hiera_b+.yaml" ,
98- "sam2_hiera_large" : "configs/sam2/sam2_hiera_l.yaml" ,
9998 "sam2.1_hiera_tiny" : "configs/sam2.1/sam2.1_hiera_t.yaml" ,
10099 "sam2.1_hiera_small" : "configs/sam2.1/sam2.1_hiera_s.yaml" ,
101100 "sam2.1_hiera_base" : "configs/sam2.1/sam2.1_hiera_b+.yaml" ,
102101 "sam2.1_hiera_large" : "configs/sam2.1/sam2.1_hiera_l.yaml" ,
103102}
104103
105104# ── HuggingFace Hub auto-download registry ────────────────────────────
105+ # Only SAM 2.1 checkpoints are listed; SAM 2.0 and original SAM 1
106+ # (vit_h/l/b) have been retired.
106107_DOWNLOAD_REGISTRY = {
107108 "sam2.1_hiera_large.pt" : {
108109 "repo_id" : "facebook/sam2.1-hiera-large" ,
@@ -120,37 +121,6 @@ def restore_device(sam_wrapper):
120121 "repo_id" : "facebook/sam2.1-hiera-tiny" ,
121122 "filename" : "sam2.1_hiera_tiny.pt" ,
122123 },
123- "sam2_hiera_large.pt" : {
124- "repo_id" : "facebook/sam2-hiera-large" ,
125- "filename" : "sam2_hiera_large.pt" ,
126- },
127- "sam2_hiera_base_plus.pt" : {
128- "repo_id" : "facebook/sam2-hiera-base-plus" ,
129- "filename" : "sam2_hiera_base_plus.pt" ,
130- },
131- "sam2_hiera_small.pt" : {
132- "repo_id" : "facebook/sam2-hiera-small" ,
133- "filename" : "sam2_hiera_small.pt" ,
134- },
135- "sam2_hiera_tiny.pt" : {
136- "repo_id" : "facebook/sam2-hiera-tiny" ,
137- "filename" : "sam2_hiera_tiny.pt" ,
138- },
139- "sam_vit_h_4b8939.pth" : {
140- "repo_id" : "ybelkada/segment-anything" ,
141- "filename" : "checkpoints/sam_vit_h_4b8939.pth" ,
142- "subfolder" : "checkpoints" ,
143- },
144- "sam_vit_l_0b3195.pth" : {
145- "repo_id" : "ybelkada/segment-anything" ,
146- "filename" : "checkpoints/sam_vit_l_0b3195.pth" ,
147- "subfolder" : "checkpoints" ,
148- },
149- "sam_vit_b_01ec64.pth" : {
150- "repo_id" : "ybelkada/segment-anything" ,
151- "filename" : "checkpoints/sam_vit_b_01ec64.pth" ,
152- "subfolder" : "checkpoints" ,
153- },
154124}
155125
156126
@@ -166,9 +136,8 @@ def _detect_config(model_name):
166136 normalized_name = name .replace ("." , "" ).replace ("_" , "" )
167137 if normalized_key in normalized_name :
168138 return config
169- # Heuristic fallback
170- is_21 = "2.1" in name or "2_1" in name
171- prefix = "configs/sam2.1/sam2.1" if is_21 else "configs/sam2/sam2"
139+ # Heuristic fallback — SAM 2.1 is the only supported SAM2 variant.
140+ prefix = "configs/sam2.1/sam2.1"
172141 if "tiny" in name or "_t." in name :
173142 return f"{ prefix } _hiera_t.yaml"
174143 if "small" in name or "_s." in name :
@@ -180,17 +149,14 @@ def _detect_config(model_name):
180149
181150
182151class SAMModelLoaderMEC :
183- """Load a Segment Anything Model (SAM / SAM2 / SAM2 .1 / SAM3 ).
152+ """Load a Segment Anything Model (SAM 2 .1 or SAM 3 ).
184153
185154 Uses the official ``sam2`` Python package (pip install SAM-2) for
186- SAM2/2.1/SAM3 models. Falls back to ``segment_anything`` for
187- original SAM (ViT-H/L/B) .
155+ both architectures. Legacy SAM 1 (vit_h/l/b) and the original
156+ SAM 2.0 line are not supported .
188157 """
189158
190- SUPPORTED_TYPES = [
191- "auto" , "sam2" , "sam2.1" , "sam3" ,
192- "sam_vit_h" , "sam_vit_l" , "sam_vit_b" ,
193- ]
159+ SUPPORTED_TYPES = ["auto" , "sam2.1" , "sam3" ]
194160
195161 @classmethod
196162 def INPUT_TYPES (cls ):
@@ -225,9 +191,8 @@ def INPUT_TYPES(cls):
225191 "default" : "auto" ,
226192 "tooltip" : (
227193 "Model architecture. 'auto' detects from filename.\n "
228- "sam2/sam2.1: Segment Anything 2 (requires sam2 package)\n "
229- "sam3: SAM3 (uses SAM2 infrastructure)\n "
230- "sam_vit_*: Original SAM (requires segment_anything)"
194+ "sam2.1: Segment Anything 2.1 (requires sam2 package)\n "
195+ "sam3: SAM3 (uses SAM2 infrastructure)"
231196 ),
232197 }),
233198 "device" : (["auto" , "cuda" , "cpu" ], {"default" : "auto" }),
@@ -271,7 +236,7 @@ def _scan_extra_paths(cls, model_files):
271236 FUNCTION = "load"
272237 CATEGORY = "MaskEditControl/SAM"
273238 DESCRIPTION = (
274- "Load SAM/SAM2/SAM2.1/SAM3 model. "
239+ "Load SAM 2.1 or SAM 3 model. "
275240 "Auto-detects architecture from filename. "
276241 "Supports VRAM offload."
277242 )
@@ -295,15 +260,17 @@ def load(self, model_name: str, model_type: str, device: str,
295260 sam_model = None
296261 load_method = "unknown"
297262
298- if detected_type in ("sam2" , "sam2.1" , "sam3" ):
299- sam_model , load_method = self ._load_sam2_family (
300- model_path , clean_name , detected_type , torch_dtype , device , offload_to_cpu
301- )
302- else :
303- sam_model , load_method = self ._load_original_sam (
304- model_path , detected_type , torch_dtype , device , offload_to_cpu
263+ if detected_type not in ("sam2.1" , "sam3" ):
264+ raise ValueError (
265+ f"Unsupported SAM model_type '{ detected_type } '. "
266+ f"Only 'sam2.1' and 'sam3' are supported. "
267+ f"Legacy SAM 1 (vit_h/l/b) and SAM 2.0 have been removed."
305268 )
306269
270+ sam_model , load_method = self ._load_sam2_family (
271+ model_path , clean_name , detected_type , torch_dtype , device , offload_to_cpu
272+ )
273+
307274 if sam_model is None :
308275 sam_model , load_method = self ._load_generic_fallback (
309276 model_path , torch_dtype , device , offload_to_cpu
@@ -456,20 +423,14 @@ def _detect_type(model_name):
456423 return "sam3"
457424 if "sam2.1" in name or "sam2_1" in name :
458425 return "sam2.1"
459- if "sam2" in name :
460- return "sam2"
461- if "vit_h" in name :
462- return "sam_vit_h"
463- if "vit_l" in name :
464- return "sam_vit_l"
465- if "vit_b" in name :
466- return "sam_vit_b"
467- return "sam2"
468-
469- # ── SAM2 / SAM2.1 / SAM3 ─────────────────────────────────────────
426+ # Default everything else (including unlabelled checkpoints) to
427+ # SAM 2.1 — SAM 2.0 / SAM 1 are no longer supported.
428+ return "sam2.1"
429+
430+ # ── SAM 2.1 / SAM 3 ──────────────────────────────────────────────
470431 def _load_sam2_family (self , model_path , model_name , model_type ,
471432 torch_dtype , device , offload ):
472- """Load SAM2/ 2.1/SAM3 model using the official sam2 package.
433+ """Load SAM 2.1 / SAM 3 model using the official sam2 package.
473434
474435 Strategy:
475436 1. Load state_dict from any format (safetensors/pt/pth)
@@ -548,24 +509,6 @@ def _load_state_dict(model_path):
548509 sd = sd ["model" ]
549510 return sd
550511
551- # ── Original SAM ──────────────────────────────────────────────────
552- @staticmethod
553- def _load_original_sam (model_path , detected_type , torch_dtype , device , offload ):
554- try :
555- from segment_anything import sam_model_registry
556- arch_map = {"sam_vit_h" : "vit_h" , "sam_vit_l" : "vit_l" , "sam_vit_b" : "vit_b" }
557- arch = arch_map .get (detected_type , "vit_h" )
558- model = sam_model_registry [arch ](checkpoint = model_path )
559- model = model .to (torch_dtype )
560- if not offload :
561- model = model .to (device )
562- return model , "sam_registry"
563- except ImportError :
564- logger .debug ("[MEC] segment_anything not available" )
565- except Exception as e :
566- logger .debug (f"[MEC] Original SAM failed: { e } " )
567- return None , "failed"
568-
569512 # ── Generic fallback ──────────────────────────────────────────────
570513 @staticmethod
571514 def _load_generic_fallback (model_path , torch_dtype , device , offload ):
0 commit comments