快速体验
本章将以CNN模型为例,在Atlas 800T A2 训练服务器上端到端的详细介绍如何进行迁移和训练PyTorch模型。
整体流程
检查环境
在昇腾平台上进行开发运行环境搭建前,首先需要检查安装环境的NPU(Neural-Network Processing Unit,神经网络处理器单元,此处NPU指昇腾AI处理器)是否正常在位。
以Atlas 800T A2 训练服务器为例,执行lspci | grep d802命令检查NPU是否正常在位,如果服务器上有N(N>0)路NPU芯片,回显中含“d802”字段的行数为N,则表示NPU正常在位。
1 2 3 4 5 6 7 8 |
01:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) 02:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) 41:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) 42:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) 81:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) 82:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) c1:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) c2:00.0 Processing accelerators: Huawei Technologies Co., Ltd. Device d802 (rev 20) |
准备软件包
下载NPU驱动和固件包以及配套版本的CANN开发套件包。下载本软件即表示您同意华为企业业务最终用户许可协议(EULA)的条款和条件。
其中<chip_type>代表昇腾AI处理器的型号。
安装驱动和固件
- 以root用户登录待安装环境,将驱动和固件包上传至安装环境的任意目录(如“/home/package”)。
- 创建驱动运行用户HwHiAiUser。
groupadd HwHiAiUser useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash
- 增加对软件包的可执行权限。
chmod +x Ascend-hdk-<chip_type>-npu-driver_24.1.rc3_linux-aarch64.run chmod +x Ascend-hdk-<chip_type>-npu-firmware_7.3.0.1.231.run
- 执行如下命令,校验安装包的一致性和完整性。
./Ascend-hdk-<chip_type>-npu-driver24.1.rc3_linux-aarch64.run --check ./Ascend-hdk-<chip_type>-npu-firmware_7.3.0.1.231.run --check
- 执行以下命令,完成驱动固件安装,软件包默认安装路径为“/usr/local/Ascend”。
- 安装驱动
./Ascend-hdk-<chip_type>-npu-driver_24.1.rc3_linux-aarch64.run --full --install-for-all
出现类似如下回显信息,表示驱动安装成功。1
Driver package installed successfully!
- 安装固件
./Ascend-hdk-<chip_type>-npu-firmware_7.3.0.1.231.run --full
出现类似如下回显信息,表示固件安装成功。1
Firmware package installed successfully!
- 安装驱动
- 驱动和固件安装完成后,请根据提示信息重启系统。
reboot
- 执行如下命令,查看驱动加载是否成功。
npu-smi info
若出现如下类似回显信息,说明加载成功,具体回显信息请以实际情况为准。
+-------------------------------------------------------------------------------------------+ | npu-smi 24.1.rc3 Version: 24.1.rc3 | +----------------------+---------------+----------------------------------------------------+ | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)| | Chip | Bus-Id | AICore(%) Memory-Usage(MB) xxx-Usage(MB) | +======================+===============+====================================================+ | 0 xxx | OK | 0.0 40 0 / 0 | | 0 | 0000:C1:00.0 | 0 882 / 15169 0 / 32768 | +======================+===============+====================================================+ | 1 xxx | OK | 0.0 35 0 / 0 | | 0 | 0000:81:00.0 | 0 1603 / 15169 0 / 32768 | +======================+===============+====================================================+ | 2 xxx | OK | 0.0 32 0 / 0 | | 0 | 0000:41:00.0 | 0 2440 / 15169 0 / 32768 | +======================+===============+====================================================+ | 3 xxx | OK | 0.0 40 0 / 0 | | 0 | 0000:01:00.0 | 0 1014 / 15071 0 / 32768 | +======================+===============+====================================================+ | 4 xxx | OK | 0.0 39 0 / 0 | | 0 | 0000:C2:00.0 | 0 457 / 15169 0 / 32768 | +======================+===============+====================================================+ | 5 xxx | OK | 0.0 33 0 / 0 | | 0 | 0000:82:00.0 | 0 523 / 15169 0 / 32768 | +======================+===============+====================================================+ | 6 xxx | OK | 0.0 31 0 / 0 | | 0 | 0000:42:00.0 | 0 2182 / 15169 0 / 32768 | +======================+===============+====================================================+ | 7 xxx | OK | 0.0 39 0 / 0 | | 0 | 0000:02:00.0 | 0 2771 / 15071 0 / 32768 | +======================+===============+====================================================+ | No running processes found in NPU 0 | +======================+===============+====================================================+ | No running processes found in NPU 1 | +======================+===============+====================================================+ | No running processes found in NPU 2 | +======================+===============+====================================================+ | No running processes found in NPU 3 | +======================+===============+====================================================+ | No running processes found in NPU 4 | +======================+===============+====================================================+ | No running processes found in NPU 5 | +======================+===============+====================================================+ | No running processes found in NPU 6 | +======================+===============+====================================================+ | No running processes found in NPU 7 | +======================+===============+====================================================+
- 执行如下命令查看芯片固件版本号。若与固件软件包版本号一致,则说明安装成功。
/usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --component -1 --version
如果安装驱动时指定安装路径,则命令中的“/usr/local/Ascend”请根据实际情况替换。
安装CANN
驱动固件安装完成后,就可以进行CANN软件包的安装了,本节以在昇腾AI处理器上安装开发套件包为例,介绍CANN软件安装的步骤。CANN开发套件包包含开发应用程序所需的库文件、开发辅助工具等,安装之后开发者可进行应用及自定义算子的开发。需要注意CANN开发套件包安装过程需要安装相关依赖,请确保安装环境能够连接外部网络,并已配置软件源,以下以root用户操作为例。
- 安装第三方依赖。
- Debian系列(Ubuntu、Debian、UOS20、UOS20 SP1):
apt-get install -y gcc make net-tools python3 python3-dev python3-pip
- openEuler系列(openEuler、CentOS、Kylin、BCLinux、BC-Linux-for-Euler、UOS201050e、UOS20 1020e、UOSV20、AntOS、CTyunOS、CULinux、Tlinux):
yum install -y gcc make net-tools python3 python3-devel python3-pip
- Debian系列(Ubuntu、Debian、UOS20、UOS20 SP1):
- 安装Python。
可执行如下命令检查系统是否安装满足要求的Python开发环境(支持Python3.8.x至3.11.4版本)。
python3 --version pip3 --version
如果返回信息满足Python版本要求,则直接进入下一步,若不满足请自行准备符合要求的Python环境。若后续需要安装PyTorch 2.1.0版本、PyTorch 2.3.1或者PyTorch 2.4.0的深度学习框架,Python版本需要为Python3.8.x至3.11.4。
- 执行如下命令安装所需的Python第三方库:root用户安装,执行如下命令:
pip3 install attrs cython numpy==1.24 decorator sympy cffi pyyaml pathlib2 psutil protobuf==3.20 scipy requests absl-py
非root用户安装,执行如下命令:
pip3 install attrs cython numpy==1.24 decorator sympy cffi pyyaml pathlib2 psutil protobuf==3.20 scipy requests absl-py --user
- 安装CANN开发套件包。
- 将CANN开发套件包上传至安装环境的任意目录,执行如下命令增加对软件包的可执行权限。
chmod +x Ascend-cann-toolkit_8.0.RC3_linux-aarch64.run
- 执行如下命令校验软件包的一致性和完整性。
./Ascend-cann-toolkit_8.0.RC3_linux-aarch64.run --check
- 执行如下命令安装CANN开发套件包。
./Ascend-cann-toolkit_8.0.RC3_linux-aarch64.run --install
用户需签署华为企业业务最终用户许可协议(EULA)后进入安装流程,根据回显页面输入y或Y接受协议,输入其他任意字符为拒绝协议,确认接受协议后开始安装。安装完成后,若显示如下信息,则说明软件安装成功。
1
[INFO] Ascend-cann-toolkit install success
- 配置CANN环境变量。
source /usr/local/Ascend/ascend-toolkit/set_env.sh
- 将CANN开发套件包上传至安装环境的任意目录,执行如下命令增加对软件包的可执行权限。
安装PyTorch框架及Ascend Extension for PyTorch插件
本节介绍了在操作系统架构为aarch64、python版本为3.9.x的环境下,安装PyTorch 2.1.0的操作步骤,更多场景请参考《Ascend Extension for PyTorch 配置与安装》。
- 下载并安装官方2.1.0版本torch包。
# 下载官方torch包 wget https://download.pytorch.org/whl/cpu/torch-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl --no-check-certificate # 安装官方torch包 pip3 install torch-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- 下载并安装昇腾提供的2.1.0版本的PyTorch适配插件Ascend Extension for PyTorch。
# 下载Ascend Extension for PyTorch插件包 wget https://gitee.com/ascend/pytorch/releases/download/v6.0.rc3-pytorch2.1.0/torch_npu-2.1.0.post8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl --no-check-certificate # 安装Ascend Extension for PyTorch插件包 pip3 install torch_npu-2.1.0.post8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- 安装后验证。
执行如下命令,验证是否可正常导入PyTorch以及Ascend Extension for PyTorch的python库,若返回True则说明安装成功。
python3 -c "import torch;import torch_npu;print(torch_npu.npu.is_available())"
- 安装PyTorch扩展库torchvision,用于处理计算机视觉相关任务。
pip3 install torchvision==0.16.0
模型迁移训练
本节提供了一个简单的模型迁移样例,采用了最简单的自动迁移方法,帮助用户快速体验GPU模型脚本迁移到昇腾NPU上的流程,将在GPU上训练CNN模型识别手写数字的脚本代码进行修改,使其可以迁移到昇腾NPU上进行训练。
- 新建脚本train.py,写入以下原GPU脚本代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
# 引入模块 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 # 使能自动迁移
- 使能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
删除以下加粗部分的原GPU脚本代码。...... 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() # 更新优化器
添加以下加粗部分代码开启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
训练结束后生成如下图权重文件,则说明迁移训练成功。