目前,众多的深度学习算法采用PyTorch框架开发,通常是在CPU或者英伟达的GPU运行,为了使这些程序能够利用在昇腾AI处理器上运行,需要对PyTorch模型进行迁移。
PyTorch适配昇腾AI处理器

PyTorch框架对接适配昇腾AI处理器的方案为在线对接方案。 当前选择在线对接适配方案的主要原因有以下几点:
- 最大限度的继承PyTorch框架动态图的特性。
- 最大限度的继承GPU在PyTorch上的使用方式,可以使用户在将模型移植到昇腾AI处理器设备进行训练时,在开发方式和代码重用方面做到最小的改动。
- 最大限度的继承PyTorch原生的体系结构,保留框架本身出色的特性,比如自动微分、动态分发、Debug、Profiling、Storage共享机制以及设备侧的动态内存管理等。
- 扩展性好。在打通流程的通路之上,对于新增的网络类型或结构,只需涉及相关计算类算子的开发和实现。框架类算子,反向图建立和实现机制等结构可保持复用。
- 与GPU的使用方式和风格保持一致。用户在使用在线对接方案时,只需在Python侧和device相关操作中,指定device为昇腾AI处理器,即可完成用昇腾AI处理器在PyTorch对网络的开发、训练以及调试,用户无需进一步关注昇腾AI处理器具体的底层细节。这样可以确保用户的修改最小化,迁移成本较低。
昇腾AI处理器
昇腾AI处理器在硬件体系结构上深度神经网络进行了特殊的优化,其主要的架构组成部件包括AI CPU、控制CPU、AI Core、任务调度器和数字视觉预处理模块。
- 控制CPU用于控制处理器整体运行;而AI CPU用于承担非矩阵类复杂计算。
- AI Core是处理器的算力担当,采用达芬奇架构实现了高通量、大算力和低功耗,特别适合处理深度学习中神将网络必须的常用计算,如矩阵乘法等。
- 任务调度器是实现计算任务在AI Core上的高效分配和调度的专用CPU。
- 数字视觉预处理模块(Digital Vision Pre-Processing,DVPP)实现图像的格式

昇腾AI处理器的计算核心主要由AI Core构成,负责执行标量、向量和张量相关的计算密集型算子,采用达芬奇架构。包含了三种基础计算资源:矩阵计算单元(Cube Unit)、向量计算单元(Vector Unit)和标量计算单元(Scalar Unit)。矩阵计算单元负责执行矩阵运算,每次可以执行完成一个fp16的16*16与16*16的矩阵乘法,涵盖matmul、conv2d、linear等操作;向量计算单元负责执行向量运算,算力低于矩阵计算单元但是灵活度高,涵盖各种基本的计算类型和许多定制的计算类型,主要包括fp16,fp32,int32,int8等;标量计算单元负责各类标量运算和程序的流程控制。
此外还有片上缓冲区、储存转换单元、控制单元等。存储单元为各个计算单元提供被转置过并符合要求的数据, 计算单元返回运算的结果给存储单元, 控制单元为计算单元和存储单元提供指令控制, 三者相互协调合作完成计算任务。
PyTorch模型迁移
目前业界较为常用的深度学习框架为PyTorch,为了使基于PyTorch开发的算法模型可以在昇腾NPU设备上运行,需要对模型进行迁移。

