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

ViT (Vision Transformer) 昇腾 NPU 迁移文档


1. 模型介绍

1.1 模型概述

Vision Transformer (ViT) 是由 Google Research 提出的视觉 Transformer 模型,首次将 Transformer 架构直接应用于图像分类任务,取代传统的卷积神经网络(CNN)。

  • 论文: "An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale" (Dosovitskiy et al., ICLR 2021)
  • 论文链接: https://arxiv.org/abs/2010.11929
  • Google 原始代码仓库: https://github.com/google-research/vision_transformer
  • timm 实现仓库: https://github.com/huggingface/pytorch-image-models

1.2 本次迁移模型

属性值
模型名称vit_base_patch16_224
权重版本augreg2_in21k_ft_in1k
参数量86.57M
输入分辨率224×224
Patch Size16×16
GMACs16.9
预训练数据ImageNet-21k
微调数据ImageNet-1k
分类数1000

模型信息数据来源: timm 官方模型卡 https://huggingface.co/timm/vit_base_patch16_224.augreg2_in21k_ft_in1k ,以及 timm 官方 results-imagenet.csv(https://github.com/huggingface/pytorch-image-models/blob/main/results/results-imagenet.csv),条目 vit_base_patch16_224.augreg2_in21k_ft_in1k。

1.3 训练背景

该权重由 Google 论文作者在 ImageNet-21k 上预训练,再由 Ross Wightman(timm 作者)使用 AugReg 策略在 ImageNet-1k 上微调。相关论文:

  • "How to train your ViT? Data, Augmentation, and Regularization in Vision Transformers" (Steiner et al., arXiv:2106.10270)

2. 模型相关数据获取

2.1 模型源码

ViT 的模型实现由 timm 包 提供,通过 pip 安装。

属性值
包名timm (PyTorch Image Models)
版本1.0.19
安装方式pip install timm==1.0.19
包安装路径/usr/local/python3.11.15/lib/python3.11/site-packages/timm/
ViT 核心实现文件/usr/local/python3.11.15/lib/python3.11/site-packages/timm/models/vision_transformer.py
GitHub 仓库https://github.com/huggingface/pytorch-image-models

在推理脚本中通过以下方式引入模型:

import timm
model = timm.create_model('vit_base_patch16_224', pretrained=False, num_classes=1000)

2.2 权重文件

属性值
文件名vit_base_patch16_224_weights.pth
大小331MB
HuggingFace 模型页https://huggingface.co/timm/vit_base_patch16_224.augreg2_in21k_ft_in1k
权重文件 URLhttps://huggingface.co/timm/vit_base_patch16_224.augreg2_in21k_ft_in1k/resolve/main/model.safetensors
本地路径/home/zy/vit-a3/vit_base_patch16_224_weights.pth

获取方式:

source /usr/local/Ascend/ascend-toolkit/set_env.sh
export HF_ENDPOINT=https://hf-mirror.com

python3 -c "
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
import timm, torch
model = timm.create_model('vit_base_patch16_224', pretrained=True)
model.eval()
torch.save(model.state_dict(), '/home/zy/vit-a3/vit_base_patch16_224_weights.pth')
print('Weights saved. Params:', sum(p.numel() for p in model.parameters()) / 1e6, 'M')
"

说明: 使用 hf-mirror.com 镜像是因为当前环境无法直接访问 huggingface.co。如网络通畅可去掉 HF_ENDPOINT 设置。

2.3 验证数据集

属性值
数据集ImageNet-1k (ILSVRC 2012) 验证集
样本数50,000 张
类别数1,000
每类样本50 张
HuggingFace 数据集页https://huggingface.co/datasets/Tsomaros/Imagenet-1k_validation
格式Parquet (15 个分片文件)
总大小~7.9 GB
本地路径/home/zy/vit-a3/imagenet_val/

获取方式:

mkdir -p /home/zy/vit-a3/imagenet_val
cd /home/zy/vit-a3/imagenet_val

for i in $(seq 0 14); do
  fname=$(printf "validation-%05d-of-00015.parquet" $i)
  wget -O "$fname" \
    "https://hf-mirror.com/datasets/Tsomaros/Imagenet-1k_validation/resolve/main/data/$fname"
done

验证数据完整性:

python3 -c "
import pyarrow.parquet as pq, os
from collections import Counter
total, labels = 0, []
for f in sorted(os.listdir('/home/zy/vit-a3/imagenet_val')):
    if f.startswith('validation-') and f.endswith('.parquet'):
        t = pq.read_table(os.path.join('/home/zy/vit-a3/imagenet_val', f))
        total += t.num_rows
        labels.extend(t.column('label').to_pylist())
