快速体验
在介绍迁移和训练模型的步骤之前,本章节提供了一个简单的模型迁移样例,采用了最简单的自动迁移方法,帮助用户快速体验GPU模型脚本迁移到昇腾NPU上的流程,将在GPU上训练CNN模型识别手写数字的脚本代码进行修改,使其可以迁移到昇腾NPU上进行训练。
原脚本代码
新建脚本train.py,写入以下原GPU脚本代码。
# 引入模块
import time
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import torchvision
# 初始化运行device
device = torch.device('cuda:0')
# 定义模型网络
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.net = nn.Sequential(
# 卷积层
nn.Conv2d(in_channels=1, out_channels=16,
kernel_size=(3, 3),
stride=(1, 1),
padding=1),
# 池化层
nn.MaxPool2d(kernel_size=2),
# 卷积层
nn.Conv2d(16, 32, 3, 1, 1),
# 池化层
nn.MaxPool2d(2),
# 将多维输入一维化
nn.Flatten(),
nn.Linear(32*7*7, 16),
# 激活函数
nn.ReLU(),
nn.Linear(16, 10)
)
def forward(self, x):
return self.net(x)
# 下载数据集
train_data = torchvision.datasets.MNIST(
root='mnist',
download=True,
train=True,
transform=torchvision.transforms.ToTensor()
)
# 定义训练相关参数
batch_size = 64
model = CNN().to(device) # 定义模型
train_dataloader = DataLoader(train_data, batch_size=batch_size) # 定义DataLoader
loss_func = nn.CrossEntropyLoss().to(device) # 定义损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=0.1) # 定义优化器
epochs = 10 # 设置循环次数
# 设置循环
for epoch in range(epochs):
for imgs, labels in train_dataloader:
start_time = time.time() # 记录训练开始时间
imgs = imgs.to(device) # 把img数据放到指定NPU上
labels = labels.to(device) # 把label数据放到指定NPU上
outputs = model(imgs) # 前向计算
loss = loss_func(outputs, labels) # 损失函数计算
optimizer.zero_grad()
loss.backward() # 损失函数反向计算
optimizer.step() # 更新优化器
# 定义保存模型
torch.save({
'epoch': 10,
'arch': CNN,
'state_dict': model.state_dict(),
'optimizer' : optimizer.state_dict(),
},'checkpoint.pth.tar')
迁移体验
在train.py中做以下修改:
- 首先添加以下加粗部分库代码。
- 若用户使用Atlas 训练系列产品,由于其架构特性限制,用户在训练时需要开启混合精度(AMP),可以提升模型的性能。具体介绍可参见《PyTorch 训练模型迁移调优指南》中的“迁移适配 > 模型训练适配 > 关键特性适配 > 混合精度适配(可选)”章节。
- 若用户使用Atlas A2 训练系列产品,则可以选择不开启混合精度(AMP)。
import time import torch ...... import torch_npu from torch_npu.npu import amp # 导入AMP模块 from torch_npu.contrib import transfer_to_npu # 使能自动迁移
若未使能自动迁移,用户可参考《PyTorch 训练模型迁移调优指南》中的“迁移适配 > 模型脚本迁移 > 手工迁移”章节进行相关操作。
- 使能AMP混合精度计算。若用户使用Atlas A2 训练系列产品,则可以选择跳过此步骤。在模型、优化器定义之后,定义AMP功能中的GradScaler。
...... loss_func = nn.CrossEntropyLoss().to(device) # 定义损失函数 optimizer = torch.optim.SGD(model.parameters(), lr=0.1) # 定义优化器 scaler = amp.GradScaler() # 在模型、优化器定义之后,定义GradScaler epochs = 10
这一部分我们在训练代码中添加AMP功能相关的代码开启AMP。...... for i in range(epochs): for imgs, labels in train_dataloader: imgs = imgs.to(device) labels = labels.to(device) with amp.autocast(): outputs = model(imgs) # 前向计算 loss = loss_func(outputs, labels) # 损失函数计算 optimizer.zero_grad() # 进行反向传播前后的loss缩放、参数更新 scaler.scale(loss).backward() # loss缩放并反向转播 scaler.step(optimizer) # 更新参数(自动unscaling) scaler.update() # 基于动态Loss Scale更新loss_scaling系数 - 执行命令启动训练脚本(命令脚本名称可根据实际修改)。
python3 train.py
训练结束后生成如下图权重文件,则说明迁移训练成功。
