Ultralytics SAM 模型接口全解析:统一 Segment Anything(SAM / SAM2 / SAM3)家族的 Python API 参考
2026/9/8 16:52:51 网站建设 项目流程

Ultralytics SAM 模型接口全解析:统一 Segment Anything(SAM / SAM2 / SAM3)家族的 Python API 参考

【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics

本篇文章基于 Ultralytics 仓库中 docs/en/reference/models/sam/model.md 所对应的 API 参考页,以 ultralytics/models/sam/model.py 中的SAM类为主线,系统讲解它在推理、加载、任务调度上的接口设计、默认行为与底层实现。读完你不仅能熟练使用from ultralytics import SAM完成框选、点选、负点提示等 promptable 分割,还能理解该类如何通过一个入口同时兼容 SAM、SAM 2 与 SAM 3 三类权重,并掌握其背后的 Predictor 推理流水线。

一、ultralytics.models.sam.model模块定位

在 Ultralytics 的代码树中,models/sam/目录专门承载 Segment Anything 系列模型的封装与推理逻辑,其中 ultralytics/models/sam/model.py 是最上层的模型接口文件,定义了向用户暴露的SAM类;同目录的 predict.py 实现底层预测器,build.py 负责按权重构建具体网络结构,build_sam3.py 负责构建 SAM 3 交互模型。模块导出集中在 ultralytics/models/sam/init.py,对外提供SAMPredictorSAM2PredictorSAM2VideoPredictorSAM2DynamicInteractivePredictorSAM3Predictor等符号;同时顶层包 ultralytics/init.py 将SAMYOLOFastSAMRTDETR等并列导出,因此日常使用只需:

from ultralytics import SAM

根据类注释(model.py),SAM类是面向"实时图像分割任务"的接口类,设计目标是promptable segmentation(可提示分割):支持以边界框、点、标签等作为提示来产生目标掩码,并具备zero-shot(零样本)迁移能力——它由基于 SA-1B 数据集的 Segment Anything 项目发展而来,可适应未见过的图像分布与任务。它沿用了标准的 Ultralytics 引擎接口(.predict().info()task等),但仅用于推理task固定为"segment"),不支持训练、验证与导出。

二、单一入口兼容三代模型:构造函数与权重加载

SAM继承自引擎基类Model(见 ultralytics/engine/model.py),构造签名非常简单:

def __init__(self, model: str = "sam_b.pt") -> None:

默认权重为sam_b.pt。构造函数内部依次做了三件事(model.py):

  1. 扩展名校验:要求权重文件后缀必须是.pt.pth,否则抛出NotImplementedError("SAM prediction requires pre-trained *.pt or *.pth model.")。这与 YOLO 等可端到端训练/导出的任务不同——SAM 只接受预训练检查点。
  2. 版本探测:依据文件名stem是否包含"sam2"/"sam3"设置布尔标志self.is_sam2self.is_sam3。例如sam2_b.ptis_sam2=Truesam3_l.ptis_sam3=True,而sam_b.pt两者皆 False。
  3. task="segment"调用父类初始化,使该模型归入实例分割任务体系。

_load:不同代际权重的构建分派

真正的网络加载发生在_load()(model.py):

if self.is_sam3: from .build_sam3 import build_interactive_sam3 self.model = build_interactive_sam3(weights) else: from .build import build_sam # slow import self.model = build_sam(weights)

可见 SAM 3 权重走 build_sam3.py 中的build_interactive_sam3,而 SAM 1 / SAM 2 / MobileSAM 等统一走 build.py 的build_sam。其中 import 被刻意做成局部延迟导入,以加快包的整体加载速度。

支持的预定义权重

build.py 中的sam_model_map给出了所有内置可识别的权重名及其构建函数,既包括官方 SAM 系列,也覆盖 Meta 的 SAM 2 / SAM 2.1 检查点:

