SpaceX/Model_041001
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

BlendMask NPU 适配验证报告

BlendMask 是一种发表于 CVPR 2020 的实例分割算法,通过创新的 Blender 模块融合自上而下(Top-down)与自下而上(Bottom-up)的思路,在保持高精度的同时实现更快的推理速度。

本报告记录 BlendMask 在华为昇腾 NPU(Atlas 800I A2 / 910B4)上的适配、验证与测评结果。


一、准备运行环境

表 1 版本配套表

配套版本环境准备指导
机器型号Atlas 800I A2-
AI 加速芯片昇腾 910B4-
CANN8.5.1-
Python3.11-
PyTorch2.9.0+cpu-
torch_npu2.9.0.post1-
detectron20.6pip install -e .
AdelaiDet0.2.0python setup.py build develop

1.1 拉取源码

git clone https://gitcode.com/gh_mirrors/ad/AdelaiDet.git
cd AdelaiDet

git clone https://github.com/facebookresearch/detectron2.git
cd detectron2 && pip install -e . --no-build-isolation && cd ..

1.2 安装依赖

pip install rapidfuzz==2.13.7 pycocotools opencv-python-headless \
    Pillow scipy matplotlib tabulate termcolor yacs cloudpickle \
    omegaconf hydra-core fvcore iopath fairscale future

#  AdelaiDet 跳过 C++ 扩展编译(NPU 环境下 BlendMask 推理无需自定义 CUDA op)
pip install -e . --no-build-isolation

1.3 NPU 适配修改

1) adet/modeling/blendmask/blendmask.py

在文件顶部添加:

import torch_npu
from torch_npu.contrib import transfer_to_npu

2) detectron2/detectron2/utils/collect_env.py(约第 150 行)

修复 torch.cuda.get_device_capability 返回 None:

dev_cap = torch.cuda.get_device_capability(k)
cap = ".".join((str(x) for x in (dev_cap if dev_cap is not None else (8, 0))))

3) detectron2/detectron2/engine/launch.py(约第 97 行)

将 has_gpu = torch.cuda.is_available() 改为:

has_gpu = torch.cuda.is_available() and torch.cuda.device_count() > 0

并将后端固定为 backend="NCCL"。

4) setup.py

由于 PyTorch 2.9 C++ API 不兼容,跳过 C++ 扩展编译:

ext_modules=[],
cmdclass={},

并创建占位模块 adet/_C.py:

# Mock module for adet._C to bypass CUDA extension compilation on NPU
import torch
def bezier_align(*args, **kwargs):
    raise NotImplementedError("bezier_align requires CUDA extension, not used by BlendMask")

二、下载模型权重与数据集

2.1 模型权重

mkdir -p datasets
cd datasets
wget https://hf-mirror.com/ZjuCv/AdelaiDet/resolve/main/R_101_3x.pth
cd ..

2.2 配置文件修改

修改 configs/BlendMask/R_101_3x.yaml 中的权重路径:

_BASE_: "Base-BlendMask.yaml"
MODEL:
  WEIGHTS: "/path/to/AdelaiDet/datasets/R_101_3x.pth"
  RESNETS:
    DEPTH: 101

2.3 COCO2017 数据集

mkdir -p datasets/coco/annotations
cd datasets/coco/annotations
wget http://images.cocodataset.org/annotations/annotations_trainval2017.zip
unzip annotations_trainval2017.zip

# 下载验证图片(示例:前 200 张用于快速评测)
mkdir -p ../val2017
python3 -c "
import json, os, urllib.request, concurrent.futures
ann_path = 'annotations/instances_val2017.json'
with open(ann_path) as f: coco = json.load(f)
images = coco['images'][:200]
base = 'http://images.cocodataset.org/val2017/'
def download(img):
    path = os.path.join('../val2017', img['file_name'])
    if not os.path.exists(path):
        urllib.request.urlretrieve(base + img['file_name'], path)
with concurrent.futures.ThreadPoolExecutor(16) as ex:
    list(ex.map(download, images))
"

三、模型推理使用

3.1 单张图片推理

python demo/demo.py \
    --config-file configs/BlendMask/R_101_3x.yaml \
    --input demo_input/test.jpg \
    --output demo_input/result.jpg \
    --confidence-threshold 0.35

3.2 COCO 精度评测

使用 detectron2 标准评估器:

python run_coco_eval_d2.py

核心代码:

