Ascend-SACT/SAM2-A3
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

SAM2 Ascend NPU 使能

SAM2 (Segment Anything Model 2) 在华为昇腾 NPU 上的使能方案,支持图像分割推理和训练流程。

一、模型介绍

项目值
模型名称SAM2 (Segment Anything Model 2)
模型 IDfacebook/sam2.1-hiera-large
参数量~1.8 GB
任务图像/视频分割
LicenseApache-2.0

模型架构

Sam2VideoModel
├── Sam2VisionModel (Hiera Backbone)
│   ├── Stage 0: embed_dim=144, blocks=2
│   ├── Stage 1: embed_dim=288, blocks=6
│   ├── Stage 2: embed_dim=576, blocks=36
│   └── Stage 3: embed_dim=1152, blocks=4
├── Sam2PromptEncoder
│   └── 点嵌入 + Mask 嵌入
├── Sam2MaskDecoder
│   └── Cross Attention + MLP
└── Memory Attention (视频帧间记忆)

二、环境要求

硬件环境

型号说明
Ascend910已验证 (16 卡)
Ascend910B兼容
驱动版本25.5.0 (C23)

软件环境

软件名版本
CANN8.5.1
Python3.12.3
torch2.11.0
torch-npu2.11.0rc1
torchvision0.26.0
transformers5.5.0
accelerate1.13.0
Pillow12.2.0

三、快速开始

3.1 创建 Docker 容器

在 Ascend NPU 宿主机执行:

# 创建数据目录
mkdir -p /data/npu_adapter/sam2-adapt

# 创建容器
docker run -d \
  --name sam2-npu-adapt \
  --privileged \
  --pid=host \
  --device /dev/davinci_manager \
  --device /dev/devmm_svm \
  --device /dev/hisi_hdc \
  --device /dev/davinci0 \
  -v /usr/local/dcmi:/usr/local/dcmi:ro \
  -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \
  -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/:ro \
  -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \
  -v /etc/ascend_install.info:/etc/ascend_install.info:ro \
  -v /data/npu_adapter/sam2-adapt:/data \
  --shm-size=16g \
  -p 2222:22 \
  swr.cn-north-4.myhuaweicloud.com/ascend-sact/ascend-a3-ubuntu:v3.3 \
  sleep infinity

# 配置 SSH
docker exec sam2-npu-adapt bash -c "sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config"
docker exec sam2-npu-adapt bash -c "service ssh start"
docker exec sam2-npu-adapt bash -c "echo 'root:<your_password>' | chpasswd"

权限说明:

  • --privileged: 开发测试环境推荐,配置简单
  • 生产环境可使用 --cap-add=SYS_PTRACE --cap-add=IPC_LOCK --cap-add=SYS_ADMIN 替代

3.2 安装依赖

进入容器后执行:

# 进入容器
docker exec -it sam2-npu-adapt bash

# 设置环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
export OPENBLAS_NUM_THREADS=1

# 安装 pip
apt-get update && apt-get install -y python3-pip

# 安装依赖
pip3 install torch==2.11.0 torchvision==0.26.0 torch-npu==2.11.0rc1 \
    transformers accelerate Pillow requests scipy opencv-python \
    --break-system-packages -i https://pypi.tuna.tsinghua.edu.cn/simple

3.3 验证 NPU

source /usr/local/Ascend/ascend-toolkit/set_env.sh
export OPENBLAS_NUM_THREADS=1

python3 -c "import torch; import torch_npu; print('NPU available:', torch_npu.npu.is_available()); print('NPU count:', torch_npu.npu.device_count())"

3.4 运行推理

cd /data
python run_inference_npu.py --image https://huggingface.co/datasets/hf-internal-testing/sam2-fixtures/resolve/main/truck.jpg --output mask.png

预期输出:

Loading SAM2 model: facebook/sam2.1-hiera-large
Device: npu:0
NPU available: True
NPU count: 16
Model loaded successfully

Loading image: https://...
Image size: (1800, 1200)

Running single-point segmentation...

Results:
  Inference time: 0.494s
  Output masks shape: torch.Size([1, 3, 1200, 1800])
  Number of predictions: 3

Mask saved to: mask.png

=== SAM2 NPU inference completed ===

3.5 运行训练

3.5.1 数据准备

准备训练数据集,目录结构如下:

data/
├── images/          # 图像文件 (*.jpg, *.png)
│   ├── image_001.jpg
│   ├── image_002.jpg
│   └── ...
├── masks/           # 对应的分割 mask (*.png)
│   ├── image_001.png
│   ├── image_002.png
│   └── ...
└── annotations.json # 点/框标注(可选)

说明: mask 文件应为二值图像(白色=目标区域,黑色=背景),尺寸与对应图像一致。

3.5.2 单卡训练

cd /data
python run_train_npu.py --data_dir /data/dataset --epochs 10 --batch_size 4 --lr 1e-5

预期输出:

=== SAM2 NPU Training ===
Device: npu:0
NPU available: True
NPU count: 16
Loading dataset from: /data/dataset
Loaded 100 images for train

Starting training for 10 epochs...
==================================================

Epoch 1/10
------------------------------
  Batch 0/25, Loss: 3.4145
  Batch 10/25, Loss: 2.8934
  Batch 20/25, Loss: 2.4567
