分布式并行训练 (GPU)

Linux GPU 模型训练 中级 高级

概述

本篇教程我们主要讲解,如何在GPU硬件平台上,利用MindSpore的数据并行及自动并行模式训练ResNet-50网络。

准备环节

下载数据集

本样例采用CIFAR-10数据集,数据集的下载以及加载方式和Ascend 910 AI处理器一致。

数据集的下载和加载方式可参考:https://www.mindspore.cn/tutorial/training/zh-CN/r1.2/advanced_use/distributed_training_ascend.html

配置分布式环境

调用集合通信库

在GPU硬件平台上,MindSpore分布式并行训练的通信使用的是NCCL。

GPU平台上,MindSpore暂不支持用户进行:

get_local_rankget_local_sizeget_world_rank_from_group_rankget_group_rank_from_world_rankcreate_group操作。

下面是调用集合通信库的代码样例:

from mindspore import context
from mindspore.communication.management import init

if __name__ == "__main__":
    context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
    init("nccl")
    ...

其中,

  • mode=context.GRAPH_MODE:使用分布式训练需要指定运行模式为图模式(PyNative模式不支持并行)。

  • init("nccl"):使能NCCL通信,并完成分布式训练初始化操作。

定义网络

在GPU硬件平台上,网络的定义和Ascend 910 AI处理器一致。

网络、优化器、损失函数的定义可参考:https://www.mindspore.cn/tutorial/training/zh-CN/r1.2/advanced_use/distributed_training_ascend.html

运行脚本

在GPU硬件平台上,MindSpore采用OpenMPI的mpirun进行分布式训练。下面以使用8张卡的分布式训练脚本为例,演示如何运行脚本:

你可以在这里找到样例的运行脚本:

https://gitee.com/mindspore/docs/blob/r1.2/tutorials/tutorial_code/distributed_training/run_gpu.sh

如果通过root用户执行脚本,mpirun需要加上--allow-run-as-root参数。

#!/bin/bash

echo "=============================================================================================================="
echo "Please run the script as: "
echo "bash run_gpu.sh DATA_PATH"
echo "For example: bash run_gpu.sh /path/dataset"
echo "It is better to use the absolute path."
echo "=============================================================================================================="
DATA_PATH=$1
export DATA_PATH=${DATA_PATH}

rm -rf device
mkdir device
cp ./resnet50_distributed_training.py ./resnet.py ./device
cd ./device
echo "start training"
mpirun -n 8 pytest -s -v ./resnet50_distributed_training.py > train.log 2>&1 &

脚本会在后台运行,日志文件会保存到device目录下,共跑了10个epoch,每个epoch有234个step,关于Loss部分结果保存在train.log中。将loss值grep出来后,示例如下:

epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854
epoch: 1 step: 1, loss is 2.3025854

运行多机脚本

若训练涉及多机,则需要额外在mpirun命令中设置多机配置。你可以直接在mpirun命令中用-H选项进行设置,比如mpirun -n 16 -H DEVICE1_IP:8,DEVICE2_IP:8 python hello.py,表示在ip为DEVICE1_IP和DEVICE2_IP的机器上分别起8个进程运行程序;或者也可以构造一个如下这样的hostfile文件,并将其路径传给mpirun--hostfile的选项。hostfile文件每一行格式为[hostname] slots=[slotnum],hostname可以是ip或者主机名。

DEVICE1 slots=8
DEVICE2 slots=8

两机十六卡的执行脚本如下,需要传入变量DATA_PATHHOSTFILE,表示数据集的路径和hostfile文件的路径。更多mpirun的选项设置可见OpenMPI的官网。

#!/bin/bash

DATA_PATH=$1
HOSTFILE=$2

rm -rf device
mkdir device
cp ./resnet50_distributed_training.py ./resnet.py ./device
cd ./device
echo "start training"
mpirun -n 16 --hostfile $HOSTFILE -x DATA_PATH=$DATA_PATH -x PATH -mca pml ob1 pytest -s -v ./resnet50_distributed_training.py > train.log 2>&1 &

在GPU上进行分布式训练时,模型参数的保存和加载可参考分布式训练模型参数保存和加载