lc = Counter(labels)
print(f'Total: {total}, Classes: {len(lc)}, Per class: {Counter(lc.values())}')
"

预期输出: Total: 50000, Classes: 1000, Per class: Counter({50: 1000})

2.4 软件依赖

组件版本用途
torch2.1.0PyTorch 框架(环境预装)
torch_npu2.1.0.post17昇腾 NPU 适配插件(环境预装)
timm1.0.19模型实现(ViT 源码)
transformers4.44.0Hugging Face 工具库
torchvision0.16.0图像预处理 transforms
numpy1.26.0数值计算
Pillow12.2.0图像解码
pyarrow24.0.0Parquet 文件读取

3. 环境信息

3.1 硬件环境

属性值
NPU 型号Ascend 910C
NPU 数量8 卡
单卡 HBM65536 MB
驱动版本25.5.1
CANN 版本9.0.0

获取方式: 执行 npu-smi info 查看 NPU 信息,执行 cat /usr/local/Ascend/driver/version.info 查看驱动版本。

3.2 软件环境

组件版本
操作系统Linux (aarch64)
Python3.11.15
PyTorch2.1.0
torch_npu2.1.0.post17

获取方式: 执行 python3 --version 和 pip3 list | grep -iE "torch|timm|transform" 查看。

3.3 环境搭建

配置昇腾CANN环境,安装CANN镜像:

docker run -it -u root -d --net=host \
--privileged \
--ipc=host \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/sbin:/usr/local/sbin \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
--name zy-a3-ubuntu \
quay.io/ascend/cann:9.0.0-a3-ubuntu22.04-py3.11 \
/bin/bash

依赖安装:

# 激活 CANN 环境(每次执行脚本前必须执行)
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 安装 timm(模型实现)
pip install --no-deps timm==1.0.19 -i https://pypi.tuna.tsinghua.edu.cn/simple

# 安装 torchvision(图像预处理,匹配 torch 2.1.0)
pip install --no-deps torchvision==0.16.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

# 安装 transformers 及其依赖
pip install --no-deps "transformers>=4.44.0" -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install --no-deps "tokenizers>=0.19,<0.20" -i https://pypi.tuna.tsinghua.edu.cn/simple

# 安装数据处理依赖
pip install --no-deps Pillow pyarrow numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

说明: 使用 --no-deps 是因为环境中已有 torch 2.1.0 和 torch_npu 2.1.0.post17 的预装组合,避免 pip 自动升级破坏兼容性。


4. 官方标准 Benchmark 指标

4.1 精度指标

来源: timm 官方 results-imagenet.csv

  • URL: https://github.com/huggingface/pytorch-image-models/blob/main/results/results-imagenet.csv
  • 模型条目: vit_base_patch16_224.augreg2_in21k_ft_in1k
  • CSV 原始行: vit_base_patch16_224.augreg2_in21k_ft_in1k,224,85.108,14.892,97.530,2.470,86.57,0.900,bicubic
指标官方值
Top-1 Accuracy85.108%
Top-5 Accuracy97.530%
参数量86.57M
输入分辨率224×224
Crop Pct0.900
插值方式bicubic

4.2 官方评估条件

  • 数据集: ImageNet-1k 验证集 (50,000 张, 1000 类)
  • 预处理: Resize(256, bicubic) → CenterCrop(224) → Normalize(mean=0.5, std=0.5)
  • 评估设备: GPU(具体型号 timm 未公开)
  • 推理框架: PyTorch + timm
  • 推理速度: timm 官方未公开(因 GPU 型号各异)

5. NPU迁移完整执行步骤

Step 1: 检查环境

# 检查 Python 版本
python3 --version

# 检查 NPU 状态
npu-smi info

# 检查驱动版本
cat /usr/local/Ascend/driver/version.info

# 激活 CANN 环境
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 验证 NPU 可用
python3 -c "
import torch, torch_npu
print('torch:', torch.__version__)
print('torch_npu:', torch_npu.__version__)
print('NPU available:', torch.npu.is_available())
print('NPU count:', torch.npu.device_count())
"

预期输出:

torch: 2.1.0
torch_npu: 2.1.0.post17
NPU available: True
NPU count: 16

步骤 2:安装依赖

source /usr/local/Ascend/ascend-toolkit/set_env.sh

