# 动态组网启动方式
[](https://gitee.com/mindspore/docs/blob/r2.1/tutorials/experts/source_zh_cn/parallel/dynamic_cluster.md)
## 概述
出于训练时的可靠性要求,MindSpore提供了**动态组网**特性,用户能够不依赖任何第三方库(OpenMPI)来启动Ascend/GPU/CPU分布式训练任务,并且训练脚本无需做任何修改。我们建议用户优先使用此种启动方式。用户可以点击[多卡启动方式](https://www.mindspore.cn/tutorials/experts/zh-CN/r2.1/parallel/startup_method.html)查看多卡启动方式在不同平台的支持情况。
OpenMPI在分布式训练的场景中,起到在Host侧同步数据以及进程间组网的功能;而MindSpore**动态组网**特性通过**复用Parameter Server模式训练架构**,取代了OpenMPI能力,可参考[Parameter Server模式](https://mindspore.cn/tutorials/experts/zh-CN/r2.1/parallel/parameter_server_training.html)训练教程。
**动态组网**特性将多个MindSpore训练进程作为`Worker`启动,并且额外启动一个`Scheduler`负责组网和容灾恢复。用户只需对启动脚本做少量修改,即可执行分布式训练。
> 动态组网启动脚本能在多种硬件平台间快速迁移,无需对其进行额外修改。
## 注意事项
- 动态组网当前不支持`PyNative`模式。
## 环境变量
动态组网启动训练脚本前需要导出若干环境变量,如下表格所示:
| 环境变量 |
功能 |
类型 |
取值 |
说明 |
| MS_ROLE |
指定本进程角色。 |
String |
- MS_SCHED: 代表Scheduler进程,一个训练任务只启动一个Scheduler,负责组网,容灾恢复等,不会执行训练代码。
- MS_WORKER: 代表Worker进程,一般设置分布式训练进程为此角色。
- MS_PSERVER: 代表Parameter Server进程,只有在Parameter Server模式下此角色生效,具体请参考Parameter Server模式。
|
Worker和Parameter Server进程会向Scheduler进程注册从而完成组网。 |
| MS_SCHED_HOST |
指定Scheduler的IP地址。 |
String |
合法的IP地址。 |
当前版本暂不支持IPv6地址。 |
| MS_SCHED_PORT |
指定Scheduler绑定端口号。 |
Integer |
1024~65535范围内的端口号。 |
|
| MS_NODE_ID |
指定本进程的ID,集群内唯一。 |
String |
代表本进程的唯一ID,默认由MindSpore自动生成。 |
MS_NODE_ID在在以下情况需要设置,一般情况下无需设置,由MindSpore自动生成:
- 开启容灾场景:容灾恢复时需要获取当前进程ID,从而向Scheduler重新注册。
- 开启GLOG日志重定向场景:为了保证各训练进程日志独立保存,需设置进程ID,作为日志保存路径后缀。
- 指定进程rank id场景:用户可通过设置MS_NODE_ID为某个整数,来指定本进程的rank id。
|
| MS_WORKER_NUM |
指定角色为MS_WORKER的进程数量。 |
Integer |
大于0的整数。 |
用户启动的Worker进程数量应当与此环境变量值相等。若小于此数值,组网失败;若大于此数值,Scheduler进程会根据Worker注册先后顺序完成组网,多余的Worker进程会启动失败。
|
| MS_SERVER_NUM |
指定角色为MS_PSERVER的进程数量。 |
Integer |
大于0的整数。 |
只在Parameter Server训练模式下需要设置。 |
| MS_ENABLE_RECOVERY |
开启容灾。 |
Integer |
1代表开启,0代表关闭。默认为0。 |
|
| MS_RECOVERY_PATH |
持久化路径文件夹。 |
String |
合法的用户目录。 |
Worker和Scheduler进程在执行过程中会进行必要的持久化,如用于恢复组网的节点信息以及训练业务中间状态等,并通过文件保存。 |
| MS_HCCL_CM_INIT |
是否使用CM方式初始化HCCL。 |
Integer |
1代表是,0代表否。默认为0。 |
此环境变量只在Ascend硬件平台并且通信域数量较多的情况下建议开启。开启此环境变量后,能够降低HCCL集合通信库的内存占用,并且训练任务执行方式与`rank table`启动方式相同。 |
> 以上环境变量在各进程启动前都需设置且`MS_SCHED_HOST`,`MS_SCHED_PORT`,`MS_WORKER_NUM`内容保持一致,否则会由于各进程配置不一致导致组网失败。
## 执行训练任务
由于**动态组网**启动脚本在各硬件平台下能够保持一致,下面仅以GPU硬件平台下使用8卡分布式训练为例,演示如何编写启动脚本:
> 样例的运行目录:[distributed_training](https://gitee.com/mindspore/docs/tree/r2.1/docs/sample_code/distributed_training)。
### 1. 准备Python训练脚本
```python
import mindspore as ms
from mindspore.train import CheckpointConfig, ModelCheckpoint
from mindspore.communication import init
if __name__ == "__main__":
ms.set_context(mode=ms.GRAPH_MODE, device_target="GPU")
init()
ms.set_auto_parallel_context(parallel_mode=ms.ParallelMode.DATA_PARALLEL, gradients_mean=True)
...
```
其中,
- `mode=GRAPH_MODE`:使用分布式训练需要指定运行模式为图模式(当前版本**动态组网**特性暂不支持PyNative模式)。
- `init()`:初始化组网,根据`set_context`接口中指定后端,初始化集合通信库(此案例下为NCCL),完成分布式训练初始化操作。
- `ms.ParallelMode.DATA_PARALLEL`:设置训练模式为数据并行模式。
动态组网还支持**安全加密通道**特性,支持`TLS/SSL`协议,满足用户的安全性需求。默认情况下,安全加密通道是关闭的,若需要开启,则通过`set_ps_context`正确配置安全加密通道后,才能调用init(),否则初始化组网会失败。若想使用安全加密通道,请配置:
`set_ps_context(config_file_path="/path/to/config_file.json", enable_ssl=True, client_password="123456", server_password="123456")`
> 详细参数配置说明请参考Python API [mindspore.set_ps_context](https://www.mindspore.cn/docs/zh-CN/r2.1/api_python/mindspore/mindspore.set_ps_context.html#mindspore.set_ps_context),以及本文档[安全认证](#安全认证)章节。
### 2. 准备启动脚本
#### 单机多卡
单机多卡启动脚本内容`run_gpu_cluster.sh`如下,在启动Worker和Scheduler之前,需要添加相关环境变量设置:
```bash
#!/bin/bash
echo "=========================================="
echo "Please run the script as: "
echo "bash run_gpu_cluster.sh DATA_PATH"
echo "For example: bash run_gpu_cluster.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_gpu.py ./resnet.py ./device
cd ./device
echo "start training"
# 循环启动8个Worker训练进程
for((i=0;i<8;i++));
do
export MS_WORKER_NUM=8 # 设置集群中Worker进程数量为8
export MS_SCHED_HOST=127.0.0.1 # 设置Scheduler IP地址为本地环路地址
export MS_SCHED_PORT=8118 # 设置Scheduler端口
export MS_ROLE=MS_WORKER # 设置启动的进程为MS_WORKER角色
export MS_NODE_ID=$i # 设置进程id,可选
pytest -s -v ./resnet50_distributed_training_gpu.py > worker_$i.log 2>&1 & # 启动训练脚本
done
# 启动1个Scheduler进程
export MS_WORKER_NUM=8 # 设置集群中Worker进程数量为8
export MS_SCHED_HOST=127.0.0.1 # 设置Scheduler IP地址为本地环路地址
export MS_SCHED_PORT=8118 # 设置Scheduler端口
export MS_ROLE=MS_SCHED # 设置启动的进程为MS_SCHED角色
pytest -s -v ./resnet50_distributed_training_gpu.py > scheduler.log 2>&1 & # 启动训练脚本
```
> Scheduler和Worker进程的训练脚本内容和启动方式完全一致,这是因为在MindSpore已经差异化处理了两种角色内部流程。用户只需按照普通的训练方式拉起进程即可,无需按照角色修改Python代码。这是动态组网启动脚本在多硬件平台能够保持一致的原因之一。
执行如下指令,即可执行单机8卡分布式训练:
```bash
./run_gpu_cluster.sh /path/to/dataset/
```
#### 多机多卡
多机训练场景下,需拆分启动脚本。下面以执行2机8卡训练,每台机器执行启动4 Worker为例:
脚本`run_gpu_cluster_1.sh`在节点1上启动1`Scheduler`和`Worker1`到`Worker4`:
```bash
#!/bin/bash
echo "=========================================="
echo "Please run the script as: "
echo "bash run_gpu_cluster.sh DATA_PATH"
echo "For example: bash run_gpu_cluster.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_gpu.py ./resnet.py ./device
cd ./device
echo "start training"
# 循环启动Worker1到Worker4,4个Worker训练进程
for((i=0;i<4;i++));
do
export MS_WORKER_NUM=8 # 设置集群中Worker进程总数为8(包括其他节点进程)
export MS_SCHED_HOST=