典型场景是开启混合精度进行一般模型训练的场景。以下示例以一个简单的自定义模型为例,适配NPU需要注意和修改的内容已加粗标注。
在构建神经网络前,导入AMP模块至torch_npu中。
# 引入模块 import argparse import torch import torch_npu import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms # 导入AMP模块 from torch_npu.npu import amp
在模型、优化器定义之后,定义AMP功能中的GradScaler。
args = parse_args() transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)) ]) train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform = transform) # 数据集获取 train_loader = DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True) # 定义DataLoader device = torch.device("npu") model = ToyModel().to(device) # 把模型放到指定NPU上 criterion = nn.CrossEntropyLoss() # 定义损失函数 optimizer = optim.Adam(model.parameters(), lr=args.learning_rate) # 定义优化器 scaler = amp.GradScaler() # 在模型、优化器定义之后,定义GradScaler
在训练代码中添加AMP功能适配代码。
for epoch in range(args.epochs): model.train() for inputs, labels in train_loader: inputs, labels = data_process(inputs, labels) # 数据预处理,将数据集的数据转成需要的shape inputs, labels = inputs.to(device), labels.to(device) # 将数据转到NPU处理 with amp.autocast(): # 设置amp outputs = model(inputs) # 前向计算 loss = criterion(outputs, labels).to(device) # 损失函数计算 optimizer.zero_grad() # 进行反向传播前后的loss缩放、参数更新 scaler.scale(loss).backward() # loss缩放并反向转播 scaler.step(optimizer) # 更新参数(自动unscaling) scaler.update() # 基于动态Loss Scale更新loss_scaling系数