pip install --no-deps timm==1.0.19 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install --no-deps torchvision==0.16.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install --no-deps Pillow pyarrow numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

验证安装:

python3 -c "
import timm, torchvision, PIL, pyarrow
print('timm:', timm.__version__)
print('torchvision:', torchvision.__version__)
print('Pillow:', PIL.__version__)
print('pyarrow:', pyarrow.__version__)
print('All imports OK')
"

步骤 3:下载模型权重

source /usr/local/Ascend/ascend-toolkit/set_env.sh
export HF_ENDPOINT=https://hf-mirror.com

python3 -c "
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'
import timm, torch
model = timm.create_model('vit_base_patch16_224', pretrained=True)
model.eval()
torch.save(model.state_dict(), '/home/zy/vit-a3/vit_base_patch16_224_weights.pth')
print('Weights saved. Params:', sum(p.numel() for p in model.parameters()) / 1e6, 'M')
"

预期输出:

Weights saved. Params: 86.567656 M

验证:ls -lh /home/zy/vit-a3/vit_base_patch16_224_weights.pth → 约 331MB

步骤 4:下载验证数据集

mkdir -p /home/zy/vit-a3/imagenet_val
cd /home/zy/vit-a3/imagenet_val

for i in $(seq 0 14); do
  fname=$(printf "validation-%05d-of-00015.parquet" $i)
  echo "Downloading $fname ..."
  wget -q --show-progress -O "$fname" \
    "https://hf-mirror.com/datasets/Tsomaros/Imagenet-1k_validation/resolve/main/data/$fname"
done

echo "Download complete"
ls -lh *.parquet | wc -l
du -sh .

预期输出: 15 个 parquet 文件,总计约 7.9GB

验证数据完整性:

python3 -c "
import pyarrow.parquet as pq, os
from collections import Counter
total, labels = 0, []
for f in sorted(os.listdir('/home/zy/vit-a3/imagenet_val')):
    if f.startswith('validation-') and f.endswith('.parquet'):
        t = pq.read_table(os.path.join('/home/zy/vit-a3/imagenet_val', f))
        total += t.num_rows
        labels.extend(t.column('label').to_pylist())
lc = Counter(labels)
print(f'Total: {total}, Classes: {len(lc)}, Per class: {Counter(lc.values())}')
"

预期输出: Total: 50000, Classes: 1000, Per class: Counter({50: 1000})

步骤 5:编写 NPU 推理脚本

5a. 基准测试脚本(benchmark_npu.py)

用于在完整验证集上采集聚合指标(Top-1/Top-5 精度、平均延迟、吞吐量),不展示单张图片的推理结果。

脚本核心逻辑:

  1. 通过 import torch_npu 注册 NPU 后端
  2. 使用 timm.create_model() 创建 ViT-B/16 模型结构
  3. 加载本地权重文件
  4. 使用 torch.device('npu:0') 将模型迁移到 NPU
  5. 预处理与官方一致:Resize(256, bicubic) → CenterCrop(224) → Normalize(0.5, 0.5)
  6. 逐批次推理,使用 torch.npu.synchronize() 同步后计时
  7. 前 N 个批次作为热身(warmup)不计入延迟统计
  8. 统计 Top-1/Top-5 精度、平均延迟、吞吐量

5b. 推理展示脚本(inference_demo_npu.py)

用于逐张图片展示具体推理结果,包括:真实类别名、预测类别名、Top-K 预测及置信度、正确/错误标记。适合验证模型是否真正“认识”图片内容,而不仅仅是看聚合数字。

脚本核心逻辑:

  1. 与基准测试脚本相同的模型加载和 NPU 迁移方式
  2. 支持 --stride 参数跨类别采样(如 stride=50 则每类取 1 张,避免同类重复)
  3. 对每张图片输出 Top-K 预测结果及 softmax 概率
  4. 读取 imagenet_class_names.txt 将类别索引映射为可读英文类别名
  5. 结果同时输出到终端和 JSON 文件

5c. 类别名映射文件(imagenet_class_names.txt)

ImageNet-1k 的标签是 0-999 的数字索引,不可直接阅读。imagenet_class_names.txt 提供 1000 行英文类别名,每行对应一个索引(如第 0 行 tench、第 1 行 goldfish、第 2 行 great white shark)。inference_demo_npu.py 读取此文件,在输出中显示可读的类别名。