家族预定义权重名备注
SAM 1(Meta 原始 SAM)sam_h.ptsam_l.ptsam_b.ptViT-H/L/B 主干
MobileSAMmobile_sam.pt轻量化的移动端变体
SAM 2sam2_t.ptsam2_s.ptsam2_b.ptsam2_l.ptTiny/Small/Base/Large
SAM 2.1sam2.1_t.ptsam2.1_s.ptsam2.1_b.ptsam2.1_l.pt复用 SAM 2 的构建函数

若传入的权重名不在此映射内,build_sam会抛出FileNotFoundError并列出可用模型。你也可以传入自定义.pt/.pth文件的路径,只要后缀合法即可,例如SAM("path/to/custom_checkpoint.pt")

注意:尽管sam_model_map支持sam_h.ptmobile_sam.pt等,官方文档 docs/en/models/sam.md 中"可用模型"表格仅正式列出sam_b.ptsam_l.pt两个权重,均只支持 Inference(✅),训练、验证、导出为 ❌。MobileSAM 的完整介绍见 docs/en/models/mobile-sam.md。

三、推理入口:predict__call__

SAM.predict()是整个接口的核心(model.py):

def predict(self, source, stream: bool = False, bboxes=None, points=None, labels=None, **kwargs):

参数含义:

  • source:图像或视频路径,也可以是PIL.Imagenp.ndarray
  • stream:为True时开启实时流式处理。
  • bboxes:用于"框提示"的边界框坐标列表,格式为 XYXY。
  • points:用于"点提示"的坐标列表,格式为像素坐标。
  • labels:点提示对应的标签列表;1表示前景(要分割的目标),0表示背景(排除区域)
  • **kwargs:透传给底层预测器的其它参数。

SAM.__call__(model.py)是predict的别名,因此model(...)model.predict(...)等价。

默认覆盖参数(override)

predict内部,方法先构造一组默认 override,再与用户传入的kwargs合并(用户值优先),这是理解 SAM 行为的关键:

overrides = {"conf": 0.25, "task": "segment", "mode": "predict", "imgsz": 1024} kwargs = {**overrides, **kwargs, "retina_masks": True} prompts = {"bboxes": bboxes, "points": points, "labels": labels} return super().predict(source, stream, prompts=prompts, **kwargs)
默认项含义
conf0.25掩码质量分数过滤阈值
tasksegment分割任务
modepredict推理模式(SAM 不支持训练/导出)
imgsz1024输入边长(仅支持正方形)
retina_masksTrue(强制)保留原始分辨率掩码而非下采样掩码

也就是说,提示词bboxes/points/labels并不作为普通 kwargs 直接下传,而是统一打包成prompts字典交给引擎,再由引擎路由到对应预测器的prompt_inference流程。bboxespointslabels之外,底层预测器同样支持masks作为"掩码提示"(用于基于上一轮输出的细化迭代),见 predict.py。

典型调用示例

以仓库自带的示例图 ultralytics/assets/zidane.jpg 为例(与 docs/en/models/sam.md 一致):

from ultralytics import SAM # 加载模型(默认 sam_b.pt,也可显式指定权重) model = SAM("sam_b.pt") # 打印模型结构信息(可选) model.info() # ① 边界框提示:一次框选一个目标 results = model("ultralytics/assets/zidane.jpg", bboxes=[439, 437, 524, 709]) # ② 单点提示:labels=[1] 表示该点是前景 results = model(points=[900, 370], labels=[1]) # ③ 多点提示:同一对象给出多个正点,增强鲁棒性 results = model(points=[[400, 370], [900, 370]], labels=[1, 1]) # ④ 单对象多提示的嵌套写法(注意三层括号) results = model(points=[[[400, 370], [900, 370]]], labels=[[1, 1]]) # ⑤ 负点提示:一个正点 + 一个负点,排除误分区域 results = model(points=[[[400, 370], [900, 370]]], labels=[[1, 0]])

bboxespointsmasks提示全部为空时,预测器会自动切换为"Segment Everything"(全图自动分割)模式(见 predict.py),即对整张图像做无提示的密集掩码生成:

# 全图分割:不给任何提示 model("path/to/image.jpg")

对应的 CLI 用法为:

yolo predict model=sam_b.pt source=path/to/image.jpg

所有返回的results都是标准 Results 对象,可直接访问results[0].masks获取掩码、results[0].boxes获取框(SAM 不产出类别,框中的cls仅为对齐 Ultralytics 结果格式的占位符,注释见 predict.py)。

四、task_map:如何自动选择正确的 Predictor

task_map是只读属性(model.py),返回"segment"任务对应的预测器类,其分派完全由构造时探测到的is_sam2/is_sam3标志决定:

return { "segment": {"predictor": SAM2Predictor if self.is_sam2 else SAM3Predictor if self.is_sam3 else Predictor} }

也就是说,同一个SAM类在加载不同权重后会自动装配不同代际的预测器

权重家族is_sam2is_sam3实际使用的 Predictor
sam_b.pt/sam_l.pt/mobile_sam.ptFalseFalsePredictor(predict.py)
sam2_t.pt/sam2_b.pt/sam2.1_*TrueFalseSAM2Predictor(predict.py)
sam3_*FalseTrueSAM3Predictor

预测器家族的类定义位于 predict.py(该文件被 docs/en/reference/models/sam/predict.md 文档化),并随 ultralytics/models/sam/init.py 对外暴露。SAM 2 系列还额外提供面向视频流的分割跟踪器SAM2VideoPredictor与支持运行中动态追加提示的SAM2DynamicInteractivePredictor,它们的行为在 docs/en/models/sam-2.md 中有完整示例。

五、info():模型结构信息

info()(model.py)委托给工具函数model_info

def info(self, detailed: bool = False, verbose: bool = True): return model_info(self.model, detailed=detailed, verbose=verbose)
  • detailed=True会输出各层/运算的详细信息;返回的元组内含模型字符串表示,info[0]即概要信息。
  • 该函数来自 ultralytics/utils/torch_utils.py,与 YOLO 系列共用同一套参数统计逻辑。

六、源码纵深:SAM背后的推理流水线

要从"会调用"进阶到"懂原理",需要理解SAM类如何对接 predict.py 中的Predictor。以下几点最能体现 SAM 与 YOLO 推理的根本差异:

1. 一次性编码 + 多轮提示

提示型分割的核心优化是图像只编码一次、可反复施加提示Predictor提供set_image()/reset_image()(predict.py):set_image预处理图像并经get_im_features调用self.model.image_encoder(im)缓存特征到self.features;此后每次仅用轻量的 prompt encoder + mask decoder 产出新掩码,无需重跑图像编码器。因此更高效的交互写法是:

import cv2 from ultralytics.models.sam import Predictor as SAMPredictor overrides = {"conf": 0.25, "task": "segment", "mode": "predict", "imgsz": 1024, "model": "mobile_sam.pt"} predictor = SAMPredictor(overrides=overrides) # 设置图像:既支持文件路径,也支持 cv2 读入的 BGR ndarray predictor.set_image("ultralytics/assets/zidane.jpg") # 同一张图反复施加不同提示 results = predictor(bboxes=[439, 437, 524, 709]) # 框提示 results = predictor(points=[900, 370], labels=[1]) # 单点 results = predictor(points=[[[400, 370], [900, 370]]], labels=[[1, 0]]) # 正+负点 predictor.reset_image() # 清空图像与缓存特征

Predictor.__init__中固定batch: 1并把retina_masks置 True;pre_transform使用LetterBox填充为正方形(auto=False, center=False),且断言只支持单图、不支持批处理(predict.py)。

2. 三段式网络结构