上图展示了模型迁移的全流程包括脚本迁移、模型训练、精度调优、性能调优、模型固化五个过程。
- 脚本迁移是对PyTorch训练脚本进行少量修改,使其可以在昇腾AI处理器上运行。
- 模型训练是通过训练数据对网络权重进行迭代优化,并在训练过程中评估模型准确度。
- 精度调优是对GPU和NPU模型精度进行对比,通过检查代码和超参、检查模型结构、检查输入数据、检查损失函数曲线等方法判断NPU模型的精度是否达到预期。
- 性能调优是对NPU模型的运行性能进行优化,常用的方法有使用自动混合精度、替换亲和接口、使用AOE工具对网络进行子图调优、算子调优与梯度优化等。
脚本迁移
将基于PyTorch的训练脚本迁移到昇腾AI处理器上进行训练,目前有以下3种方式:自动迁移(推荐)、工具迁移、手工迁移,且迁移前要保证该脚本能在GPU、CPU上运行。
自动迁移
在训练脚本中导入脚本转换库,然后运行脚本进行训练。脚本在运行时会自动将CUDA接口替换为昇腾AI处理器支持的NPU接口,整体过程为边训练边转换。(该方法仅支持PyTorch1.8及以上版本)
工具迁移
使用脚本迁移工具将训练脚本中的CUDA接口替换为昇腾AI处理器支持的NPU接口,并生成迁移报告(脚本转换日志、不支持算子列表、脚本修改记录),整体过程为先转换脚本再进行训练。
安装依赖
进入迁移工具所在路径
进入分析迁移工具所在路径,执行脚本迁移任务。
参数说明查看工具迁移
查看结果文件。
手工迁移
手工迁移直接将脚本中与GPU相关的库、接口、配置等修改为NPU相关的库、接口、配置等。
手工迁移前,若PyTorch代码中多卡训练采用的是DP方法,需要将DP改为DDP。
在迁移过程中可能会遇到失败的情况,所以在手工迁移时可以通过打点、hook以及查看Host日志的方式查看错误信息。
混合精度
混合精度训练是在训练时混合使用单精度(float32)与半精度(float16)数据类型,将两者结合在一起,并使用相同的超参数实现了与float32几乎相同的精度。在迁移完成、训练开始之前,基于NPU芯片的架构特性,开启混合精度可以提升模型的性能。可以通过使用PyTorch1.8.1及以上版本框架内置的AMP功能模块来使能混合精度训练,代码实现如下。
引入相关模块
在模型、优化器定义之后,定义AMP功能中的GradScaler。
在训练代码中添加AMP功能相关的代码开启AMP。
相关原理可以参考自动混合精度
模型训练
迁移成功后的脚本可在昇腾AI处理器上执行单卡训练,也可以在多卡上执行分布式训练。 在分布式训练中,性能随着启动方式的不同而不同,性能从低到高依次为:
python -m torch.distributed.lanunch --nproc_per_node=*--master_port=*
mp.spwan
-
目前,众多的深度学习算法采用PyTorch框架开发,通常是在CPU或者英伟达的GPU运行,为了使这些程序能够利用在昇腾AI处理器上运行,需要对PyTorch模型进行迁移。
PyTorch适配昇腾AI处理器
PyTorch框架对接适配昇腾AI处理器的方案为在线对接方案。 当前选择在线对接适配方案的主要原因有以下几点:
昇腾AI处理器
昇腾AI处理器在硬件体系结构上深度神经网络进行了特殊的优化,其主要的架构组成部件包括AI CPU、控制CPU、AI Core、任务调度器和数字视觉预处理模块。
昇腾AI处理器的计算核心主要由AI Core构成,负责执行标量、向量和张量相关的计算密集型算子,采用达芬奇架构。包含了三种基础计算资源:矩阵计算单元(Cube Unit)、向量计算单元(Vector Unit)和标量计算单元(Scalar Unit)。矩阵计算单元负责执行矩阵运算,每次可以执行完成一个fp16的16*16与16*16的矩阵乘法,涵盖matmul、conv2d、linear等操作;向量计算单元负责执行向量运算,算力低于矩阵计算单元但是灵活度高,涵盖各种基本的计算类型和许多定制的计算类型,主要包括fp16,fp32,int32,int8等;标量计算单元负责各类标量运算和程序的流程控制。
此外还有片上缓冲区、储存转换单元、控制单元等。存储单元为各个计算单元提供被转置过并符合要求的数据, 计算单元返回运算的结果给存储单元, 控制单元为计算单元和存储单元提供指令控制, 三者相互协调合作完成计算任务。
PyTorch模型迁移
目前业界较为常用的深度学习框架为PyTorch,为了使基于PyTorch开发的算法模型可以在昇腾NPU设备上运行,需要对模型进行迁移。
上图展示了模型迁移的全流程包括脚本迁移、模型训练、精度调优、性能调优、模型固化五个过程。
脚本迁移
将基于PyTorch的训练脚本迁移到昇腾AI处理器上进行训练,目前有以下3种方式:自动迁移(推荐)、工具迁移、手工迁移,且迁移前要保证该脚本能在GPU、CPU上运行。
自动迁移
在训练脚本中导入脚本转换库,然后运行脚本进行训练。脚本在运行时会自动将CUDA接口替换为昇腾AI处理器支持的NPU接口,整体过程为边训练边转换。(该方法仅支持PyTorch1.8及以上版本)
工具迁移
使用脚本迁移工具将训练脚本中的CUDA接口替换为昇腾AI处理器支持的NPU接口,并生成迁移报告(脚本转换日志、不支持算子列表、脚本修改记录),整体过程为先转换脚本再进行训练。
安装依赖
进入迁移工具所在路径
进入分析迁移工具所在路径,执行脚本迁移任务。
参数说明查看工具迁移
查看结果文件。
手工迁移
手工迁移直接将脚本中与GPU相关的库、接口、配置等修改为NPU相关的库、接口、配置等。
手工迁移前,若PyTorch代码中多卡训练采用的是DP方法,需要将DP改为DDP。
单卡迁移
导入NPU库
指定NPU为训练设备
# .to(device)方式 # device = torch.device('cuda:{}'.format(args.gpu)) device = torch.device('npu:{}'.format(args.gpu)) # .cuda方式 # torch.cuda.set_device(args.gpu) torch_npu.npu.set_device(args.gpu)替换CUDA接口
多卡迁移 多卡代码迁移中,除了修改单卡中的各项外,还需要将通信方式由“nccl”切换为“hccl”。
在迁移过程中可能会遇到失败的情况,所以在手工迁移时可以通过打点、hook以及查看Host日志的方式查看错误信息。
混合精度
混合精度训练是在训练时混合使用单精度(float32)与半精度(float16)数据类型,将两者结合在一起,并使用相同的超参数实现了与float32几乎相同的精度。在迁移完成、训练开始之前,基于NPU芯片的架构特性,开启混合精度可以提升模型的性能。可以通过使用PyTorch1.8.1及以上版本框架内置的AMP功能模块来使能混合精度训练,代码实现如下。
引入相关模块
在模型、优化器定义之后,定义AMP功能中的GradScaler。
在训练代码中添加AMP功能相关的代码开启AMP。
for epo 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系数相关原理可以参考自动混合精度
模型训练
迁移成功后的脚本可在昇腾AI处理器上执行单卡训练,也可以在多卡上执行分布式训练。 在分布式训练中,性能随着启动方式的不同而不同,性能从低到高依次为:
python -m torch.distributed.lanunch --nproc_per_node=*--master_port=*mp.spwanfor i in $(seq 0 8) do taskset -c 0-24 python3.7 * done