来源:GitHub anishathalye/imagenet-simple-labels(https://github.com/anishathalye/imagenet-simple-labels/blob/master/imagenet-simple-labels.json)

步骤 7:执行 NPU 推理基准测试

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

python3 /home/zy/vit-a3/benchmark_npu.py \
    --data-dir /home/zy/vit-a3/imagenet_val \
    --model vit_base_patch16_224 \
    --weights /home/zy/vit-a3/vit_base_patch16_224_weights.pth \
    --batch-size 64 \
    --device-id 0 \
    --warmup 20 \
    --output /home/zy/vit-a3/benchmark_npu_results.json

参数说明:

  • --batch-size 64: 每批 64 张图片
  • --warmup 20: 前 20 个 batch(1280 张)作为预热,不计入延迟统计
  • --device-id 0: 使用第 0 号 NPU
  • --max-samples N: 可选,仅推理前 N 张(用于快速验证)

预期输出:

NPU available: True
NPU count: 16
Using NPU: 0 - Ascend910_9362
Loading model: vit_base_patch16_224
Model loaded. Parameters: 86.57M
Loading ImageNet validation set from /home/zy/vit-a3/imagenet_val
Loaded 50000 images, 1000 classes
Running NPU benchmark (batch_size=64, warmup=20)...
  Batch 50/782,  Top-1: 87.81%, Top-5: 98.22%
  Batch 100/782, Top-1: 88.89%, Top-5: 98.19%
  ...
  Batch 782/782, Top-1: 85.22%, Top-5: 97.47%

=== NPU Benchmark Results ===
Device: Ascend910_9362
Top-1 Accuracy: 85.22%
Top-5 Accuracy: 97.47%
Avg Latency: 0.81 ms/sample
Throughput: 1232.63 samples/s
Total Time: 225.67 s
Results saved to /home/zy/vit-a3/benchmark_npu_results.json

步骤 8:查看结果并对比

cat /home/zy/vit-a3/benchmark_npu_results.json

输出内容:

{
  "top1_accuracy": 85.218,
  "top5_accuracy": 97.472,
  "avg_latency_ms": 0.811,
  "throughput_fps": 1232.63,
  "total_samples": 50000,
  "warmup_batches": 20,
  "device": "NPU:0",
  "npu_name": "Ascend910_9362",
  "total_time_s": 225.67
}

步骤 9:查看逐张图片推理结果

benchmark_npu.py 仅输出聚合指标。若需查看每张图片的具体预测结果(类别名、Top-5 置信度等),请运行展示脚本:

前置条件:需先准备 imagenet_class_names.txt(1000 类英文名映射文件)。 获取方式:

python3 -c "
import json, urllib.request
url = 'https://raw.githubusercontent.com/anishathalye/imagenet-simple-labels/master/imagenet-simple-labels.json'
with urllib.request.urlopen(url, timeout=10) as resp:
 labels = json.loads(resp.read().decode())
with open('/home/zy/vit-a3/imagenet_class_names.txt', 'w') as f:
 for l in labels:
     f.write(l + '\n')
print(f'Saved {len(labels)} class names')
"
source /usr/local/Ascend/ascend-toolkit/set_env.sh
export OPENBLAS_NUM_THREADS=1
export OMP_NUM_THREADS=1

python3 /home/zy/vit-a3/inference_demo_npu.py \
    --num-samples 20 \
    --stride 50 \
    --top-k 5 \
    --output /home/zy/vit-a3/inference_demo_results.json

参数说明:

  • --num-samples 20: 展示 20 张图片
  • --stride 50: 每隔 50 张取 1 张(即每类取第 1 张,覆盖不同类别)
  • --top-k 5: 每张图展示 Top-5 预测
  • --start-idx 0: 起始索引(默认 0)

输出示例:

--- Image 1/20 [CORRECT] ---
  Ground Truth: [0] tench
  Prediction:   [0] tench  (conf: 53.03%)
  Top-5 predictions:
    1. [   0] tench                                     53.03%
    2. [ 394] sturgeon                                  10.28%
    ...

--- Image 3/20 [CORRECT] ---
  Ground Truth: [2] great white shark
  Prediction:   [2] great white shark  (conf: 74.37%)
  ...

Summary: 20/20 correct (100.0%)
Detailed results saved to: inference_demo_results.json

6. 昇腾 NPU 推理结果

6.1 精度指标

NPU 数据来源: 执行脚本 python3 benchmark_npu.py --batch-size 64 --warmup 20 结果文件: benchmark_npu_results.json 测试数据: imagenet_val/(ImageNet-1k 验证集,50,000 张,1,000 类,每类 50 张) 模型: vit_base_patch16_224_weights.pth(HuggingFace timm/vit_base_patch16_224.augreg2_in21k_ft_in1k) 评估设备: Ascend910_9362 (NPU:0)

指标NPU 结果
Top-1 准确率85.218%
Top-5 准确率97.472%
评估样本数50,000

6.2 性能指标

NPU 数据来源: 执行脚本 python3 benchmark_npu.py --batch-size 64 --warmup 20,预热后逐批次计时取平均值 结果文件: benchmark_npu_results.json

指标NPU 结果
平均延迟0.81 毫秒/样本
吞吐量1,232.63 样本/秒
总耗时225.67 秒
批次大小64
预热批次20(1,280 张,不计入延迟统计)

7. 指标对比分析

7.1 精度对比

官方指标来源: timm 官方 results-imagenet.csv(https://github.com/huggingface/pytorch-image-models/blob/main/results/results-imagenet.csv),条目 vit_base_patch16_224.augreg2_in21k_ft_in1k,获取方式见步骤 5 NPU 指标来源: 执行脚本 python3 benchmark_npu.py --batch-size 64 --warmup 20,在 ImageNet-1k 验证集(50,000 张,1,000 类)上完整评估 结果文件: benchmark_npu_results.json

指标官方 (timm results-imagenet.csv)NPU (Ascend 910)
Top-1 准确率85.108%85.218%
Top-5 准确率97.530%97.472%

7.2 性能对比

NPU 数据来源: 执行脚本 python3 benchmark_npu.py --batch-size 64 --warmup 20 官方性能数据: timm 官方未公开推理速度指标(因 GPU 型号各异),故仅提供 NPU 实测值作为参考基准

指标NPU (Ascend 910)
平均延迟0.81 毫秒/样本
吞吐量1,232.63 样本/秒
批次大小64

7.3 对比结论

  1. 精度完全对齐:NPU 上 Top-1 精度 85.218% 与官方 85.108% 基本一致(差异 +0.11%,在浮点误差范围内),Top-5 精度 97.472% 与官方 97.530% 差异仅 -0.058%。迁移后模型精度无损。

  2. 推理性能良好:在 Ascend 910 上,ViT-B/16 单张图片推理延迟仅 0.81ms,吞吐量达 1,232.63 samples/s(batch_size=64),满足实时推理需求。

  3. 迁移成本低:通过 torch_npu 插件,仅需修改设备指定和同步调用代码,模型结构和权重完全无需修改,实现了 零代码侵入 的迁移。


8. NPU 适配方案说明

8.1 适配策略

采用 torch_npu 适配方案,通过昇腾提供的 PyTorch NPU 插件实现无缝迁移:

修改点原始 (GPU)适配后 (NPU)
导入-import torch_npu
设备torch.device('cuda')torch.device('npu:0')
同步torch.cuda.synchronize()torch.npu.synchronize()
模型迁移model.to('cuda')model.to('npu:0')
算子PyTorch 原生torch_npu 自动映射

8.2 关键代码片段

import torch_npu                           # 注册 NPU 后端
device = torch.device(f'npu:{device_id}')  # 选择 NPU 设备
model = model.to(device)                   # 模型迁移到 NPU
torch.npu.synchronize()                    # NPU 同步(精确计时)

9. 文件清单

文件路径说明
NPU Benchmark 脚本benchmark_npu.py全量验证集推理 + 聚合精度/性能采集,输出 Top-1/Top-5 精度、延迟、吞吐量
NPU 推理展示脚本inference_demo_npu.py逐张图片推理结果展示,输出每张图片的真实类别、预测类别、Top-K 置信度,支持跨类别采样
模型权重vit_base_patch16_224_weights.pthViT-B/16 已微调权重 (331MB),来源: HuggingFace timm/vit_base_patch16_224.augreg2_in21k_ft_in1k,可直接用于 1000 类图像分类推理
NPU 结果benchmark_npu_results.jsonNPU 推理聚合指标 JSON,由 benchmark_npu.py 生成
推理展示结果inference_demo_results.json逐张图片推理详情 JSON(含 Top-K 预测),由 inference_demo_npu.py 生成
类别名映射imagenet_class_names.txtImageNet-1k 1000 类英文名(每行一个,行号=类别索引),供 inference_demo_npu.py 读取以显示可读类别名。来源: GitHub anishathalye/imagenet-simple-labels
验证数据集imagenet_val/ImageNet-1k 验证集 (15 个 Parquet, ~7.9GB),来源: HuggingFace Tsomaros/Imagenet-1k_validation