prompt_inference(predict.py)完整呈现了 SAM 的"图像编码器 + 提示编码器 + 掩码解码器"三段式推理:先取缓存特征,经_prepare_prompts把像素坐标的框/点按 letterbox 缩放比映射到 1024×1024 特征空间(并自动把缺省labels置为全1,即默认视为正点),随后调用self.model.prompt_encoder(...)生成 sparse/dense 嵌入,最后self.model.mask_decoder(...)输出掩码与质量分数。multimask_output为 True 时每个提示会返回多个候选掩码以消解歧义。SAM 2 的SAM2Predictor则改用model.forward_image+sam_prompt_encoder+sam_mask_decoder,并把 box 提示折叠进 point 序列(附加[2, 3]标签),同时维护多尺度高层特征high_res_feats(predict.py)。

3. 全图分割的参数面

generate()(predict.py)支撑"Segment Everything",它按参数网格采样点、逐批推理、裁剪区域投票并做 NMS 去重。常用可调参数包括:

参数默认值含义
points_stride32图像每边采样点的间隔(越小点越密)
points_batch_size64每批处理的提示点数
conf_thres0.88掩码质量分数过滤阈值
stability_score_thresh0.95掩码稳定性分数阈值
crop_n_layers0是否在图像裁剪块上额外预测(>0 提升细节)
crop_nms_thresh0.7裁剪块之间去重的 IoU 阈值

例如希望更细粒度地全图分割,可调用predictor(source="ultralytics/assets/zidane.jpg", crop_n_layers=1, points_stride=64)。完整签名见 predict.py。

4. 输入预处理与归一化

setup_model(predict.py)中 SAM 使用 ImageNet 风格均方差做归一化(mean=[123.675, 116.28, 103.53]std=[58.395, 57.12, 57.375]),与通用检测模型不同;同时设置model.stride = 32model.format = "sam",并提示channels_last=True不被支持。SAM 的imgsz只接受正方形,且推理 dtype 默认 float16(由self.model.fp16决定)。

七、与任务型分割模型的选型差异

值得强调的是,SAM 是一类通用提示分割基础模型,与"闭集实例分割"的 YOLO-seg 定位不同,二者并非替代关系:

  • 提示驱动 / 零样本:SAM 可通过框、点、掩码提示分割任意未见过的对象类别,适合交互式标注、目标提案、边缘检测、图文掩码(text-to-mask)等下游任务;而 YOLO11/YOLO26 的-seg系列在固定类别上速度与体积优势明显。
  • 能力边界:在 Ultralytics 框架中,SAM 权重只支持预测推理;而 YOLO 分割模型支持训练、验证、导出与部署。官方在 docs/en/models/sam.md 中给出了 SAM-b 与各代 YOLO-seg 在体积、参数量与 CPU 耗时上的对比参考,供选型时查阅。
  • 自动标注:SAM 常被用于"检测模型出框、SAM 出掩码"的自动标注流水线,即auto_annotate工具(见 ultralytics/data/annotator.py),可快速把检测数据扩成实例分割训练集:
from ultralytics.data.annotator import auto_annotate auto_annotate(data="path/to/images", det_model="yolo26x.pt", sam_model="sam_b.pt")

八、小结与导航

SAM类以极小的 API 面(构造、predict/__call__infotask_map)屏蔽了 SAM / SAM 2 / SAM 3 在网络构建与推理细节上的差异:构造函数根据文件名后缀自动探测is_sam2/is_sam3_load据此分派到build_sambuild_interactive_sam3task_map再据此装配Predictor/SAM2Predictor/SAM3Predictor。理解这套分派机制,是排查自定义权重兼容性与扩展新预测器时的关键。

若需继续深入,可在本仓库中对照阅读:

  • 类与接口实现:ultralytics/models/sam/model.py
  • 底层预测器实现与Predictor/generate全量参数:ultralytics/models/sam/predict.py、docs/en/reference/models/sam/predict.md
  • 权重注册表与网络构建:ultralytics/models/sam/build.py、ultralytics/models/sam/build_sam3.py
  • 模型使用教程与能力对比:docs/en/models/sam.md、docs/en/models/sam-2.md、docs/en/models/sam-3.md
  • 任务定义与 Results 对象:docs/en/tasks/segment.md、docs/en/modes/predict.md

【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询