摘要:
视觉项目的预算大头常常不是模型,而是标注。SAM2 让"点一下就出掩膜"可以跑在边缘设备上:一张图只编码一次,之后每次提示只需几毫秒解码。本文覆盖 SAM2 结构、数据整理、微调训练、ONNX/BModel 转换,以及在土星云 SE110S-WA32、SE110S-WB16 上的部署实测与平台侧落地做法。
一、标注成本才是真正的瓶颈
视觉项目里 GPU 能买到、模型能开源,唯独标注买不到规模:一万个实例按每实例一分钟描边,就是一百六十多个工时,还没算返工;更麻烦的是十个标注员有十种边界习惯。
SAM2 的思路是"提示即接口":给一个点或一个框,直接吐出像素级掩膜。标注员的动作从"沿边界描一圈"变成"点一下、看一眼、改一笔"。决定这条路能否落地的,是它能不能跑在离数据最近的边缘设备上。
二、SAM2 的基础知识
2.1 三段式结构
图像编码器。 主干是 Hiera,分层视觉 Transformer,用 MAE 方式预训练。它把 1024×1024 输入压成 1/16 分辨率、256 通道的 embedding,即 64×64×256。这一步最重,也最值得缓存。
提示编码器。 点被编码成"位置编码 + 正负标签嵌入",框被拆成两个角点,掩膜提示走卷积下采样。负点是最好用的设计之一:掩膜多切了一块不用重画,点一个负点让它排除。
掩膜解码器。 轻量 two-way transformer,让提示 token 与图像特征做双向注意力,再上采样两次 4 倍,输出 3 个候选掩膜和各自的 IoU 预测分数。为什么是 3 个?提示本身有歧义,多候选加 IoU 头让平台可以"取分数最高"或"三个都留着让人挑"。

图 1 SAM2 的两段式推理与编码器复用
2.2 记忆机制
视频版加了两个模块:memory encoder 把当前帧的掩膜和特征写进记忆库,memory attention 让当前帧去"看"历史帧;object pointer 区分"同一物体的新位置"和"新出现的物体"。于是视频分割变成传播:第一帧给提示,后面每帧自动延续。平台上一段视频只标第一帧、后续帧当草稿即可,但视频时延比图像高一个数量级。
2.3 三条和自动标注直接相关的性质
零样本可用。 训练数据是 SA-1B 的 1100 万张图像、11 亿个掩膜,以及 SA-V 的约 5 万段视频、60 多万个 masklet,日常场景里的目标基本不用训练就能给出可用掩膜。
提示可以自动生成。 既然框能当提示,一个跑通的检测模型就能当提示生成器:检测给类别,分割给边界,这是目前最稳的自动标注架构。
编解码天然可拆。 这一点决定了边缘部署的形态,也是本文所有性能数字的由来。
三、应用场景
- 遥感与航拍解译。 建筑物、地块、水体、船只的实例掩膜是变化检测和面积统计的基础,航拍图分辨率高、人工描边慢,收益最直接。
- 工业质检。 划痕、气泡、异物形状不规则,需要像素级区域;产线数据自带工位信息,提示点可固定生成,最适合批量预标注。
- 医学与显微影像。 细胞与病灶轮廓标注专业性强、成本高,这类域外数据零样本会打折,需要少量精标微调。
- 电商、自动驾驶与安防。 商品抠图、人像分割、可行驶区域、人车包裹掩膜,量大且单张价值低,适合一键批量。
共同点是数据私密、带宽有限、标注量大,把提示分割放在边缘设备上,原始素材不出场,这正是 SE110S 的定位。
四、数据收集与整理
4.1 采集
按业务定义采,而不是按"能拿到什么"采。同一场景至少覆盖三个时段、两种天气,避免模型把光照当成类别特征。视频按 1fps 抽帧,相邻帧用 pHash 去重,否则同一秒的近邻帧会灌满训练集。
4.2 清洗与切片
先删模糊、过曝、严重遮挡和重复帧。SAM2 输入固定 1024×1024,大图切 1024、重叠 128,同步裁剪标注;被切掉超过三分之一的目标丢弃,只露边角的打截断标记。小于 8~10 像素的目标不要放进分割集。
4.3 冷启动标注与规范
自动化标注不等于零人工。正确顺序是先精标 300~500 张,把类别边界和掩膜规范定死,再让模型照着做。
规范要写清楚:边界含不含阴影和反光;目标内部孔洞留不留(车窗算不算孔洞);两个物体重叠时被遮挡部分归谁;截断目标按可见部分还是补全。这几条不定清楚,自动生成的掩膜再准也没法用。每批抽 10% 交叉复核。
4.4 划分与增强
必须按场景、日期、设备划分,不能把同一段视频的相邻切片随机分到训练集和验证集,否则指标虚高、换场景就崩。推荐 70%/15%/15%。
增强以几何变换为主:缩放、旋转、翻转、裁剪,掩膜跟着一起变。若要微调 SAM2,增强不能破坏目标的可提示性------把目标裁到只剩一条边,提示就失效了。

