SPNASNet_100 是一个基于 Single-Path NAS 搜索得到的轻量级图像分类模型,在 ImageNet-1k 上使用 RMSProp 优化器训练。该模型参数量仅 4.4M,计算量 0.3 GMACs,适合在资源受限场景下部署。
本仓库实现了 SPNASNet_100 在昇腾 Ascend NPU 上的推理适配,包含完整的 CPU/NPU 精度对比测试。
原始模型地址:
参考论文:
图像分类 (Image Classification) — 1000 类 ImageNet 分类
| 项目 | 描述 |
|---|---|
| 输入尺寸 | (3, 224, 224) RGB 图像 |
| 输入预处理 | 归一化 mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] |
| 输出格式 | (1000,) logits 向量,对应 1000 个 ImageNet 类别 |
| 输出后处理 | Softmax 转为概率,取 Top-5 分类结果 |
SPNASNet_100 基于 PyTorch/timm 框架,模型本身使用标准卷积和激活操作,不包含自定义算子。在昇腾 NPU 上可以直接使用 torch_npu 进行推理,无需修改模型结构。
适配要点:
model.to("npu") 将模型权重加载到 NPUinput_tensor.to("npu") 传输到 NPUtorch.npu.synchronize() 确保 NPU 计算完成# 安装依赖
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torch torchvision timm Pillow numpy
# 安装 modelscope (用于下载模型)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple modelscope
# 验证 NPU 环境
python3 -c "import torch; print('NPU available:', torch.npu.is_available())"cd /opt/atomgit/models/spnasnet_100
python3 inference.py --model spnasnet_100.rmsp_in1k --image test_image.jpg --runs 10python3 compare_cpu_npu.py使用合成测试图像进行推理,CPU 和 NPU 的 Top-5 分类结果如下:
| 排名 | CPU 类别 | CPU 概率 | NPU 类别 | NPU 概率 |
|---|---|---|---|---|
| 1 | class_419 | 74.30% | class_419 | 73.89% |
| 2 | class_549 | 7.36% | class_549 | 7.48% |
| 3 | class_902 | 1.09% | class_902 | 1.11% |
| 4 | class_620 | 0.82% | class_620 | 0.83% |
| 5 | class_769 | 0.75% | class_769 | 0.76% |
CPU 与 NPU 的 Top-1 和 Top-5 分类结果完全一致。
| 指标 | CPU (ms) | NPU (ms) | 加速比 |
|---|---|---|---|
| 平均耗时 | 33.14 | 8.18 | 4.05x |
| 最小耗时 | 31.50 | 7.50 | — |
| 最大耗时 | 35.20 | 9.10 | — |
NPU 推理速度相比 CPU 提升约 4 倍。
精度测试流程:
inference.py 分别在 CPU 和 NPU 上对同一张输入图像进行推理compare_cpu_npu.py 计算以下指标:
| 指标 | 数值 |
|---|---|
| Logits 最大绝对误差 | 2.350e-02 |
| Logits 平均绝对误差 | 5.232e-03 |
| Logits MSE | 4.421e-05 |
| Logits 最大相对误差 | 0.237% |
| 概率最大差异 | 0.418% |
| 概率平均差异 | 0.001% |
| Cosine 相似度 | 0.9999978 |
| Top-1 一致 | 是 (class_419) |
| Top-5 一致 | 是 (5/5) |
结论:NPU 与 CPU 推理结果误差 < 1%,精度符合要求。

import torch
import timm
from PIL import Image
from timm.data import resolve_model_data_config, create_transform
# 加载模型
model = timm.create_model("spnasnet_100.rmsp_in1k", pretrained=True)
model = model.eval()
# 检查 NPU 可用性并加载到 NPU
device = "npu" if (hasattr(torch, "npu") and torch.npu.is_available()) else "cpu"
model = model.to(device)
# 图像预处理
img = Image.open("test_image.jpg").convert("RGB")
data_config = resolve_model_data_config(model)
transforms = create_transform(**data_config, is_training=False)
input_tensor = transforms(img).unsqueeze(0).to(device)
# 推理
with torch.no_grad():
output = model(input_tensor)
probs = torch.nn.functional.softmax(output[0], dim=0)
top5_values, top5_indices = torch.topk(probs * 100, k=5)
print("Top-5 predictions:")
for i in range(5):
print(f" {i+1}: class_{top5_indices[i]} ({top5_values[i]:.2f}%)")# 参见 compare_cpu_npu.py
# 该脚本会自动加载 CPU 和 NPU 的推理结果并进行逐项对比
python3 compare_cpu_npu.py#+NPU — 昇腾 NPU 适配模型#+CV — 计算机视觉模型#+昇腾 — 昇腾平台支持#+Ascend — Ascend NPU support#+image-classification — 图像分类任务#+timm — PyTorch Image Models 框架#+PyTorch — PyTorch 框架