Vision Transformer (ViT) 是由 Google Research 提出的视觉 Transformer 模型,首次将 Transformer 架构直接应用于图像分类任务,取代传统的卷积神经网络(CNN)。
| 属性 | 值 |
|---|---|
| 模型名称 | vit_base_patch16_224 |
| 权重版本 | augreg2_in21k_ft_in1k |
| 参数量 | 86.57M |
| 输入分辨率 | 224×224 |
| Patch Size | 16×16 |
| GMACs | 16.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。
该权重由 Google 论文作者在 ImageNet-21k 上预训练,再由 Ross Wightman(timm 作者)使用 AugReg 策略在 ImageNet-1k 上微调。相关论文:
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)| 属性 | 值 |
|---|---|
| 文件名 | vit_base_patch16_224_weights.pth |
| 大小 | 331MB |
| HuggingFace 模型页 | https://huggingface.co/timm/vit_base_patch16_224.augreg2_in21k_ft_in1k |
| 权重文件 URL | https://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设置。
| 属性 | 值 |
|---|---|
| 数据集 | 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})
| 组件 | 版本 | 用途 |
|---|---|---|
| torch | 2.1.0 | PyTorch 框架(环境预装) |
| torch_npu | 2.1.0.post17 | 昇腾 NPU 适配插件(环境预装) |
| timm | 1.0.19 | 模型实现(ViT 源码) |
| transformers | 4.44.0 | Hugging Face 工具库 |
| torchvision | 0.16.0 | 图像预处理 transforms |
| numpy | 1.26.0 | 数值计算 |
| Pillow | 12.2.0 | 图像解码 |
| pyarrow | 24.0.0 | Parquet 文件读取 |
| 属性 | 值 |
|---|---|
| NPU 型号 | Ascend 910C |
| NPU 数量 | 8 卡 |
| 单卡 HBM | 65536 MB |
| 驱动版本 | 25.5.1 |
| CANN 版本 | 9.0.0 |
获取方式: 执行
npu-smi info查看 NPU 信息,执行cat /usr/local/Ascend/driver/version.info查看驱动版本。
| 组件 | 版本 |
|---|---|
| 操作系统 | Linux (aarch64) |
| Python | 3.11.15 |
| PyTorch | 2.1.0 |
| torch_npu | 2.1.0.post17 |
获取方式: 执行
python3 --version和pip3 list | grep -iE "torch|timm|transform"查看。
配置昇腾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 自动升级破坏兼容性。
来源: timm 官方 results-imagenet.csv
vit_base_patch16_224.augreg2_in21k_ft_in1kvit_base_patch16_224.augreg2_in21k_ft_in1k,224,85.108,14.892,97.530,2.470,86.57,0.900,bicubic| 指标 | 官方值 |
|---|---|
| Top-1 Accuracy | 85.108% |
| Top-5 Accuracy | 97.530% |
| 参数量 | 86.57M |
| 输入分辨率 | 224×224 |
| Crop Pct | 0.900 |
| 插值方式 | bicubic |
# 检查 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: 16source /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')
"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
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})
benchmark_npu.py)用于在完整验证集上采集聚合指标(Top-1/Top-5 精度、平均延迟、吞吐量),不展示单张图片的推理结果。
脚本核心逻辑:
import torch_npu 注册 NPU 后端timm.create_model() 创建 ViT-B/16 模型结构torch.device('npu:0') 将模型迁移到 NPUResize(256, bicubic) → CenterCrop(224) → Normalize(0.5, 0.5)torch.npu.synchronize() 同步后计时inference_demo_npu.py)用于逐张图片展示具体推理结果,包括:真实类别名、预测类别名、Top-K 预测及置信度、正确/错误标记。适合验证模型是否真正“认识”图片内容,而不仅仅是看聚合数字。
脚本核心逻辑:
--stride 参数跨类别采样(如 stride=50 则每类取 1 张,避免同类重复)imagenet_class_names.txt 将类别索引映射为可读英文类别名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)
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.jsoncat /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
}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.jsonNPU 数据来源: 执行脚本
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(HuggingFacetimm/vit_base_patch16_224.augreg2_in21k_ft_in1k) 评估设备: Ascend910_9362 (NPU:0)
| 指标 | NPU 结果 |
|---|---|
| Top-1 准确率 | 85.218% |
| Top-5 准确率 | 97.472% |
| 评估样本数 | 50,000 |
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 张,不计入延迟统计) |
官方指标来源: 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% |
NPU 数据来源: 执行脚本
python3 benchmark_npu.py --batch-size 64 --warmup 20官方性能数据: timm 官方未公开推理速度指标(因 GPU 型号各异),故仅提供 NPU 实测值作为参考基准
| 指标 | NPU (Ascend 910) |
|---|---|
| 平均延迟 | 0.81 毫秒/样本 |
| 吞吐量 | 1,232.63 样本/秒 |
| 批次大小 | 64 |
精度完全对齐:NPU 上 Top-1 精度 85.218% 与官方 85.108% 基本一致(差异 +0.11%,在浮点误差范围内),Top-5 精度 97.472% 与官方 97.530% 差异仅 -0.058%。迁移后模型精度无损。
推理性能良好:在 Ascend 910 上,ViT-B/16 单张图片推理延迟仅 0.81ms,吞吐量达 1,232.63 samples/s(batch_size=64),满足实时推理需求。
迁移成本低:通过 torch_npu 插件,仅需修改设备指定和同步调用代码,模型结构和权重完全无需修改,实现了 零代码侵入 的迁移。
采用 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 自动映射 |
import torch_npu # 注册 NPU 后端
device = torch.device(f'npu:{device_id}') # 选择 NPU 设备
model = model.to(device) # 模型迁移到 NPU
torch.npu.synchronize() # NPU 同步(精确计时)| 文件 | 路径 | 说明 |
|---|---|---|
| NPU Benchmark 脚本 | benchmark_npu.py | 全量验证集推理 + 聚合精度/性能采集,输出 Top-1/Top-5 精度、延迟、吞吐量 |
| NPU 推理展示脚本 | inference_demo_npu.py | 逐张图片推理结果展示,输出每张图片的真实类别、预测类别、Top-K 置信度,支持跨类别采样 |
| 模型权重 | vit_base_patch16_224_weights.pth | ViT-B/16 已微调权重 (331MB),来源: HuggingFace timm/vit_base_patch16_224.augreg2_in21k_ft_in1k,可直接用于 1000 类图像分类推理 |
| NPU 结果 | benchmark_npu_results.json | NPU 推理聚合指标 JSON,由 benchmark_npu.py 生成 |
| 推理展示结果 | inference_demo_results.json | 逐张图片推理详情 JSON(含 Top-K 预测),由 inference_demo_npu.py 生成 |
| 类别名映射 | imagenet_class_names.txt | ImageNet-1k 1000 类英文名(每行一个,行号=类别索引),供 inference_demo_npu.py 读取以显示可读类别名。来源: GitHub anishathalye/imagenet-simple-labels |
| 验证数据集 | imagenet_val/ | ImageNet-1k 验证集 (15 个 Parquet, ~7.9GB),来源: HuggingFace Tsomaros/Imagenet-1k_validation |