图 2 从数据到自动标注的完整链路
五、训练与微调
先问要不要训。 SAM2 的价值很大程度来自零样本能力。只有当业务域离自然图像很远------医学切片、显微图像、红外、工业缺陷------才值得微调;多数项目第一步应该拿 100 张业务图跑零样本。
微调哪一部分。 推荐冻结 image encoder,只训 prompt encoder 和 mask decoder:编码器占大部分参数,冻结它既省显存又避免过拟合,编码器 bmodel 也不用重编。数据量 500~5000 张,学习率 1e-5~1e-4,batch 4~8,10~30 个 epoch。
提示怎么采样。 训练提示必须和推理提示同分布:线上用"检测框 + 一个正点",训练时就用 GT 掩膜的框和质心点做提示,再加几个随机负点。只用完整 GT 框训练,线上遇到偏移的检测框就会掉得很厉害。
看什么指标。 别只盯 mIoU 均值,更有业务意义的是 mIoU 大于 0.75 的实例占比,它决定标注员要动手改几次。
六、模型转换:PyTorch → ONNX → BModel
6.1 拆分与导出
设备端只接受静态 shape 的模型,而 SAM2 原始实现带着不少动态逻辑,所以第一步是把模型拆成可独立推理的子图:图像模式拆 image encoder 与 image decoder 两个;视频模式再拆出 memory attention 和 memory encoder,共四个。
导出时固定 batch=1、opset 17,有两处必须改:一是把 encoder 里的位置编码拆成常量文件(例程对应 pos.npz、maskmem_pos_enc.npz),由主机侧注入;二是 memory attention 里的矩阵乘要改写(例程文件名中的 nomatmul 即为此)。这两处不动,编译会报算子不支持或精度对不上。
导出后用 onnxruntime 跑同一张图与 PyTorch 逐像素比对,重点看掩膜面积、候选排序和边界有无整体偏移。
6.2 编译与量化
BModel 在 x86 Linux 上用 TPU-MLIR 编译,流程是 ONNX → MLIR → 校准/量化 → BModel。以 WA32(BM1684X)的编码器为例:
model_transform.py --model_name sam2_encoder \
--model_def sam2_encoder.onnx \
--input_shapes \[1,3,1024,1024] \
--mean 0,0,0 --scale 1.0 \
--pixel_format rgb --mlir sam2_encoder.mlir
run_calibration.py sam2_encoder.mlir \
--dataset cali_1024 --input_num 200 -o sam2_encoder_cali
model_deploy.py --mlir sam2_encoder.mlir \
--quantize INT8 --chip bm1684x \
--calibration_table sam2_encoder_cali \
--model sam2_encoder_int8_1b.bmodel
WB16(BM1688)把 --chip 换成 bm1688 并加 --num_core 2,同一份 ONNX 可分别产出 1core 与 2core。归一化放在前处理就传 0 和 1,放进模型就必须与训练侧一致------两边不一致是精度掉点最常见的原因。
6.3 校准与精度对齐
校准集建议 100~300 张,按设备端同样的预处理生成,覆盖不同光照并保留难样本。官方例程的 COCO 结果很说明问题:在 SE 系列设备上 FP32、FP16、INT8 三档的 mIoU 都是 0.44,量化几乎没有损失。原因是分割输出是一张概率图,量化误差被阈值化和后处理吸收了,这是分割模型相对检测模型在量化上的天然优势。
0.44 也要正确理解:它用 COCO 目标框中心点做单点提示,掩膜质量被提示质量限制,例程说明也提到测试图像越多该指标越高。所以它是"单点提示 + 无后处理"的保守下限,交互式标注里给的是框和多点,可用比例会明显更高。
七、部署到 SE110S-WA32 与 SE110S-WB16
7.1 规格与选型
|-------------|----------|-----------------------------|--------|-----------------------|--------------------|
| 设备 | 计算平台 | 整机算力 | 内存 | 视频解码 | 编码器选型 |
| SE110S-WA32 | BM1684X | 32 TOPS@INT8,16 TFLOPS@FP16 | 16GB | 32 路 1080p25 | INT8 1b 优先,FP16 兜底 |
| SE110S-WB16 | BM1688 | 16 TOPS@INT8 | 8GB | 1080p@480fps,16 路智能分析 | INT8 2core |
两款都是无风扇导冷、20W / 15W 典型功耗、DC12V、Ubuntu,可以直接放进没有空调的弱电间。WA32 算力与内存余量更大,适合切片和多实例重活;WB16 更适合固定工位、少路数场景。
7.2 部署链路
推荐链路:图像源 → 硬件解码 → resize 到 1024 → SAIL 推理 → 掩膜后处理 → 多边形化 → 标注服务。例程用 Python + OpenCV + SAIL 跑通,生产环境建议换成 C++ + BMCV。
单点提示
python3 python/sam2_image_opencv.py --img_path datasets/images/truck.jpg \
--points '\[500, 375]' --label 1 \
--encoder_bmodel models/BM1684X/image_encoder/sam2_encoder_int8_1b.bmodel \
--decoder_bmodel models/BM1684X/image_decoder/sam2_decoder_int8_1b.bmodel
框提示
python3 python/sam2_image_opencv.py --img_path datasets/images/truck.jpg \
--points '\[900, 300, 350, 350]' --label 1 \
--encoder_bmodel models/BM1684X/image_encoder/sam2_encoder_int8_1b.bmodel \
--decoder_bmodel models/BM1684X/image_decoder/sam2_decoder_int8_1b.bmodel
7.3 性能实测
先看 bmrt_test 的纯算子时延,单位毫秒,已折算为单张图片:
|-------------|-----------------------|------------------------|
| 设备 | 模型 | calculate time(ms) |
| SE110S-WA32 | encoder INT8 1b | 69.10 |
| SE110S-WA32 | encoder FP16 1b | 100.25 |
| SE110S-WA32 | decoder INT8 1b | 3.22 |
| SE110S-WA32 | decoder FP16 1b | 4.28 |
| SE110S-WB16 | encoder INT8 1b 2core | 131.86 |
| SE110S-WB16 | encoder INT8 1b 1core | 186.33 |
| SE110S-WB16 | encoder FP16 1b 2core | 225.64 |
| SE110S-WB16 | decoder INT8 1b 2core | 5.11 |
| SE110S-WB16 | decoder FP16 1b 2core | 8.73 |
再看程序级耗时,即例程跑 truck.jpg 单图时统计的预处理、编码、解码、后处理时间:
|-----------------|---------|-------------|-------------|---------|--------|
| 设备与精度 | 预处理 | encoder | decoder | 后处理 | 合计 |
| WA32 INT8 | 68.27 | 115.02 | 14.62 | 1.18 | 199.09 |
| WA32 FP16 | 69.86 | 149.04 | 20.79 | 1.54 | 241.23 |
| WA32 FP32 | 74.79 | 847.89 | 40.83 | 1.61 | 965.12 |
| WB16 INT8 2core | 88.34 | 188.08 | 19.73 | 1.35 | 297.50 |
| WB16 FP16 2core | 100.79 | 311.52 | 34.60 | 1.11 | 448.02 |
注意 3.22 毫秒与 14.62 毫秒的差别:前者是纯算子时间,后者含数据搬运、SAIL 调度和 Python 开销。容量规划要用程序级数据,只看 bmrt_test 会高估整机能力。
换算成标注平台产能,按每张图 20 个实例(编码器 1 次 + 解码器 20 次):
|-----------------|-----------|-----------|------------|
| 设备与精度 | 单图耗时 | 单实例均摊 | 理论吞吐 |
| WA32 INT8 | 476.9 ms | 23.8 ms | 7,549 张/小时 |
| WA32 FP16 | 636.2 ms | 31.8 ms | 5,658 张/小时 |
| WB16 INT8 2core | 672.4 ms | 33.6 ms | 5,354 张/小时 |
| WB16 FP16 2core | 1105.4 ms | 55.3 ms | 3,257 张/小时 |
单实例均摊二三十毫秒,这是自动标注在经济上成立的根本;交互体验更好------改第二个、第三个实例时编码器结果已在缓存,每次提示只需再跑一次解码,WA32 是 14.62 毫秒,WB16 是 19.73 毫秒。

