Segment Anything Model (SAM) 是由 Meta 开源的图像分割大模型,在计算机视觉领域(CV)取得了新的突破。SAM 可在不需要任何标注的情况下,对任何图像中的任何物体进行分割,SAM 的开源引起了业界的广泛反响,被称为计算机视觉领域的 GPT。
论文:
[Segment Anything](https://arxiv.org/abs/2304.02643)
Alexander Kirillov, Eric Mintun, Nikhila Ravi, Hanzi Mao, Chloe Rolland, Laura Gustafson, Tete Xiao, Spencer Whitehead, Alexander C. Berg, Wan-Yen Lo, Piotr Dollár, Ross Girshick参考实现:
url=https://github.com/facebookresearch/segment-anything.git
commit_id=6fdee8f2727f4506cfbbe553e23b895e27956588
model_name=sam_vit_b_01ec64表 1 版本配套表
| 配套 | 版本 | 环境准备指导 |
|---|---|---|
| 固件与驱动 | 25.2.RC1 | Pytorch框架推理环境准备 |
| CANN | 8.2.RC1 | - |
| Python | 3.11.10 | - |
| PyTorch | 2.1.0 | - |
| 说明:仅支持Atlas 300I Duo 推理卡,请以CANN版本选择实际固件与驱动版本。 | \ | \ |
git clone https://gitee.com/ascend/ModelZoo-PyTorch.git
cd ModelZoo-PyTorch/ACL_PyTorch/built-in/cv/SAM
git clone https://github.com/facebookresearch/segment-anything.git
cd segment-anything
git reset --hard 6fdee8f2727f4506cfbbe553e23b895e27956588
git apply ../segment_anything_diff.patch
pip3 install -e .
cd ..pip3 install -r requirements.txt说明:如果某些库通过此方式安装失败,可使用 pip3 install 单独进行安装。
SAM 首先会自动分割图像中的所有内容,但是如果你需要分割某一个目标物体,则需要你输入一个目标物体上的坐标,比如一张图片你想让SAM分割Cat或Dog这个目标的提示坐标,SAM会自动在照片中猫或狗进行分割,在离线推理时,会转成encoder模型和decoder模型,其输入输出详情如下:
encoder输入数据
| 输入数据 | 数据类型 | 大小 | 数据排布格式 |
|---|---|---|---|
| x | FLOAT32 | 1 x 3 x 1024 x 1024 | NCHW |
encoder输出数据
| 输出数据 | 数据类型 | 大小 | 数据排布格式 |
|---|---|---|---|
| image_embeddings | FLOAT32 | 1 x 256 x 64 x 64 | NCHW |
decoder输入数据
| 输入数据 | 数据类型 | 大小 | 数据排布格式 |
|---|---|---|---|
| image_embeddings | FLOAT32 | 1 x 256 x 64 x 64 | NCHW |
| point_coords | FLOAT32 | 1 x -1 x 2 | ND |
| point_labels | FLOAT32 | 1 x -1 | ND |
| mask_input | FLOAT32 | 1 x 1 x 256 x 256 | NCHW |
| has_mask_input | FLOAT32 | 1 | ND |
decoder输出数据
| 输出数据 | 数据类型 | 大小 | 数据排布格式 |
|---|---|---|---|
| iou_predictions | FLOAT32 | -1 x 1 | ND |
| low_res_masks | FLOAT32 | -1 x 1 x -1 x -1 | ND |
mkdir data
cd data
wget -O demo.jpg https://raw.githubusercontent.com/facebookresearch/segment-anything/571794162e0887c15d12b809505b902c7bf8b4db/notebooks/images/truck.jpg
cd ..下载并解压COCO-2017数据集的图片与标注,放置coco2017目录下
coco2017
├── annotations/
│ └── instances_val2017.json
└── val2017/
├── 000000000139.jpg
├── 000000000139.jpg
└── ...GitHub 仓库提供了三种大小的权重文件:vit_h、vit_l、vit_b。这里以 vit_b 为例。
mkdir models
cd models
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth
cd ..python3 segment-anything/scripts/export_onnx_model.py \
--checkpoint models/sam_vit_b_01ec64.pth \
--model-type vit_b \
--opset 14 \
--encoder-output models/encoder.onnx \
--decoder-output models/decoder.onnx \
--return-single-mask参数说明:
这里以 batchsize=1 为例。
batchsize=1
onnxsim models/encoder.onnx models/encoder_sim.onnx --overwrite-input-shape="x:${batchsize},3,1024,1024"
onnxsim models/decoder.onnx models/decoder_sim.onnx参数说明:
python3 encoder_onnx_modify.py \
--input models/encoder_sim.onnx \
--output models/encoder_modify.onnx参数说明:
配置环境变量。
source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/mindie/set_env.sh说明: 该脚本中环境变量仅供参考,请以实际安装环境配置环境变量。详细介绍请参见《CANN 开发辅助工具指南 》。
执行命令查看芯片名称(${chip_name})。
npu-smi info
#该设备芯片名为Ascend310P3 (自行替换)
回显如下:
+-------------------+-----------------+------------------------------------------------------+
| NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page) |
| Chip Device | Bus-Id | AICore(%) Memory-Usage(MB) |
+===================+=================+======================================================+
| 0 310P3 | OK | 15.8 42 0 / 0 |
| 0 0 | 0000:82:00.0 | 0 1074 / 21534 |
+===================+=================+======================================================+
| 1 310P3 | OK | 15.4 43 0 / 0 |
| 0 1 | 0000:89:00.0 | 0 1070 / 21534 |
+===================+=================+======================================================+执行 atc 命令。
atc \
--framework 5 \
--model models/encoder_modify.onnx \
--output models/encoder_modify \
--insert_op_conf sam.aippconfig \
--enable_small_channel 1 \
--soc_version "Ascend${chip_name}"
atc \
--framework 5 \
--model models/decoder_sim.onnx \
--output models/decoder_sim \
--input_format 'ND' \
--input_shape 'image_embeddings:1,256,64,64;point_coords:1,-1,2;point_labels:1,-1;mask_input:1,1,256,256;has_mask_input:1' \
--dynamic_dims '2,2;3,3;4,4;5,5;6,6;7,7;8,8;9,9' \
--op_select_implmode 'high_performance' \
--optypelist_for_implmode 'Gelu' \
--soc_version "Ascend${chip_name}"参数说明:
更多参数说明请参考 ATC 参数概览(如果链接失效,请从 CANN 社区版文档 查找目录「应用开发 > ATC 模型转换 > 参数说明 > 参数概览」)
6.1 端到端推理。成功执行下述命令后会在save-path参数指定的目录生成离线推理的结果。
python3 sam_end2end_infer.py \
--src-path data/demo.jpg \
--save-path . \
--encoder-model-path models/encoder_modify.om \
--decoder-model-path models/decoder_sim.om \
--input-point '[[500, 375], [1125, 625], [1520, 625]]' \
--device-id 0参数说明:
```若出现类似"OSError: .../python3.10/site-packages/torch/lib/libgomp-d22c30c5.so.1: cannot allocate memory in static TLS block"错误,可以使用export LD_PRELOAD=$LD_PRELOAD:<报错路径>解决。
例子:export LD_PRELOAD=$LD_PRELOAD:/root/anaconda3/envs/sam/lib/python3.10/site-packages/torch/lib/libgomp-d22c30c5.so.1
```在线模型推理结果:
离线模型推理结果:
6.2 性能验证。
encoder 纯推理性能验证。
python3 -m ais_bench --model models/encoder_modify.om --loop 100参数说明:
decoder 纯推理性能验证。
这里以输入 3 个坐标为例。
num_points=3
python3 -m ais_bench \
--model models/decoder_sim.om \
--dymDims "image_embeddings:1,256,64,64;point_coords:1,${num_points},2;point_labels:1,${num_points};mask_input:1,1,256,256;has_mask_input:1" \
--outputSize '1000,1000000' \
--loop 100参数说明:
6.3 精度验证。
SAM 官方未提供精度评测手段,这里提供对应脚本,基于 COCO 验证集标注框作为输入提示,使用 SAM 预测分割掩码,并与 COCO 标注掩码逐实例进行 IoU 计算,最后对所有实例的 IoU 结果取平均,得到整体的平均交并比(mIoU)。
```bash
python sam_coco_metric.py \
--dataset-path coco2017 \
--save-path outputs \
--encoder-model-path models/encoder_sim.om \
--decoder-model-path models/decoder_sim.om \
--device-id 0 \
--max-instances 0
```参数说明:
性能结果:
| 芯片型号 | 模型 | Batch Size | 性能 |
|---|---|---|---|
| 300I Pro | encoder | 1 | 4.43 fps |
| 300I Pro | decoder | 1 | 679.77 fps |
精度结果:
| 芯片型号 | 模型 | Batch Size | 精度(mIoU) |
|---|---|---|---|
| 300I Pro | SAM | 1 | 0.7654 |