基于 SAM2 的视觉自动标注平台:从数据整理、微调训练到土星云 SE110S 系列边缘部署

摘要:

视觉项目的预算大头常常不是模型,而是标注。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 毫秒以内,这是标注员愿意用的前提。

相关推荐
土星云SaturnCloud4 小时前
基于 YOLOv26-OBB 的无人机视角路面汽车检测:从数据整理到 SE110S 系列边缘部署
边缘计算·车辆检测·yolo26-obb·无人机视觉
AiNightVision6 小时前
电力巡检夜视方案选型指南——无人机/机器人/固定监测三种场景怎么选
人工智能·科技·车载系统·机器人·无人机·边缘计算·视频
陕西亿鑫鸿物联技术有限公司8 小时前
异构视频流统一汇聚架构实战:基于GB/T 28181与边缘计算的安防改造
边缘计算·视频汇聚·智慧矿山·流媒体技术·gb/t 28181
XMAIPC_Robot1 天前
-40~85℃宽温实测:RK3588 机器人控制器硬件底座,长时间 SLAM 定位稳定性验证
人工智能·fpga开发·机器人·边缘计算·arm+fpga·rk3588+fpga
陕西亿鑫鸿物联技术有限公司1 天前
传统安防利旧升级实战:如何基于边缘计算接入海康大华IPC构建AI分析系统?
深度学习·计算机视觉·边缘计算·物联网架构·流媒体技术
桐盛科技1 天前
中央空调全链路管控:基于边缘计算的负荷预判与安全联锁实现
物联网·安全·能源·边缘计算
陕西亿鑫鸿物联技术有限公司1 天前
配电箱温度过高、漏电,系统能提前报警吗?聊聊电气火灾预警的底层架构与避坑
边缘计算·工业互联网·智慧消防·物联网架构·电气安全
ShiMetaPi2 天前
1828 工业检测方案详解:工业异常检测应用
边缘计算·rk3588·rk1820·rk1828
LittroInno3 天前
边缘AI模组选型:把视频带宽、压缩和推理吞吐分别算清
人工智能·音视频·边缘计算·视频编码·模组选型·视频带宽·tofu6