一句话理解整篇论文:
建立一个统一的 segmentation interface,让其他模型、用户以及不同任务都能够调用
SAM 的目标是:给模型任意一种 prompt,模型都尽可能输出一个合理的分割 mask;再依靠海量数据和这种promptable训练方式,让一个模型能够零样本迁移到很多不同分割任务。
论文围绕三个彼此关联的东西展开:Task、Model、Data。全文的三个核心问题:什么任务能支持 zero-shot generalization、模型应该如何设计、以及数据从哪里来。
1. 论文想解决什么问题?
传统 segmentation 通常是:Image → 特定任务的 segmentation
比如:semantic segmentation、instance segmentation、interactive segmentation:用户点击一个点,模型把对应物体分出来。
这些模型通常都是针对固定任务训练的。
SAM 希望把 segmentation 变成:Image + Prompt → Mask
prompt 可以是:
- foreground/background point;
- bounding box;
- 一个粗糙 mask;
- text;
- 更广义地说,任何能表达“我要分割什么”的信息。
论文把这个任务叫做:Promptable Segmentation,也就是“可提示分割”。
2. 为什么要专门定义一个 Promptable Segmentation Task?
思路其实是从 NLP foundation model 来的。LLM 有一个非常统一的任务:next-token prediction,模型通过一个统一的训练目标学会了很多能力,然后推理时只需要改变 prompt,就能完成:翻译、问答、摘要、分类、写代码……
SAM 想找一个 segmentation 对应的“统一任务”。于是提出:
给我任意 segmentation prompt,我都输出一个valid mask。
这里的valid mask和以往不同。这个 prompt 本身是 ambiguous 的,SAM 并不要求:必须猜中用户唯一真正想要的东西。而是要求:至少输出一个合理的 segmentation。
比如你在一个人的衣服上点一个点:这个点可能表示:shirt,也可能表示:person,甚至可能表示更小的衣服局部。如果 prompt 有歧义,输出只要对应其中一个合理对象,就算 valid。
3. SAM 模型结构
SAM 本身的核心就三个模块:Image Encoder + Prompt Encoder + Mask Decoder
整体流程可以理解为:
然后:
最后:
3.1 Image Encoder
图像首先经过一个大型 ViT 得到 image embedding:
Image Encoder(MAE-pretrained ViT,主要版本最终用了 ViT-H) 是 SAM 中最重的部分。
重要设计:
一张图片只需要跑一次 Image Encoder。
论文明确强调,image encoder 每张图只运行一次,得到 image embedding 后缓存下来。随后不同 prompts 都可以复用 image embedding。这就是为什么 SAM 能用于交互式分割。
3.2 Prompt Encoder
SAM 把 prompt 分成两类:
Sparse Prompt
包括:point / box / text(少量token / vector)
point 和 box 主要用:Positional Encoding + Learned Prompt Embedding 来编码。
如:(x,y),先告诉模型点在哪里,再通过 learned embedding 告诉模型:这是 foreground point 还是 background point。
Dense Prompt
主要就是:mask(空间feature map)
mask 通过 convolution 得到一个 dense embedding,然后和 image embedding 相加。
3.3 Mask Decoder
prompt 真正和 image 发生交互的地方。
Mask Decoder 的输入有:(image embedding)、
(prompt embedding),以及几个特殊的 output tokens,然后通过一个很轻量的 Transformer decoder。
其中有:prompt → image的cross-attention,同时还有:image → prompt 的cross-attention,也就是一种双向信息交互。
经过两个 decoder blocks 后,对 image embedding 上采样,然后通过 output token 动态生成一个线性 classifier:
然后对每个位置计算:,得到每个像素属于 foreground 的概率。
其实和之前看的很多:
的 segmentation-VLM 工作已经有一点思想上的联系了。
4. SAM 怎么解决 prompt ambiguity?
刚才那个例子:一个点落在人衣服上。可能是shirt,也可能是person
如果模型只输出一个 mask,很容易把几个可能的 mask“平均”起来。所以 SAM 直接一个 prompt 输出多个 masks,默认输出3个候选 mask。
为什么是 3?
作者认为很多歧义大致对应:
例如:
三个 mask 往往已经足够覆盖常见层级。
同时每个 mask 会预测一个:estimated IoU score,用它进行排序。
所以 SAM 实际输出的是:,而不只是单个 mask。
5. SAM 的训练方式
SAM 的训练不是简单: Image + GT Mask → Mask,而是模拟用户不断交互。
针对一个 ground-truth mask:先随机生成一个 prompt:(例如一个 foreground point)。
模型预测:,然后根据错误区域再产生:
,继续预测。
不断模拟:
论文训练时对一个 mask 会模拟11 rounds的 prompting。
Loss 则主要是:
所以从训练角度看,SAM 学的是:
面对各种不同形式、不同精确程度的 prompt,我都应该能够恢复一个合理 mask。
6. 为什么 SAM 能叫“Segment Anything”?
其实最关键的不完全是 architecture。真正让它产生强泛化能力的是:Data Scale
LLM 的训练数据网上到处都是 text,CLIP 的训练数据也可以从网页获得:(image, text)
但是网上不存在:(image, pixel-level mask) 这种 web-scale 数据。
所以 Meta 自己设计了一个 Data Engine
7. Data Engine:论文真正重要的另一部分
data engine 有三个阶段:Manual → Semi-Automatic → Fully Automatic
第一阶段:Assisted-manual
一开始 SAM 还比较弱。标注员点击 foreground/background point:Human Prompt → SAM → Mask,人再修正。
然后:new masks → retrain SAM,SAM 变强以后,标注速度也越来越快。
最后第一阶段获得约:4.3M masks,来自约:120K images。
第二阶段:Semi-automatic
这时候SAM已经不错了,先自动把容易的物体分出来。
例如:person、car、large object,这些比较显著的物体自动产生 mask。
然后标注员主要负责找模型没分出来的东西。
这样做的目的不是单纯提高数量,而是:增加 mask diversity,尤其是小目标、不显眼目标、unusual objects。
这一阶段最终累计到:10.2M masks。
第三阶段:Fully Automatic
到这里 SAM 已经足够强,所以作者开始:完全自动生成 mask
在图片上均匀打:的 point grid(1024个point prompts)。
每个点:,然后做几层过滤:
① predicted IoU
留下 confidence 高的 mask。
② stability
稍微改变 mask threshold:和
如果两个 mask 差别很小:
③ NMS
去掉大量重复 mask。
④ multi-scale crop
为了发现小目标,对 image crop 放大以后再跑 SAM。
这个流程最后在:11M images 上产生:1.1B masks。于是得到:SA-1B
8. SA-1B 有多大?
论文最终的数据集:11M images、1.1B masks,
平均:
而且最终 SA-1B 中:99.1% 的 masks 是自动生成的。
作者还人工检查了一部分自动 mask:
随机抽取约: 50K masks 然后让专业标注员修正。
结果:94% 的自动 mask 与人工修正 mask: IoU > 90%。
所以作者认为自动 annotation 的质量已经足够高。
9. 为什么它能做到 zero-shot?
SAM 没有固定 category taxonomy,它不需要预测:dog, cat, car, person
只学 这个 prompt 对应哪些 pixels?学到的是一种非常通用的:映射。因此测试时遇到没见过的数据分布,也可能继续工作。
作者在 23 个非常不同的 segmentation datasets 上进行 zero-shot single-point 测试,包括普通场景、ego-centric、underwater 等分布。
单点测试中,SAM 在 23 个数据集中的 16 个上 mIoU 高于强基线 RITM;如果从 SAM 输出的三个候选 mask 中 oracle 地选择最符合 GT 的一个,所有数据集上都超过 RITM。
10. 一个非常容易误解的问题:SAM 的 zero-shot 是什么?
SAM 的 zero-shot 和 LLM zero-shot QA 并不完全一样。
比如 object detector 输出 cat bounding box,把这个 box 给 SAM:
那么原本 SAM 从来没有专门训练 cat instance segmentation 这个任务。但通过 prompt composition 可以完成这个任务。
所以作者所谓 zero-shot 很大程度是:Promptable model + Prompt engineering 实现 downstream task transfer。
利用大规模训练中学到的通用视觉分割先验,再结合当前 prompt,对图像中的边界、纹理、形状、区域一致性等视觉信息进行分割。
SAM 本身并不主要负责“cat 是什么”这种高层语义判断。如:先由一个 cat detector 找到猫的 bounding box,再把这个 box 作为 prompt 给 SAM;SAM 负责把这个 box 对应的区域精细分割出来。论文明确把这种方式称为通过 prompt engineering 将一个 promptable segmentation model 组合到更大的系统里,从而完成新的 downstream task。
所以这里可以把两个模块分工成:
- detector:负责语义——“这里是猫”
- SAM:负责像素级定位——“这只猫具体覆盖哪些像素”
作者所说的zero-shot是指:如果已经有一个 cat bounding-box detector,那么可以把它输出的 box 作为 SAM 的 prompt,从而把cat detection转换成cat instance segmentation。
11. SAM 的 text prompt 能力其实没有后来大家想象得那么强
原始 SAM 论文里确实做了:text-to-mask,但只是 proof-of-concept。
作者没有大量 text-mask annotation。而是利用 CLIP 的:对齐。
训练时:作为 prompt。
推理时则:再给 SAM。
因为 CLIP image/text embedding 已经在一个共同 embedding space 中,因此可以这样“偷梁换柱”。
所以原始 SAM 的 text understanding 能力其实比较有限。
这也是后面很多 Grounded SAM、Grounding DINO + SAM、LISA、ReasonSeg、SAM2、segmentation VLM工作继续发展的原因。
12. SAM 的 limitation
- 很细的结构可能漏掉;
- 偶尔产生小的 disconnected artifact;
- boundary 不一定像专门做高精度 segmentation 的方法那么锐利;
- 输入很多 interactive points 时,专门的 interactive segmentation 方法可能比 SAM 更好;
- ViT-H image encoder 很重,所以完整 image encoding 并不是真正实时;
- text-to-mask 还只是探索性的;
- semantic segmentation / panoptic segmentation 不容易简单通过 prompt 直接实现。
所以它优化的目标不是:最高 segmentation IoU
而是:
13. 从研究角度看,这篇论文最重要的贡献是什么?
如果站在做 VLM + segmentation 的角度,我认为这篇论文最值得注意的,其实不是 ViT + prompt encoder + decoder 本身。
而是它把 segmentation 的研究范式改了一次。
以前:
比如:
SAM 变成:
推理阶段:
也就是说,它把研究问题从:
“怎么把某一个 segmentation benchmark 再提高 1 个点?”
转成:
“能不能建立一个统一的 segmentation interface,让其他模型、用户以及不同任务都能够调用?”
论文最后自己也是把贡献总结成三件事:
Task: Promptable Segmentation、Model: SAM、Data: SA-1B
14. 那为什么这和 CONVERSEG-NET 特别相关?
SAM 原本支持的 prompt 本质上比较“低层”:point、box、mask,甚至 text 也是比较初步的 proof-of-concept。
但是 CONVERSEG 想处理的是:
“the object that can be used to cut something”
或者:
“the object that would be dangerous to touch”
这种语言。
这时候问题变成:
SAM 本身已经是非常强的:prompt-to-mask interface,问题是:
怎么把 VLM 对复杂语言的理解,变成 SAM decoder 能利用的 prompt representation?
15.之前看到的 CONVERSEG-NET 可以这样映射
之前看的结构里:
Qwen 得到:
然后:
而:
再送入 SAM2 mask decoder。
这里实际上就是在重新实现 SAM 的 prompt interface。
原始 SAM:
CONVERSEG:
原始 SAM:
CONVERSEG:
也就是说:
而:
这就是二者最核心的关系。
16. 读 SAM 时真正要掌握到什么程度?
如果是为了继续看 CONVERSEG,把下面这条链彻底搞懂就够了:
然后:
接着:
最后:
然后再看 CONVERSEG,就会发现它真正做的事情可以压缩成一句话:用 VLM hidden states 替代传统的几何 prompt encoder 输入, 再继续复用 SAM/SAM2 的 dense segmentation 能力。
如果把整篇论文压缩成一张逻辑图,大概就是:
对现在的CONVERSEG / VLM segmentation / reasoning segmentation这些工作来说,SAM 可以看成非常重要的“前一代基础设施”:SAM 解决的是“如何根据一个相对明确的 prompt 得到 pixels”,而后面的 VLM segmentation 工作开始研究“如何先理解复杂语言、语义、关系甚至推理,再把这个理解转成 SAM 能够执行的 pixel grounding”。