图 3 单图 20 实例的耗时拆解与理论吞吐
视频模式要单独说。四个 bmodel 的时延相加,WA32 约 875.6 毫秒/帧(约 1.14 FPS),WB16 约 2894.5 毫秒/帧(约 0.35 FPS),适合离线批量预标注而不是实时跟踪。
7.4 两个容易踩的坑
分辨率影响解码时间。 原图越大,掩膜上采样和阈值化开销越高,平台侧应先把长边限制在 2000 像素左右;掩膜 logits 阈值则放在平台侧配置,不要为改阈值重编 bmodel。
前后处理必须同源。 训练、导出、设备端共用同一份 resize、归一化和掩膜处理代码;三处各写一套,量化后掩膜边界会整体偏移几个像素,批量导出成数据集才会被发现。
八、平台侧的自动化标注怎么实现
8.1 单图交互式预标注
标注员打开一张图,操作只有三种:点正点、点负点、拉框。每次操作先查缓存,命中只跑解码器,未命中才跑一次编码器。
默认交互推荐"检测框 + 正点"。图 5 展示了真实差别:单点提示只切到整车面积约 3.7% 的局部,框提示和双正点却能一次拿到完整实例。所以平台先给检测框,标注员补一两个点修正,比纯点选快得多。修正必须即时生效------点下负点瞬间重新解码刷新掩膜,WA32 上是 14.62 毫秒。
8.2 批量预标注
批量模式的提示由检测模型生成:检测框作框提示,框中心作正点提示,两者都跑取 IoU 分数更高的候选。
按图片维度并行。 同一张图的所有提示共用一个编码器结果,天然适合放进一个任务单元;按实例维度调度会让编码器被反复调用。
提示质量决定一切。 检测框偏 20 个像素,掩膜就多带一圈背景;检测召回率比精度更重要,漏检的最后还要人工补,框略大可以用负点修回来。
8.3 掩膜后处理与多边形化
模型输出的是概率图,要变成能进数据集的标注,中间要做二值化清理(保留最大连通域、填孔洞、形态学去毛刺)、多边形化、去重和导出。
多边形化。 轮廓提取加多边形逼近。以图 4 为例,一个 58.7 万像素实例的外轮廓原始有 2752 个点,取周长 0.4% 作为 ε 后简化成 33 个顶点,审核时几乎看不出与原掩膜的差异。
去重与导出。 两个实例 IoU 超过 0.85 就合并或交人工裁决;一份标注同时导出 COCO polygon、YOLO-seg、LabelMe 与平台内部格式,避免每个下游各写转换脚本。

