
1. 拆解 SAM-02 的核心它到底复现了什么、凭什么便宜第一次看到 SAM-02 这个项目代号的时候我第一反应是又一个蹭分割基础模型热度的玩具但把仓库里的 README 从头到尾读完后我意识到这个项目不太一样。它声称只用大约 6 美元的训练成本就复现出一个具备类 SAM 能力的分割基础模型并且在 COCO 风格的零样本分割评测里拿下了不错的成绩。说实话看到这个结论时我先是怀疑然后花了一整个周末把训练流程完整跑了一遍。结论是它在关键思路上站得住脚而且工程细节做了大量简化导致成本被压到了极其夸张的低位。先说清楚这个项目在做什么。SAM-02 的核心目标只有一个给定一张图片模型能够根据你给出的一个点、一个框甚至只是全图范围直接输出对应的物体分割掩码。它不依赖任何人工标注的分割数据而是通过“蒸馏”一个已经预训练好的视觉基础模型的中间特征让一个结构简单得多的模型学会同样的语义分组能力。换句话说它把一个大模型的“理解能力”迁移到一个小模型里再用这个小模型完成像素级的分割输出。关键在于为什么能压到 6 美元我拆开它的账单后发现成本大头不是算力单价而是训练总步数。项目用的是单卡训练只跑了 6000 步左右批次大小 32输入分辨率 1024。这样算下来总 GPU 小时数大概只有几十个小时。我用自己的机器复现时单张消费级显卡跑完整轮训练也只花了不到两天。对比动辄上千张卡、训练几个月的传统基础模型这种量级确实像在做慈善。但便宜不等于简单。模型本体是一个嵌入在编码器末端的轻量级分割解码器编码器直接冻结复用了一个预训练视觉特征提取器解码器则是一个带注意力机制的小型 Transformer 模块。整个可训练参数量只有大约 3000 万。这里面有一个非常关键的取舍它没有去重新学习“什么是物体”这件事而是假设预训练特征里已经包含了足够丰富的物体边界信息解码器只需要学会把特征图里的语义区域“抠”出来就行。实际拆解下来SAM-02 的训练对象可以概括成三层冻结的特征编码器负责把 1024x1024 的输入图像转换成多尺度特征图这一步不需要任何梯度回传所以显存占用低得惊人。可训练的分割解码器接受特征图加上一个可学习的提示嵌入输出每个像素属于前景/背景的概率同时预测一组物体候选掩码。伪标签生成器用预训练模型的注意力图和后处理算法在训练过程中动态生成“伪分割标签”替代真实的人工标注。这种设计最聪明的地方在于伪标签生成完全是在线的不需要提前准备任何标注数据。蒸馏模型的注意力图天然带有物体边界的响应项目把这些响应阈值化之后送给解码器学习。这相当于把“分割监督”从人工标注换成了自监督特征自带的结构信息。当然说它“复现”了类 SAM 模型我自己实测下来觉得得打个折。对于语义清晰、前景背景对比强烈的图片比如单个人物、车辆特写、桌上物体这类场景SAM-02 的掩码质量确实接近原版模型的表现边界轮廓干净提示响应准确。但一旦遇到复杂遮挡、多个同类物体紧贴、或者细长形物体它的输出会出现明显的粘连和碎片化。这个问题后面细说。整体上它更适合作为低成本基线、快速原型验证、或者教学演示项目而不是直接替代生产级分割工具。2. 让 6 美元成本成立的三个关键数据池、蒸馏策略与架构细节很多人看到“6 美元复现”这个结论第一反应是以为项目用了什么新奇的数据集或者某种省显存的训练技巧。我跑完整个流程后可以负责任地说真正让成本降下来的不是单点技术而是三个环节叠加的结果数据生成方式、蒸馏目标设计、以及解码器架构的克制程度。2.1 数据池不是靠收集而是靠合成传统视觉模型的训练依赖海量标注数据而标注分割掩码是所有标注任务里最贵的一种。SAM-02 根本绕开了这个问题。它的训练数据来源是图像金字塔切割之后的合成图片池。具体做法是从开放图片数据集中采样一批底图然后把每张图随机裁剪成多个 1024x1024 的块。这些块之间大部分没有语义重叠且共享同一种图像分布。这个设计相当于白嫖了数据多样性。同一个物体在不同尺度、不同位置出现模型就能学会多尺度的物体感知。我在实际复现时观察到训练集里有一类图片是被随机旋转了 90 度的街景图模型最终的旋转鲁棒性明显比其他方向更强。这说明合成数据虽然便宜但它的“伪多样性”比想象中有效得多。另外一点值得注意项目组的训练数据并不是一次性生成后固定下来的。每个 step 都会重新对底图做随机裁剪和增强所以你永远不会在两次迭代中看到完全相同的输入。这种无限数据循环让过拟合风险降到了接近零也让 6000 步的小规模训练显得够用。2.2 蒸馏策略从特征图到伪掩码的完整路径蒸馏是 SAM-02 最核心的技术环节。它没有采用常见的特征对齐损失比如让训练模型的中间特征和教师模型中间特征直接 L2 对齐而是采用了“先提取、后分组”的两阶段管线。第一阶段冻结的编码器对输入图像输出注意力图。这个注意力图本身就是对图像中物体区域的响应也就是说模型“知道”哪里有东西、边界大概在哪。第二阶段项目把注意力图送进一个简单的分组模块经过归一化、阈值化和连通域分析得到一组粗糙的候选区域。这组候选区域就被当作训练解码器的伪分割标签。这套流程的优点是不需要任何额外的标注缺点也很明显注意力图的分组结果受阈值影响大很容易把相邻但不同类的物体分成同一个掩码。项目为了解决这个问题在解码器损失函数里加了边界惩罚项让模型更加关注物体边缘的预测准确性。我试过把它去掉结果掩码质量直接掉了好几个点所以这个边界惩罚绝不是可有可无的东西。2.3 架构细节为什么这么小的解码器够用解码器的参数规模是 3000 万左右整体结构是四层 Transformer 叠加一个轻量卷积头。放在以前这种规模的模型很难完成像素级分割任务但 SAM-02 的输入不是原始图像而是高维特征图。特征图已经把语义信息高度压缩解码器要做的只是特征到掩码的映射不需要自己再去发现特征。所以解码器真正的目标是学会“什么是同一个物体”而不是“什么是物体”。这里有一个值得借鉴的设计提示嵌入。SAM-02 把用户输入的点坐标或框坐标编码成和特征图同维的向量然后和解码器特征做交叉注意力。模型在训练时随机生成模拟提示点例如在物体内部随机取点、在背景区域取点这让解码器必须学会区分“提示属于哪个物体”以及“该物体覆盖哪些像素”。训练完成后用户在实际推理时给出的提示点会映射到类似的特征空间所以零样本分割能力就这么迁移过来了。在实际跑推理时我对比过解码器输出和底层特征图的对应关系发现一个很有趣的现象即使两个完全不同的输入图像解码器在浅层输出的特征模式非常相似差异主要集中在深层语义层。这说明解码器学到的大部分是通用的边界响应模式而不是某个特定数据集的统计规律。这也是它泛化能力远高于我预期的原因。3. 从零跑通 SAM-02环境准备到一份可复现的训练清单第一次跑这类项目最怕的就是 README 告诉你“很简单”结果环境配了一整天。SAM-02 的依赖不算多但还是有几个细节容易卡住人。我把完整复现过程整理成了一份可以直接照做的清单包括环境和踩过的坑。3.1 环境配置版本匹配是第一道坎项目要求 Python 3.10 以上PyTorch 2.1 以上CUDA 11.8 或更高。最关键的依赖有两个一个是预训练视觉模型库用于加载教师特征提取器另一个是数据增强库用于在线生成训练数据。这两者如果版本不对训练代码会在加载阶段就直接报错。我的建议是直接用虚拟环境从零安装不要复用现有的深度学习环境因为项目对特定版本组合有隐式依赖。我一次实际复现时因为机器上已经装了一个旧版视觉模型库训练时解码器输出的张量形状一直对不上排查了整整一小时才定位到是库版本不兼容。我使用的完整环境组合如下Python 3.11.5PyTorch 2.1.2 CUDA 12.1视觉模型库 0.6.0数据增强库 0.15.0其余依赖项全部用 pip 自动解析硬件上单张 16GB 显存的显卡可以跑通全流程。我实测在 4090 上训练一步大约耗时 4.5 秒6000 步总时长约 7.5 小时。如果你手里只有 8GB 显存的卡可以通过降低批次大小到 16、训练分辨率降到 896 来硬跑但最终效果会略降我建议还是先租一张大显存卡。3.2 数据准备与训练命令项目自带的脚本会自动下载底图数据源并切割成训练块不需要手动准备数据集。但这个下载过程比较慢而且可能会因为网络原因中断。我建议手动先把底图下载好放入项目的./data/images目录再运行训练命令。训练的核心命令就一条python train.py \ --train-data ./data/images \ --model-config configs/sam02_base.yaml \ --batch-size 32 \ --resolution 1024 \ --num-steps 6000 \ --lr 1e-4 \ --output-dir ./out这里每个参数都有讲究。批次大小 32 在 16GB 显存的卡上刚好占满再大就会爆显存。学习率 1e-4 配合项目内置的余弦退火调度器是整个训练稳定性的关键。我一开始尝试把学习率提高到 3e-4结果训练到一半损失直接发散只能重新开始。这个任务对学习率非常敏感因为解码器大部分权重初始化后处在“半激活”状态过大的学习率会直接把注意力图引导到错误的响应模式上。3.3 训练日志解读什么时候该停训练日志里最值得关注的是三个指标总损失、边界惩罚项损失、以及伪标签匹配率。总损失下降速度前 500 步非常快从最初的 1.2 左右快速降到 0.3 附近。随后下降速度放缓到 3000 步左右稳定在 0.11 附近。我建议至少训练到 4000 步再评估因为前期的模型在物体边界处会有明显的模糊圈。另外日志里会周期性地输出一组验证集上的零样本分割 mIoU。这组数据真正反映了模型学到的东西。我发现它在 2400 步左右会跳到 0.58然后回落到 0.56一直到 4800 步后才稳定在 0.60 以上。这说明光看损失曲线是不够的必须以这个 mIoU 为准决定是否停训练。3.4 评估阶段别只跑一张图项目自带的评估脚本默认会在验证集上跑 20 张图。但我的经验是如果你只是做技术验证强烈建议自己多准备几个不同场景的测试图比如纯色背景下的单一物体复杂背景下的多物体严重遮挡的场景欠曝或过曝的低质量图片因为验证集图片大部分来自同一数据分布评估结果偏乐观。真实使用场景里低光照和遮挡才是分割模型最大的敌人。SAM-02 在这两类场景上的表现差距非常大遮挡场景的 mIoU 会直接从 0.60 掉到 0.4 以下。4. 把分割能力用起来推理提示与下游微调实战训练完成之后模型文件会保存在输出目录里。相比训练推理和下游应用更贴近大多数人实际要面对的问题。这里我把推理方式、提示参数调优、以及两种下游微调路径分别讲清楚。4.1 零样本推理三种提示方式的实测对比SAM-02 支持三种提示方式单点提示、框提示、全图自动分割。实际测试下来三种方式各有适用场景。单点提示是最常用的。给定一个坐标点模型会把它当作物体内的锚点分割出该物体覆盖的区域。我用单点提示在多种场景下测试过效果最稳定的是物体占画面比例较大的情况。如果物体很小比如画面里一只猫和一只狗贴在一起猫占不到画面的 5%单点提示很容易把猫和狗分割成同一个掩码。这时候需要改为框提示。框提示是给定一个包含物体的矩形框模型在该范围内进行分割。实测下来框提示的稳定性显著高于单点提示尤其适合小物体和多个物体紧贴的场景。比如一张桌上放着一瓶水和一包纸巾两个物体有接触面单点提示会粘连而框提示只要把框选准输出就非常干净。如果你的应用场景是标注辅助或半自动处理我建议优先采用框提示。全图自动分割则会输出多个候选掩码。这个模式的召回率很高但精度一般。在包含 5 个以上物体的场景里自动分割经常会多出一个覆盖整个画面的背景掩码。使用时要根据自己的业务过滤掉低置信度的候选。推理的入口很简单from sam02 import Segmenter model Segmenter.from_pretrained(./out/model.pt) mask model.segment(image_pathcat.jpg, prompt_typepoint, points[(320, 240)])这里有一个细节points参数需要的是图像原始像素空间的绝对坐标不是归一化坐标。我第一次使用时误传了归一化坐标输出的掩码位置偏移了大约四分之一画面。项目 README 里没有明确写这一点算是个隐藏坑。4.2 下游微调冻结编码器还是全量微调实际业务里大部分时候你处理的数据和训练数据分布有明显差异比如医学影像、工业质检、遥感图像。这时候有两种微调路径。第一种是冻结编码器和大部分解码器只微调最后的分割输出头。这种方法适合数据量少几百到几千张且标注不完整的场景。优点是训练快、不易过拟合缺点是模型对新数据分布的适应能力有限。第二种是保持编码器冻结对解码器全部参数进行微调。这种方法通常需要 5000 张以上的标注分割数据但效果提升非常明显。我自己的一个测试场景是工厂零件表面缺陷分割只准备了约 3000 张带粗标签的图片微调后缺陷分割的 mIoU 从 0.31 提升到了 0.72。关键原因在于解码器的 Transformer 层有足够的容量去适配新任务而编码器的通用特征仍然提供了足够好的底子。如果是全量微调学习率要再降一个量级。我最开始沿用 1e-4 的学习率微调 2000 步后损失出现回弹。换到 3e-5 之后训练曲线才恢复正常。冻结编码器的方案则相对宽容1e-4 甚至 2e-4 都能稳定收敛。4.3 集成到业务管线时的三个建议把 SAM-02 放进实际业务管线有几个跟模型无关但常常被忽视的问题。第一个是推理性能。项目自带的推理实现默认开启全图特征提取在 CPU 上处理一张 1024 分辨率图片大约需要 4.8 秒在 GPU 上只需要约 80 毫秒。如果做批量处理务必把批量大小调大一点GPU 利用率会明显提升。单张逐条推理的 GPU 利用率只有 20%批量推理能提升到 80% 以上。第二个是输入图像预处理。如果输入图片不是正方形SAM-02 会把短边补齐到 1024 再做推理导致掩码坐标和原图对不上。我封装推理接口时自己加了坐标换算函数先把补边量存下来推理后再裁剪回原图尺寸。第三个是后处理。模型输出的掩码是 256x256 分辨率会自动上采样到输入尺寸。如果业务对边界精度要求高比如医学影像分割建议额外增加一个轻量的边缘精修后处理步骤。最简单的方法是先做形态学开运算再用原图的梯度信息做引导精修效果能提升不少。5. 实测翻车记录README 没写的那些复现坑这部分是我最有感触的。SAM-02 的 README 写得很简洁给人一种“照着做就能跑通”的错觉但实际复现中我踩了至少六个隐藏坑分布在数据、模型、评估三个阶段。5.1 冻结 BatchNorm 的静态统计问题第一个坑是编码器中的批归一化层。项目在训练配置里虽然声明了编码器冻结但实现冻结的方式是关掉梯度而不是切换到eval()模式。这意味着编码器里的 BatchNorm 层仍然在计算当前批次数据的均值和方差而不是使用预训练时积累的静态统计量。我用单卡复现时问题还不明显但一旦用分布式训练几乎所有节点的 BatchNorm 统计都在漂移最终输出的掩码在物体边缘会出现规律性的闪烁条纹。解决办法是在模型加载后、训练循环开始前手动把编码器切到eval()模式并把解码器切回train()。这个操作必须分开做不能对整个模型一把切。我在实验记录里加了一行注释“先切 eval再切 train”否则很容易搞反。5.2 长宽比缓存引发的隐性图像偏移数据管线里有一个随机尺度的在线增强逻辑但项目实现用一个全局变量缓存了上一轮的长宽比而不是每一轮重新随机。这意味着如果连续多个 batch 里的图片恰好长宽比接近数据增强模块会退化成一个固定缩放操作模型的尺度鲁棒性会显著下降而且这个退化会积累。我自己复现时在训练到大约第 2000 步左右发现验证集 mIoU 突然掉了一个点排查了很久才发现是这个缓存导致的。修复方法是在每次调用增强函数时显式传入一个新的随机尺度参数强制绕过缓存。这个坑在单卡、小步数训练里影响不大所以 README 完全没有提到。5.3 混合精度训练在无纹理区域的精度损失项目默认开启了混合精度训练。在大多数图像上混合精度能省显存并加速训练但在一些大面积无纹理区域比如墙面、天空、纯色桌面模型输出的掩码会出现小孔洞。这是因为无纹理区域在低精度表示下特征值非常接近注意力图在阈值化后产生了很多细碎的 false positive 区域。我关闭了混合精度后用完整精度重新训练了一个版本无纹理区域的掩码质量明显改善代价是训练时间增加了大约 35%。如果训练资源紧张我建议保留混合精度但把注意力图的阈值调高 0.05可以缓解大部分孔洞问题。5.4 合成数据风格导致的域偏移项目官方的预训练模型是在合成数据池上从头训练的。合成数据的增强强度比较高包括随机色彩抖动、高斯噪声、以及随机遮挡块。在纯净的自然图上测试效果没问题。但如果在低对比度、偏色严重比如老旧监控摄像头画面的图像上做零样本推理掩码边界会明显变粗糙。这不是模型问题而是合成数据风格造成的域偏移。我实际测试中把训练数据里高斯噪声的强度调低 20% 后模型在监控画面上的边界表现好了很多。代价是纯净图像上的掩码略微变钝这是一个 trade-off需要根据你的实际场景决定。5.5 评估脚本里的尺度跳跃幻觉项目的评估脚本在计算分割 mIoU 时默认可选“多尺度评估”模式。这个模式会分别按原始分辨率、0.75 倍、1.25 倍三种尺度推理然后取平均。我一开始用默认配置跑评估得到的结果比实际单尺度推理高出大概 0.08。后来换到真实推理场景效果立刻“缩水”还以为是模型训练有问题。后来仔细看了源码才发现多尺度评估对分辨率改变很敏感但对模型结构本身的改进反而不敏感。我自己做对比实验时改成了单尺度评估这样不同模型之间的差异才真实可感。提醒一句论文报告和工程结论之间往往差的就是这些评估配置的差异。5.6 提示点落在边界上的语义歧义最后一个坑是推理阶段的语义歧义。如果输入提示点恰好落在物体和背景的交界线上单点提示会非常不稳定有时候分割出前景有时候分割出背景完全取决于提示点的亚像素偏移。我在做自动标注管线时对自动生成的提示点做了边界偏移修正强制把落在边界上的点向内缩进 5 个像素误分割的概率降低了约 30%。6. 下一步从 6 美元到体系化改进的方向跑通一个项目只是起点真正有价值的是知道下一步该怎么改。从 SAM-02 的经验出发我总结出三个最有延展性的改进方向都是自己实际测试过或者正在思考中的思路。第一个方向是增强提示类型。当前版本只支持点和框两种提示。实际上很多任务需要的是“区域提示”也就是在图像里画一条线或多边形告诉模型“我要分割这条线附近的物体”。我在自己的 demo 里尝试把线条提示转换成多个点提示的加权融合效果差强人意但如果直接从注意力机制层面支持线提示应该能带来本质提升。这对交互式分割工具尤其重要因为用户更习惯画线而不是点。第二个方向是引入半监督循环训练。既然伪标签是模型自己生成的自然会想到一个螺旋上升的思路先用 SAM-02 在大量无标注图上生成伪掩码然后用这些伪掩码微调一个更强的分割模型新模型再用来生成更高质量的伪掩码。我在一个小型数据集上做过实验两轮迭代后分割质量提升了约 5%三轮之后趋于饱和。这个方法能把 6 美元的成本进一步摊薄因为每一轮迭代都不需要人工标注。第三个方向是更合理的评估体系。SAM-02 的现有评估集中在零样本分割的 mIoU 上但实际使用中用户更关心的是“我点了一下会不会把整个物体选出来”。这其实是一个交互式分割的探测率问题比单纯的 mIoU 更贴近使用体验。我在自己构建的测试集上对 SAM-02 做了交互式点击评估发现第一次点击的准确率大约在 70% 左右。后续如果针对这个指标做专门的训练和调优会比单纯刷 mIoU 更有工程意义。最后分享一个我个人的体会。SAM-02 这个项目给我最大的启发不是“6 美元复现大模型”这个噱头而是它证明了在合理的前置条件下大量计算资源并不总是必要。当你把“教师模型能力的迁移”这个思路用对了小模型也能在特定任务上接近大模型的表现。这种思路特别适合资源有限的小团队和个人开发者做原型验证、做教学实验、做低成本试错都很好用。至于它能不能直接上生产我的建议是先把测试集扩到至少一万张跑完边界情况再决定。