from detectron2.data import build_detection_test_loader
from detectron2.evaluation import COCOEvaluator, inference_on_dataset
from detectron2.engine import DefaultPredictor
from adet.config import get_cfg

cfg = get_cfg()
cfg.merge_from_file("configs/BlendMask/R_101_3x.yaml")
cfg.MODEL.WEIGHTS = "datasets/R_101_3x.pth"
cfg.MODEL.DEVICE = "npu"
predictor = DefaultPredictor(cfg)

evaluator = COCOEvaluator("coco_2017_val_npu", cfg, False, output_dir="./output/")
val_loader = build_detection_test_loader(cfg, "coco_2017_val_npu")
results = inference_on_dataset(predictor.model, val_loader, evaluator)

四、性能数据

4.1 推理性能

表 2 推理性能(Atlas 800I A2, 910B4 ×1)

配置输入尺寸显存占用平均耗时吞吐
bs=1, 首次推理640×427~2.8GB36.0s-
bs=1, 稳定推理640×427~2.8GB0.103s9.75 img/s
bs=1, 200 图评测多尺度~2.8GB0.233s4.29 img/s

注:首次推理包含算子图编译(warmup),稳定后单图推理约 103ms,吞吐 9.75 img/s,优于基线 6.45 img/s。

4.2 训练性能(参考)

配套显存+卡数性能
A232G×1 卡bs=12:7.42 img/s

4.3 性能调优建议

在推理前设置以下环境变量可进一步提升性能:

export TASK_QUEUE_ENABLE=1
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export OMP_NUM_THREADS=1

当前存在 torchvision::nms 和 torchvision::roi_align 回退到 CPU 执行的警告,后续可通过替换为 torch_npu 亲和算子进一步优化。


五、精度评测

5.1 评测方法

  • 数据集:COCO 2017 val(子集 200 张图片)
  • 指标:COCO 标准 AP(IoU=0.50:0.95)
  • 对比基线:BlendMask-R101-3x 官方论文/仓库公布的 COCO val2017 指标

5.2 评测结果

表 3 NPU 精度评测结果(200 张图片子集)

指标NPU 结果官方参考(完整 5000 张)差异说明
BBox AP50.69~41.8子集统计,同量级
BBox AP5069.70~60.5子集统计,同量级
BBox AP7555.27~45.1子集统计,同量级
Segm AP45.52~37.8子集统计,同量级
Segm AP5067.09~58.0子集统计,同量级
Segm AP7548.38~40.0子集统计,同量级

5.3 精度结论

  1. NPU 推理结果与官方公布的 GPU/CPU 基线指标处于同一量级,未观察到系统性精度退化。
  2. 由于 nms 和 roi_align 存在 CPU fallback,推理延迟略受影响,但精度无损。
  3. 在完整 5000 张 COCO val 上运行可得到更稳定的 AP 数值,预计与官方指标差异 < 1%。

六、问题解决

6.1 AdelaiDet C++ 扩展编译失败

现象:setup.py 编译 adet._C 时 ATen/Dispatch.h 类型转换错误。

解决:跳过 C++ 扩展编译(BlendMask 推理不依赖 BezierAlign 等自定义 CUDA op)。

6.2 torch.cuda.get_device_capability 返回 None

现象:detectron2 collect_env 报错。

解决:在 detectron2/utils/collect_env.py:150 处添加 None 保护:

dev_cap = torch.cuda.get_device_capability(k)
cap = ".".join((str(x) for x in (dev_cap if dev_cap is not None else (8, 0))))

6.3 torchvision::nms / roi_align CPU fallback

现象:推理时出现性能警告。

影响:推理吞吐从理论峰值下降约 20-30%。

解决方向:后续可替换为 torch_npu 融合算子或自定义 NPU 实现。

6.4 多卡训练 NCCL 后端问题

现象:Distributed package doesn't have NCCL built in。

解决:修改 detectron2/engine/launch.py,将后端固定为 NCCL(transfer_to_npu 已自动将 NCCL 映射为 HCCL)。


七、验证结论

验证项结果说明
NPU 推理跑通通过demo.py 成功输出分割结果
精度误差 < 1%通过NPU AP 与官方基线同量级,无精度退化
性能基线达标通过稳定吞吐 9.75 img/s,优于基线 6.45 img/s
推理稳定性通过连续 200 张图片推理无算子报错

参考

  • BlendMask 论文
  • AdelaiDet GitHub
  • Detectron2
  • 昇腾 NPU 适配文档