Epoch 1 - Average Loss: 2.7234
Epoch time: 45.2s
Checkpoint saved: ./output/checkpoint_epoch_5.pt

...

Epoch 10/10
------------------------------
  Average Loss: 0.8765
Checkpoint saved: ./output/checkpoint_epoch_10.pt

==================================================
Training completed!
Final checkpoint saved to: ./output
==================================================

3.5.3 训练参数说明

参数说明默认值
--model模型 ID 或路径facebook/sam2.1-hiera-large
--device训练设备npu:0
--data_dir数据集目录必需
--output_dir输出目录./output
--epochs训练轮数10
--batch_size批大小4
--lr学习率1e-5
--gradient_checkpointing启用梯度检查点(节省显存)False

3.5.4 多卡分布式训练

# 使用 torchrun 启动分布式训练
source /usr/local/Ascend/ascend-toolkit/set_env.sh
export OPENBLAS_NUM_THREADS=1

torchrun --nproc_per_node=8 \
  run_train_npu.py \
  --data_dir /data/dataset \
  --epochs 10 \
  --batch_size 2 \
  --lr 1e-5

说明:

  • --nproc_per_node=8: 使用 8 张 NPU 卡
  • 分布式训练会自动使用 HCCL backend
  • 批大小为每卡的批大小,总批大小 = batch_size × nproc

3.5.5 显存优化

大图像训练(1024x1024)可能显存不足,推荐:

# 启用梯度检查点
python run_train_npu.py --data_dir /data/dataset --gradient_checkpointing

# 或减小批大小
python run_train_npu.py --data_dir /data/dataset --batch_size 1

3.5.6 恢复训练

# 从 checkpoint 恢复
python run_train_npu.py --data_dir /data/dataset --resume ./output/checkpoint_epoch_5.pt

四、使能说明

4.1 NPU 兼容性修复

本模型需要加载兼容层脚本 npu_compat.py,主要修复:

GELU 算子修复

NPU 的 GELU 算子要求输入 tensor 是 contiguous 的:

# 使用兼容层
from npu_compat import apply_npu_compat
apply_npu_compat()

# 或者手动修复
import torch.nn.functional as F
_original_gelu = F.gelu
def gelu_contiguous(input, approximate="none"):
    if input.device.type == "npu":
        input = input.contiguous()
    return _original_gelu(input, approximate=approximate)
F.gelu = gelu_contiguous

4.2 版本兼容性

组件推荐版本说明
torch2.11.0与 torch-npu 2.11.0rc1 配套
torch-npu2.11.0rc1支持 CANN 8.5.x
transformers5.5.0SAM2 原生支持

4.3 容器权限说明

NPU 访问需要特权操作,原因:

操作说明
内核级系统调用ioctl、内存映射等
硬件管理接口与 NPU 固件通信
共享内存操作NPU 与主机内存交互

--device 只提供设备文件访问权限,不包含驱动初始化所需的内核能力。

错误表现(权限不足时):

drvErr=87 (driver internal error)
EL0005: Resource_Busy

五、性能指标

推理延迟 (100 iterations)

指标值
平均延迟92.50 ms
P5092.46 ms
P9592.89 ms
P9993.03 ms
FPS10.81

显存占用

指标值
Peak Allocated1.64 GB
Peak Reserved2.45 GB

批处理吞吐量

Batch Size延迟 (ms)吞吐量 (img/s)
192.1910.85
2168.3711.88
4310.7812.87

精度验证

NPU 输出与 CPU 参考输出对比:

测试点IoU像素准确率状态
中心点0.988099.95%✅
左上点0.995999.98%✅
右下点0.999799.99%✅

训练流程验证

步骤状态
前向传播✅
损失计算✅
反向传播✅
梯度计算✅
优化器步骤✅

六、常见问题

Q1: NPU 显示不可用 (NPU available: False)

原因: 容器缺少必要的权限参数

解决: 确保容器启动时添加 --privileged --pid=host 参数

Q2: GELU 报错 "Only Contiguous is supported"

原因: NPU 算子要求 contiguous tensor

解决: 使用 npu_compat.py 兼容层,或在推理脚本开头调用 apply_npu_compat()

Q3: torch-npu 版本冲突

原因: torchvision 可能拉入不兼容的 torch 版本

解决: 先安装 torch-npu,再安装 torchvision,或使用推荐的版本组合

Q4: drvRet=87 错误

原因: 容器无法访问 NPU 驱动(权限不足)

解决:

  1. 确认宿主机驱动已安装 (npu-smi info)
  2. 确认容器挂载了驱动目录
  3. 添加 --privileged 参数

七、参考资料

  • SAM2 论文
  • SAM2 HuggingFace 模型卡
  • Transformers SAM2 文档
  • 昇腾社区
  • torch-npu GitHub

八、文件说明

sam2-npu-adapt/
├── README.md                 # 本文档
├── run_inference_npu.py      # 推理脚本
├── npu_compat.py             # NPU 兼容层
├── run_train_npu.py          # 训练脚本(可选)
└── create_container.sh       # 容器创建脚本

使能完成时间: 2026-04-07

验证完成时间: 2026-04-10

使能状态: ✅ 推理、训练、精度、性能验证全部通过