图 4 掩膜到多边形的后处理与平台实例面板
8.4 质量控制与人机协同
质控不靠抽查,靠规则前置加审核后置。规则前置是把明显不可用的结果挡在人工审核之前:面积小于图幅万分之二、长宽比异常、顶点数超上限、掩膜触边界却标成完整实例,直接退回或标记待修。
审核后置是让审核员只判断通过、修改、删除:平台按"检测置信度 × 掩膜 IoU 分数"排序,队列先出低分实例。每次负点修正、每个被拖动的顶点都是高价值样本,攒够一批就能做一轮增量微调。
九、效果展示与成本核算
9.1 实测输出
图 5 是官方 Python 例程在 SE110S 系列设备上的真实输出:同一张 1800×1200 测试图,三种提示方式的表现。掩膜边界贴合车身,车窗、阴影等干扰区域被正确排除。

图 5 设备端真实输出:原图与三种提示的掩膜结果
图 4 把框提示结果做完了后处理:轮廓点从 2752 个简化到 33 个顶点,可直接写进标注文件。
9.2 成本对比
下表是实际项目试标的经验估算,不含平台开发成本,仅比较单张图(约 20 个实例)的标注工时:
|--------|------------|---------------------|
| 环节 | 纯人工 | SAM2 预标注 + 人工审核 |
| 逐实例描边 | 8~15 秒/实例 | 0.3~0.5 秒/实例(提示解码) |
| 边界修正 | 含在上面 | 2~4 秒/实例 |
| 类别与属性 | 2 秒/实例 | 1~2 秒/实例 |
| 单张合计 | 3~5 分钟 | 40~70 秒 |
| 一致性 | 依赖标注员 | 同一提示下结果确定 |
按这个量级,人工工时下降 60%~75%。算力侧开销可以忽略:WA32 单张图 476.9 毫秒,一天跑一万张也只占用不到一个半小时。
真正要提前规划的是隐性成本:提示生成用的检测模型要单独维护,质检规则要持续迭代,审核队列的分发策略直接影响收益。
十、总结
把 SAM2 接进标注平台,本质是一次分工选择:让模型做像素级边界,让人做判断和兜底。
推进顺序建议:官方例程跑通单图提示 → 300~500 张业务图验证零样本可用性 → 决定是否微调 decoder → 接入检测框作为提示源 → 补齐掩膜后处理、多边形化和质检规则 → 批量预标注与修正回流。
设备选型上,WA32 的 INT8 配置单图 476.9 毫秒、理论吞吐约 7500 张/小时,适合做主力标注算力;WB16 的 INT8 双核配置单图 672.4 毫秒、约 5350 张/小时,适合放在数据现场就近预标注。两者都靠编码器复用把交互延迟压到 20 毫秒以内,这是标注员愿意用的前提。