从零跑通SAM2:环境配置、权重下载与图像视频分割实践
简介面向计算机视觉研究与工程应用的SAM2图像分割项目完整跑通包压缩包命名为segment-anything-2.zip。项目基于Segment Anything Model 2实现像素级实例分割适合科研人员、算法工程师及自动驾驶、医学影像等场景开发者快速接入。整个包共297个文件约344.72MB包含预训练模型权重pt、Python脚本py、Jupyter示例ipynb、YAML配置文件、Markdown说明文档以及大量测试图片jpg并附有环境配置文档与CUDA自定义算子源码便于从零搭建运行环境。目前已有3588人学习下载。使用者可获得一套开箱即用的分割工具链既可通过image_predictor与video_predictor示例完成单图/视频分割推理也可利用自动掩码生成与SA-V可视化示例进行批量分割和效果展示配套的README与配置说明覆盖依赖安装、模型调用和常见问题能显著缩短从模型部署到实际项目落地的周期。1. SAM2到底比第一代强在哪为什么值得跑1.1 一张图和一段视频的统一分割第一代SAM把给一个点或一个框就能把目标从图里抠出来这件事做到了相当夸张的零样本水平图像分割社区里几乎人手一个。但它的硬伤也很明确只能处理单张图片。视频场景想用它只能逐帧调用又慢又傻物体被遮挡再出现时基本就断片了。SAM2解决的正是这个问题。它用一个模型同时支持图像和视频图像场景里点、框、掩码都可以当提示视频场景里在第一帧或中间的任意一帧打一次提示目标就能沿着帧一路传播下去。注意这里不是逐帧重算是真的把前一帧的目标特征带到了后续帧里。这对广告牌跟踪、运动目标分割、医学影像序列这类场景来说体验是质的飞跃。1.2 架构升级Hiera编码器 记忆注意力精度提升之外SAM2的两处架构改动值得专门说一下。第一图像编码器从第一代的ViT换成了Hiera一个多尺度分层视觉Transformer。它把特征分成多个分辨率层级来提取官方说法是精度和速度之间做了更好的折中。我实际跑下来单帧处理速度比SAM的ViT-H快不少这在视频传播场景里非常关键。第二新增了记忆注意力和记忆库。后续帧解码时不仅看当前帧还会从记忆库里参考历史帧的目标特征所以目标短暂被遮挡、出画再入画模型都更容易接回来。1.3 官方仓库和跑通版本有什么区别很多人拿到手的是一份 segment-anything-2.zip 而不是GitHub上最新的仓库。这两者通常没有本质差别zip版本一般是作者把代码和依赖锁定在一个验证过的commit上目的就是让你少踩上游版本漂移的坑。我的建议是以zip里的代码为准权重和配置用配套的那一套不要随手替换成最新代码否则很容易撞上后面要说的兼容性问题。2. 跑通前的环境准备真的没那么玄2.1 硬件底线别用8G显存硬刚large模型SAM2有四个主要规格tiny、small、base_plus、large。这里直接给一张实测参考表针对单张1024分辨率图像、float16推理估算模型规格权重大小对应配置文件推理推荐显存sam2.1_hiera_tiny约155MBsam2.1_hiera_t.yaml4GB以上sam2.1_hiera_small约287MBsam2.1_hiera_s.yaml6GB以上sam2.1_hiera_base_plus约321MBsam2.1_hiera_b.yaml8GB以上sam2.1_hiera_large约838MBsam2.1_hiera_l.yaml12GB以上视频分割因为要保存多帧记忆显存需求再往上加一档更稳妥。纯CPU也能跑通但一张图几十秒起步只适合验证逻辑。如果你只有8G显存建议直接选tiny或small别硬上large。2.2 依赖安装顺序很重要跑通SAM2的依赖不算多但安装顺序容易翻车。我的建议步骤建Python 3.10虚拟环境conda或venv都行装PyTorch版本要和本机CUDA驱动对应一般选CUDA 11.8或12.1的轮子再进入项目目录执行pip install -e . 装项目本体装完先import一下确认没有报错。为什么要先装PyTorch再装项目因为pip install -e . 在解析依赖时如果检测到已有合适的torch就不会强行从默认源拉一份CPU版本。很多人折腾半天最后发现torch装成了CPU版模型直接慢到怀疑人生。2.3 权重文件去哪下权重下载是新手第一个崩溃点。官方仓库里提供了download_ckpts.sh脚本会把几个ckpt都拉下来。国内网络如果从HuggingFace下载困难直接去魔搭社区搜SAM2有现成的权重镜像速度稳定得多。下载完务必记住sam2.1系列的权重必须配configs/sam2.1/目录下的yaml老版sam2权重配configs/sam2/目录下的配置。混用必出事具体症状在第4节细说。3. 从clone到出图完整跑通流程3.1 安装项目本体git clone https://github.com/facebookresearch/segment-anything-2.git cd segment-anything-2 conda create -n sam2 python3.10 -y conda activate sam2 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 pip install -e .如果你的网络clone比较慢也可以直接用分享的zip包流程一样只是少了clone这一步。装完先验证一下导入python -c from sam2.build_sam import build_sam2; print(sam2 import ok)这一步能过说明基础环境没问题。要是卡在这里多半是torch版本和项目依赖冲突先把torch卸了按官方源重装。3.2 权重放好并验证加载把下载好的ckpt文件放到项目根目录下的checkpoints文件夹保持这样的结构segment-anything-2/ ├── checkpoints/ │ └── sam2.1_hiera_large.ckpt ├── configs/ │ └── sam2.1/ │ └── sam2.1_hiera_l.yaml ├── sam2/ └── ...然后单独验证一下模型能不能加载from sam2.build_sam import build_sam2 model_cfg configs/sam2.1/sam2.1_hiera_l.yaml checkpoint checkpoints/sam2.1_hiera_large.ckpt model build_sam2(model_cfg, checkpoint, devicecuda) print(load ok)这一步是整个项目最关键的地基。能过说明环境和权重都没问题过不了90%是路径写错10%是权重和配置版本不匹配。3.3 写一个图像分割最小脚本这是全文核心部分。下面这个脚本是我实际在跑的最小可用版本直接保存成文件就能出分割结果import numpy as np import torch from PIL import Image from sam2.build_sam import build_sam2 from sam2.sam2_image_predictor import SAM2ImagePredictor CHECKPOINT checkpoints/sam2.1_hiera_large.ckpt CONFIG configs/sam2.1/sam2.1_hiera_l.yaml DEVICE cuda if torch.cuda.is_available() else cpu sam2_model build_sam2(CONFIG, CHECKPOINT, deviceDEVICE) predictor SAM2ImagePredictor(sam2_model) image np.array(Image.open(demo.jpg).convert(RGB)) predictor.set_image(image) # 在目标上点一个点label1表示正样本 input_point np.array([[320, 240]]) input_label np.array([1]) masks, scores, _ predictor.predict( point_coordsinput_point, point_labelsinput_label, multimask_outputTrue, ) # 取最高分的掩码保存 best_idx int(np.argmax(scores)) mask masks[best_idx].astype(np.uint8) * 255 Image.fromarray(mask).save(mask.png) print(score:, scores[best_idx])这里有两个细节新手容易忽略。第一multimask_outputTrue时SAM2会对一个提示点返回三个候选掩码因为一个点本身就存在歧义——是点在上半身还是下半身模型不知道。三个候选对应从精细到粗犷的不同假设scores是模型自己的置信度但最高分不一定是你想要的那个建议三个都可视化出来人工选。第二set_image会做一次完整的图像编码如果同一张图要反复改提示点测试只需要set_image一次后面predict都复用编码结果速度会快很多。这也是在线交互工具能保持流畅的关键。3.4 用框提示和视频分割验证进阶能力点提示之外框提示也常用。传入numpy数组格式是[x1, y1, x2, y2]input_box np.array([[150, 100, 450, 400]]) masks, scores, _ predictor.predict( point_coordsNone, point_labelsNone, boxinput_box, multimask_outputFalse, )框提示比点提示更稳因为它直接划定了目标范围。实际项目里我经常用检测器出框再让SAM2细化边缘这个组合后面细说。视频分割是SAM2的重头戏代码逻辑大致是这样的from sam2.sam2_video_predictor import SAM2VideoPredictor video_predictor SAM2VideoPredictor(build_sam2(CONFIG, CHECKPOINT, deviceDEVICE)) state video_predictor.init_state(video_pathtest.mp4) video_predictor.add_new_points_or_box( inference_statestate, frame_idx0, obj_id1, boxnp.array([[200, 150, 500, 450]]), ) for frame_idx, object_ids, video_segments in video_predictor.propagate_in_video(state): print(frame, frame_idx, objects, object_ids)不同小版本的API可能有细微差异以你手上代码仓库里的示例为准。原理是一样的先初始化视频状态再在某一帧加提示最后逐帧传播。视频分割建议用small以上模型tiny虽然快遇到本文还有配套的精品资源点击获取