Sequencer2D_s 是一种基于 Sequence-to-Sequence 机制的图像分类模型,由 timm 库实现。其核心思想是将图像视为序列,利用双向 LSTM 替代传统的自注意力机制,在保持 competitive 性能的同时减少了计算复杂度。该模型在 ImageNet-1K 数据集上预训练,适用于 1000 类图像分类任务。
原始模型地址:
图像分类(Image Classification)
| 组件 | 版本 |
|---|---|
| Python | 3.11.14 |
| torch | 2.9.0 |
| torch_npu | 2.9.0.post1 |
| timm | 1.0.27 |
| Pillow | 12.2.0 |
| numpy | 1.24+ |
该模型基于 PyTorch + timm 框架实现,在华为昇腾 NPU(Ascend 910)上可直接通过 torch_npu 进行推理加速。适配过程未修改模型架构,仅通过 model.to(torch.device("npu")) 将模型加载到 NPU 设备。
主要适配步骤:
# 安装依赖
pip install -r requirements.txtpython3 inference.py --model sequencer2d_s.in1k \
--weights /path/to/weights/model.safetensors \
--device cpu \
--dump logits_cpu.npypython3 inference.py --model sequencer2d_s.in1k \
--weights /path/to/weights/model.safetensors \
--device npu \
--dump logits_npu.npypython3 compare_cpu_npu.py --cpu logits_cpu.npy --npu logits_npu.npy --model sequencer2d_s| 指标 | CPU | NPU |
|---|---|---|
| Top-1 类别 | 701 | 701 |
| Top-1 概率 | 0.005904 | 0.005931 |
| Top-5 类别 | [701, 549, 680, 405, 974] | [701, 549, 680, 405, 974] |
| 平均延迟 | 646.67 ms | 61.46 ms |
| 加速比 | - | 10.52x |
| 指标 | 值 |
|---|---|
| 最大绝对误差 | 6.68e-03 |
| 平均绝对误差 | 1.31e-03 |
| 最大概率差异 | 2.69e-05 |
| 平均概率差异 | 1.45e-06 |
| L2 距离 | 5.21e-02 |
| 余弦相似度 | 0.99999660 |
| CPU logits 范围 | 2.956633 |
| 误差率 | 0.226% |
结论:NPU 与 CPU 推理结果误差 < 1%
精度测试结果显示,NPU 与 CPU 推理结果的误差率仅为 0.226%,远低于 1% 的阈值。Top-1 和 Top-5 类别完全一致,余弦相似度达到 0.99999660,表明 NPU 推理精度与 CPU 几乎一致。
| 设备 | 平均延迟 (ms) | 加速比 |
|---|---|---|
| CPU | 646.67 | 1x (基准) |
| NPU (Ascend 910) | 61.46 | 10.52x |

import torch
import torch_npu
from timm import create_model
from timm.data import resolve_data_config
from timm.data.transforms_factory import create_transform
from PIL import Image
# 创建模型并加载权重
model = create_model("sequencer2d_s.in1k", pretrained=False)
state_dict = torch.load("model.safetensors", map_location="cpu")
model.load_state_dict(state_dict)
model.eval()
# 迁移到 NPU
device = torch.device("npu")
model.to(device)
# 准备输入
img = Image.open("input.jpg").convert("RGB")
config = resolve_data_config({}, model=model)
transform = create_transform(**config)
input_tensor = transform(img).unsqueeze(0).to(device)
# 推理
with torch.no_grad():
output = model(input_tensor)
probs = torch.softmax(output, dim=1)
top1 = torch.argmax(probs, dim=1)
print(f"Top-1 class: {top1.item()}")