前 言
在《SAM2模型在土星云边缘计算设备上的部署实战(上)》中,我们深入解析了SAM2的核心架构、视频分割工作流以及其在工业、安防等领域的应用优势。得益于其编码器与解码器解耦的架构设计,SAM2具备了在边缘端落地的可行性。
本文作为下篇,将正式进入工程实操环节。我们将结合土星云边缘计算设备,详细介绍如何在BM1684X等国产NPU芯片上完成SAM2的工程化部署,并基于sophon-demo官方例程给出完整的图像与视频分割实战方案,同时分享性能优化与排错经验。
四、土星云边缘计算平台简介
土星云系列边缘计算设备基于BM1684X/BM1688等TPU芯片,具备高性能、低功耗、国产化的特点,非常适合AI模型的端侧部署。
4.1 硬件特性
BM1684X:INT8算力高达32TOPS,支持FP16/BF16混合精度,内置高性能视频编解码引擎;
BM1688:双核TPU架构,INT8算力28.8TOPS,面向更高密度的边缘推理场景;
丰富接口:支持多路视频输入、千兆以太网等,适配各类边缘场景;
工业级设计:宽温工作、高可靠性,满足工业现场部署要求;
4.2 软件栈
libsophon:底层驱动与运行时库;
SAIL(Sophon Artificial Intelligent Library):高级推理接口,封装了模型加载、张量管理、推理执行等功能;
sophon-opencv / sophon-ffmpeg:硬件加速的图像处理与视频编解码库;
BMNet:模型转换工具,支持将PyTorch、ONNX等模型转换为bmodel格式;
五、部署实战:基于sophon-demo的完整流程
本文部署参考官方示例项目:sophon-demo SAM2 Python例程(https://github.com/sophgo/sophon-demo/tree/release/sample/SAM2/python)
5.1 环境准备
5.1.1 硬件与系统环境
设备:土星云SE系列边缘计算盒(搭载BM1684X芯片)
系统:Ubuntu 20.04(SoC模式)
运行时:libsophon >= 0.5.0,sophon-sail >= 3.7.0
5.1.2 依赖安装
SoC平台在/opt/sophon/目录下已预装基础运行库,还需安装sophon-sail与Python依赖:
1. 安装sophon-sail(交叉编译或直接安装whl包)
pip3 install sophon-sail-x.x.x-cp38-cp38-linux_aarch64.whl
2. 克隆demo仓库
git clone https://github.com/sophgo/sophon-demo.git
cd sophon-demo/sample/SAM2/python
3. 安装Python依赖
pip3 install -r requirements.txt
5.1.3 模型准备
从模型仓库下载转换好的bmodel文件,放置到models/目录下。SAM2拆分为多个子模型:
|------------------|---------|-------------------------------------|
| 子模型 | 作用 | 典型文件名 |
| image_encoder | 图像特征提取 | sam2_encoder_f16_1b_2core.bmodel |
| image_decoder | 掩膜生成解码 | sam2_decoder_f16_1b_2core.bmodel |
| memory_attention | 时序记忆注意力 | sam2_memory_attention_f16_1b.bmodel |
| memory_encoder | 记忆特征编码 | sam2_memory_encoder_f16_1b.bmodel |
模型文件可通过模型仓库或自行使用工具从ONNX转换得到。
5.2 图像分割实战
图像分割入口程序为sam2_image_opencv.py,使用OpenCV进行图像解码,SAIL执行TPU推理。
5.2.1 单点分割测试
单点标注是最基础的交互方式,在目标物体内点击一个点即可分割:
python3 sam2_image_opencv.py \
--img_path datasets/images/truck.jpg \
--points '\[500, 375]' \
--label 1 \
--encoder_bmodel models/BM1688/image_encoder/sam2_encoder_f16_1b_2core.bmodel \
--decoder_bmodel models/BM1688/image_decoder/sam2_decoder_f16_1b_2core.bmodel \
--output_dir results/
参数说明:
--points:输入点坐标,格式为嵌套列表,单点为\[x, y]
--label:点标签,1表示正点(目标区域),0表示负点(排除区域)
--select_best:是否自动选择最佳掩膜,默认输出多个候选
5.2.2 多点分割测试
通过多个正点可以更精确地圈定目标范围,提升复杂物体的分割精度:
python3 sam2_image_opencv.py \
--img_path datasets/images/truck.jpg \
--points '\[500, 375, 345, 300, 650, 450]' \
--label 1 \
--encoder_bmodel models/BM1688/image_encoder/sam2_encoder_f16_1b_2core.bmodel \
--decoder_bmodel models/BM1688/image_decoder/sam2_decoder_f16_1b_2core.bmodel
5.2.3 边框分割测试
使用矩形框作为提示,格式遵循COCO边界框规范x, y, w, h:
python3 sam2_image_opencv.py \
--img_path datasets/images/truck.jpg \
--points '\[900, 300, 350, 350]' \
--label 1 \
--encoder_bmodel models/BM1688/image_encoder/sam2_encoder_f16_1b_2core.bmodel \
--decoder_bmodel models/BM1688/image_decoder/sam2_decoder_f16_1b_2core.bmodel
边框模式适合配合目标检测模型使用:检测器输出目标框,SAM2根据框生成精确的像素级掩膜,实现检测-分割流水线。
5.3 视频分割实战
视频分割入口为sam2_video_opencv.py,底层基于sam2_video_base.py基类实现,完整支持SAM2的记忆传播机制。
5.3.1 视频分割命令
python3 sam2_video_opencv.py \
--video_path datasets/videos/sample.mp4 \
--points '\[500, 300]' \
--label 1 \
--output_dir results/video/ \
--image_encoder_path models/BM1684X/image_encoder/sam2_encoder_f16_1b.bmodel \
--image_decoder_path models/BM1684X/image_decoder/sam2_decoder_f16_1b.bmodel \
--memory_attention_path models/BM1684X/memory_attention/sam2_memory_attention_f16_1b.bmodel \
--memory_encoder_path models/BM1684X/memory_encoder/sam2_memory_encoder_f16_1b.bmodel \
--constant_path models/sam2_hiera_base_plus_constant.npz \
--skip_num 1 \
--dev_id 0
5.3.2 关键参数详解
--skip_num:帧间隔,每隔N帧处理一次。增大此值可提升速度但可能丢失追踪连续性,建议根据场景设置1-5;
--constant_path:SAM2的常量张量文件,包含位置编码等固定参数,推理时需加载;
--dev_id:TPU设备ID,多卡场景下指定使用哪块芯片;
5.3.3 视频处理流程
首帧初始化:读取视频第一帧,运行图像编码器提取特征,根据提示点生成初始掩膜;
记忆编码:将首帧掩膜与特征编码为初始记忆状态;
帧循环处理:
-
读取下一帧,运行图像编码器;
-
Memory Attention模块融合当前特征与历史记忆;
-
Decoder生成当前帧掩膜;
-
Memory Encoder更新记忆库;
-
保存结果图像;
输出汇总:将所有帧结果保存到输出目录,可后续合成视频;
5.4 核心代码解析
5.4.1 图像分割核心流程
1. 初始化SAIL引擎
encoder = sail.Engine(encoder_bmodel, dev_id, sail.IOMode.SYSIO)
decoder = sail.Engine(decoder_bmodel, dev_id, sail.IOMode.SYSIO)
2. 图像预处理与编码
img = cv2.imread(img_path)
img_tensor = preprocess(img) # 归一化、Resize、通道转换
features = encoder.process({"image": img_tensor})
3. 提示编码与掩膜解码
point_tensor, label_tensor = encode_prompt(points, label)
masks, scores = decoder.process({
"image_embeddings": features,
"point_coords": point_tensor,
"point_labels": label_tensor
})
4. 后处理与可视化
masks = postprocess_masks(masks, img.shape)
visualize(img, masks, output_path)
5.4.2 视频记忆更新机制
初始化记忆
memory = init_memory(image_feature, initial_mask)
for frame in video_frames:
当前帧图像编码
curr_feature = image_encoder.process(frame)
记忆注意力融合
fused_feature = memory_attention.process(curr_feature, memory)
解码生成掩膜
mask, score = mask_decoder.process(fused_feature, prompt)
更新记忆
new_memory = memory_encoder.process(curr_feature, mask)
memory = update_memory_pool(memory, new_memory)
六、性能优化与工程实践
6.1 推理性能参考
在BM1684X上的典型性能数据(FP16精度):
| 模块 | 输入尺寸 | 耗时 |
|---|---|---|
| Image Encoder | 1024x1024 | ~180ms |
| Mask Decoder | - | ~15ms |
| Memory Attention | - | ~20ms |
| Memory Encoder | - | ~10ms |
图像交互式场景:首次编码约180ms,后续调整提示仅需15ms,交互流畅
视频分割:首帧约220ms,后续每帧约50-70ms(含编码+注意力+解码+记忆更新)
6.2 优化技巧
多batch与多核利用:使用2core bmodel充分利用TPU双核算力,编码器速度可提升约70%;
跳帧策略:对非高速运动场景,设置skip_num=2或skip_num=3,帧率可提升2-3倍;
输入尺寸调整:根据实际需求降低输入分辨率,精度损失可控的前提下大幅提速;
内存复用:复用输入输出张量内存,避免频繁申请释放,减少推理开销;
预处理硬件加速:使用sophon-opencv的硬件加速Resize、颜色空间转换;
6.3 常见问题排查
模型加载失败:检查bmodel版本与libsophon版本是否匹配,BM1684X与BM1688的模型不通用;
输出结果异常:确认预处理参数(均值、方差、归一化方式)与模型转换时一致;
内存不足:视频模式下及时释放无用张量,控制记忆池大小;
视频追踪漂移:增加正点数量,降低skip_num,或定期重新初始化;
七、总结与展望
SAM2作为分割大模型的代表,将通用分割能力从图像延伸到了视频领域,为众多行业应用提供了基础能力支撑。通过土星云边缘计算设备的TPU加速,我们成功将SAM2从实验室带到了边缘端,实现了低延迟、本地化、高可靠的分割推理。
从实际部署效果来看:
- 图像分割方面,首帧编码+实时解码的交互模式完全满足人机交互需求;
- 视频分割方面,记忆传播机制工作正常,对刚性与非刚性物体都有良好的追踪分割效果;
- 部署成本方面,单台边缘设备即可支持多路视频分割推理,性价比显著优于GPU方案;
未来,随着模型量化技术的进一步优化(如INT8量化)、算子融合的持续完善,SAM2在边缘端的性能还将有显著提升空间。结合多模态大模型、目标检测等能力,SAM2将在工业质检、智能安防、机器人等领域发挥更大价值。
国产化AI芯片+通用大模型的组合,正在为边缘智能注入新的活力。希望本文的部署实战能够为各位开发者提供参考,共同推动通用视觉模型在端侧的落地应用。