快速开始
备注
阅读本篇前,请确保已按照 安装教程 准备好昇腾环境及 open_clip !
本文档帮助昇腾开发者快速使用 open_clip × 昇腾 进行训练和推理。
使用 NPU 的训练
首先在 src/training/main.py
脚本导入 torch 后,导入 torch-npu,并将 cuda 对应的 GradScaler
替换为 npu 的:
1import torch
2import torch-npu
3from torch.npu.amp import GradScaler
以 MS_COCO_2017_URL_TEXT
数据集的训练为例,使用在 DataComp
数据集训练过的 CLIP-ViT-B-32
模型权重为预训练权重,使用以下脚本启动单卡/多卡 NPU 上的训练:
单卡训练
备注
请根据实际情况指定数据集路径 train-data
、 val-data
、 imagenet-val
和预训练模型路径 pretrained
1python -m training.main \
2 --model ViT-B-32 \
3 --save-frequency 1 \
4 --zeroshot-frequency 1 \
5 --report-to tensorboard \
6 --train-data="./data/MS_COCO_2017_URL_TEXT/traincoco.csv" \
7 --val-data="./data/MS_COCO_2017_URL_TEXT/traincoco.csv" \
8 --imagenet-val="./data/ImageNet-1000/val/" \
9 --pretrained "./models/CLIP-ViT-B-32-256x256-DataComp-s34B-b86K/open_clip_pytorch_model.bin" \
10 --warmup 10000 \
11 --batch-size=128 \
12 --lr=1e-3 \
13 --wd=0.1 \
14 --epochs=8 \
15 --workers=8 \
16 --seed 0
分布式训练
使用 torchrun 启动 NPU 分布式训练,需指定通信后端为 hccl(--dist-backend="hccl"
):
备注
请根据实际情况指定数据集路径 train-data
、 val-data
、 imagenet-val
和预训练模型路径 pretrained
nproc_per_node
需指定为每个节点卡的数量,为 torchrun 所需参数,更多 torchrun 相关参数详细含义可参考 PyTorch 官方文档。
1# train on multi-npu
2torchrun --nproc_per_node 2 -m training.main \
3 --save-frequency 1 \
4 --zeroshot-frequency 1 \
5 --report-to tensorboard \
6 --train-data="./data/MS_COCO_2017_URL_TEXT/traincoco.csv" \
7 --val-data="./data/MS_COCO_2017_URL_TEXT/traincoco.csv" \
8 --imagenet-val="./data/ImageNet-1000/val/" \
9 --pretrained "./models/CLIP-ViT-B-32-256x256-DataComp-s34B-b86K/open_clip_pytorch_model.bin" \
10 --warmup 10000 \
11 --batch-size=64 \
12 --lr=1e-3 \
13 --wd=0.1 \
14 --epochs=1 \
15 --workers=8 \
16 --seed 0 \
17 --model ViT-B-32 \
18 --dist-backend="hccl"
使用 NPU 的推理
一般而言,自定义脚本中使用 open_clip 在昇腾上训练,需要导入 torch-npu,并将数据和模型放到 NPU 上,如下样例所示:
备注
请根据实际情况替换模型缓存路径 /path/to/modelsViT-B-32/
、 /path/to/models/ViT-B-32/ViT-B-32.pt
、 /path/to/your/image.jpg
1import torch
2import torch_npu
3from PIL import Image
4import open_clip as clip
5
6# 下载模型至指定缓存路径
7model = clip.openai.load_openai_model('ViT-B-32', cache_dir="/path/to/modelsViT-B-32/")
8
9model, _, preprocess = clip.create_model_and_transforms('ViT-B-32', pretrained='/path/to/models/ViT-B-32/ViT-B-32.pt')
10tokenizer = clip.get_tokenizer('ViT-B-32')
11
12# put inputs and model to npu
13image = preprocess(Image.open("/path/to/your/image.jpg")).unsqueeze(0).to("npu")
14text = tokenizer(["a diagram", "a dog", "a cat"]).to("npu")
15model = model.to("npu")
16
17with torch.no_grad(), torch.npu.amp.autocast():
18 image_features = model.encode_image(image)
19 text_features = model.encode_text(text)
20 image_features /= image_features.norm(dim=-1, keepdim=True)
21 text_features /= text_features.norm(dim=-1, keepdim=True)
22
23 text_probs = (100.0 * image_features @ text_features.T).softmax(dim=-1)
24
25print("Label probs:", text_probs) # prints: [[1., 0., 0.]]
本示例所用输入图像:
对应输出以下内容,正确预测其分类为 a dog:
Label probs: tensor([[0.0010, 0.9941, 0.0049]], device='npu:0')
模型评估
在 src/training/profiler.py
脚本导入 torch-npu,并将模型放到 NPU 上:
1import argparse
2
3import torch
4import torch_npu
5
6import open_clip
7import pandas as pd
8from torch.utils.flop_counter import FlopCounterMode
9
10... ...
11
12def profile_model(model_name, batch_size=1, profiler='torch'):
13 model.eval()
14 if torch.cuda.is_available():
15 model = model.cuda()
16 elif torch.npu.is_available():
17 model = model.npu()
使用以下指令完成模型评估:
1python3 -m training.profiler --model ViT-L-14 --results-file "./logs/profiler_results.csv"
评估结果保存在 ./logs/profiler_results.csv
文件中:
model,image_size,image_width,text_width,embed_dim,mparams,image_mparams,text_mparams,gflops,image_gflops,text_gflops
ViT-L-14,224,1024,768,768,427.62,303.97,123.65,175.33,162.03,13.3