环境部署¶
环境支持列表¶
PaddlePaddle 分布式对不同系统和硬件的支持情况如下表所示,
CPU |
GPU |
昆仑 XPU |
海光 DCU |
昇腾 NPU |
|
Linux |
PS/Collective |
PS/Collective |
PS/Collective |
Collective |
Collective |
目前 Windows 只支持单机的 CPU 和 GPU,暂不支持分布式训练。
常用环境介绍¶
下面针对使用多台裸机使用分布式的场景提供指导,总体而言,
强烈推荐使用 docker 环境部署使用分布式训练,不建议在机器上直接安装使用 PaddlePaddle
当机器数量多于 5 台且长期使用时,建议使用 Kubernetes 部署 或其他类似集群管理工具使用
裸机及 Docker 化部署¶
paddle 环境安装¶
根据 安装 部分选择合适的 paddle 版本, 直接使用 pip 可以在环境中安装 PaddlePaddle, 例如
$ python -m pip install paddlepaddle-gpu==2.2.2.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
或者在装有 docker 的环境中可以直接使用 PaddlePaddle 官方提供的镜像, 下载对应版本的镜像然后通过以下命令启动
$ docker run --name paddle -it --net=host -v $PWD:/paddle registry.baidubce.com/paddlepaddle/paddle:2.2.2-gpu-cuda11.2-cudnn8 /bin/bash
当使用 gpu 时请配置 nvidia docker runtime 或使用 nvidia-docker 启动容器,进入容器后使用 nvidia-smi 命令确认环境正确
使用分布式时需要添加 --net=host 参数让容器使用主机网络以实现跨机建立连接
安装后,运行以下命令
$ python -c "import paddle; paddle.utils.run_check()"
确保输出结果符合预期以保证 paddle 环境安装正确。 至此,可以进行单机的代码开发和调试工作。
分布式启动¶
在多机中安装好环境,同步数据和代码,在任意节点上运行以下命令
$ python -m paddle.distributed.launch --nnodes=2 demo.py
nnodes 为本次分布式任务的节点个数,这时会在看到如下输出
$ Copy the following command to other nodes to run.
$ --------------------------------------------------------------------------------
$ python -m paddle.distributed.launch --master 123.45.67.89:25880 --nnodes=2 demo.py
$ --------------------------------------------------------------------------------
按照提示复制命令到其他所有节点即可启动分布式训练任务。
--nnodes 为分布式任务的节点个数,默认为 1 即启动单机任务
--master 为分布式同步主节点,可以直接由用户设置,这是用户需要配置主节点的 ip 和任意可用端口
更多 launch 启动参数和用法请参考 文档 或通过以下命令获得
$ python -m paddle.distributed.launch --help
Kubernetes 部署¶
在 kubernetes 上部署分布式任务需要安装 paddle-operator 。 paddle-operator 通过添加自定义资源类型 (paddlejob) 以及部署 controller 和一系列 kubernetes 原生组件的方式实现简单定义即可运行 paddle 任务的需求。
目前支持运行 ParameterServer (PS) 和 Collective 两种分布式任务,当然也支持运行单节点任务。
paddle-operator 安装¶
安装 paddle-operator 需要有已经安装的 kubernetes (v1.8+) 集群和 kubectl (v1.8+) 工具。
本节所需配置文件和示例可以在 这里 找到, 可以通过 git clone 或者复制文件内容保存。
deploy
|-- examples
| |-- resnet.yaml
| |-- wide_and_deep.yaml
| |-- wide_and_deep_podip.yaml
| |-- wide_and_deep_service.yaml
| `-- wide_and_deep_volcano.yaml
|-- v1
| |-- crd.yaml
| `-- operator.yaml
`-- v1beta1
|-- crd.yaml
`-- operator.yaml
注意:kubernetes 1.15 及以下使用 v1beta1 目录,1.16 及以上使用目录 v1.
执行以下命令,
$ kubectl create -f https://raw.githubusercontent.com/PaddleFlow/paddle-operator/dev/deploy/v1/crd.yaml
或者
$ kubectl create -f deploy/v1/crd.yaml
注意:v1beta1 请根据报错信息添加 --validate=false 选项
通过以下命令查看是否成功,
$ kubectl get crd
NAME CREATED AT
paddlejobs.batch.paddlepaddle.org 2021-02-08T07:43:24Z
执行以下部署命令,
$ kubectl create -f https://raw.githubusercontent.com/PaddleFlow/paddle-operator/dev/deploy/v1/operator.yaml
或者
$ kubectl create -f deploy/v1/operator.yaml
通过以下命令查看部署结果和运行状态,
$ kubectl -n paddle-system get pods
NAME READY STATUS RESTARTS AGE
paddle-controller-manager-698dd7b855-n65jr 1/1 Running 0 1m
通过查看 controller 日志以确保运行正常,
$ kubectl -n paddle-system logs paddle-controller-manager-698dd7b855-n65jr
提交 demo 任务查看效果,
$ kubectl -n paddle-system create -f deploy/examples/wide_and_deep.yaml
查看 paddlejob 任务状态, pdj 为 paddlejob 的缩写,
$ kubectl -n paddle-system get pdj
NAME STATUS MODE AGE
wide-ande-deep-service Completed PS 4m4s
以上信息可以看出:训练任务已经正确完成,该任务为 ps 模式。 可通过 cleanPodPolicy 配置任务完成/失败后的 pod 删除策略,详见任务配置。
训练期间可以通过如下命令查看 pod 状态,
$ kubectl -n paddle-system get pods
paddlejob 任务提交¶
在上述安装过程中,我们使用了 wide-and-deep 的例子作为提交任务演示,本节详细描述任务配置和提交流程供用户参考提交自己的任务。
示例 wide and deep
本示例为 PS 模式,使用 cpu 进行训练,需要配置 ps 和 worker。
准备配置文件,
$ cat demo-wide-and-deep.yaml
apiVersion: batch.paddlepaddle.org/v1
kind: PaddleJob
metadata:
name: wide-ande-deep
spec:
withGloo: 1
intranet: PodIP
cleanPodPolicy: OnCompletion
worker:
replicas: 2
template:
spec:
containers:
- name: paddle
image: registry.baidubce.com/paddle-operator/demo-wide-and-deep:v1
ps:
replicas: 2
template:
spec:
containers:
- name: paddle
image: registry.baidubce.com/paddle-operator/demo-wide-and-deep:v1
说明:
提交命名需要唯一,如果存在冲突请先删除原 paddlejob 确保已经删除再提交;
ps 模式时需要同时配置 ps 和 worker,collective 模式时只需要配置 worker 即可;
withGloo 可选配置为 0 不启用, 1 只启动 worker 端, 2 启动全部(worker 端和 Server 端), 建议设置 1;
cleanPodPolicy 可选配置为 Always/Never/OnFailure/OnCompletion,表示任务终止(失败或成功)时,是否删除 pod,调试时建议 Never,生产时建议 OnCompletion;
intranet 可选配置为 Service/PodIP,表示 pod 间的通信方式,用户可以不配置, 默认使用 PodIP;
ps 和 worker 的内容为 podTemplateSpec,用户可根据需要遵从 kubernetes 规范添加更多内容, 如 GPU 的配置.
提交任务: 使用 kubectl 提交 yaml 配置文件以创建任务,
$ kubectl -n paddle-system create -f demo-wide-and-deep.yaml
示例 resnet¶
本示例为 Collective 模式,使用 gpu 进行训练,只需要配置 worker,worker 配置中需要声明使用的 gpu 信息。
准备配置文件,
$ cat resnet.yaml
apiVersion: batch.paddlepaddle.org/v1
kind: PaddleJob
metadata:
name: resnet
spec:
cleanPodPolicy: Never
worker:
replicas: 2
template:
spec:
containers:
- name: paddle
image: registry.baidubce.com/paddle-operator/demo-resnet:v1
command:
- python
args:
- "-m"
- "paddle.distributed.launch"
- "train_fleet.py"
volumeMounts:
- mountPath: /dev/shm
name: dshm
resources:
limits:
nvidia.com/gpu: 1
volumes:
- name: dshm
emptyDir:
medium: Memory
注意:
这里需要添加 shared memory 挂载以防止缓存出错;
本示例采用内置 flower 数据集,程序启动后会进行下载,根据网络环境可能等待较长时间。
提交任务: 使用 kubectl 提交 yaml 配置文件以创建任务,
$ kubectl -n paddle-system create -f resnet.yaml
卸载¶
通过以下命令卸载部署的组件,
$ kubectl delete -f deploy/v1/crd.yaml -f deploy/v1/operator.yaml
注意:重新安装时,建议先卸载再安装
公有云和私有云部署¶
在公有云上运行 PaddlePaddle 分布式建议通过选购容器引擎服务的方式,各大云厂商都推出了基于标准 kubernetes 的云产品,然后根据上节中的教程安装使用即可。
云厂商 |
容器引擎 |
链接 |
百度云 |
CCE |
|
阿里云 |
ACK |
|
华为云 |
CCE |
FAQ¶
怎么知道分布式启动正确?¶
典型的启动日志如下所示
LAUNCH INFO 2022-05-18 11:53:09,773 ----------- Configuration ----------------------
LAUNCH INFO 2022-05-18 11:53:09,773 devices: 6,7
LAUNCH INFO 2022-05-18 11:53:09,773 elastic_level: -1
LAUNCH INFO 2022-05-18 11:53:09,773 elastic_timeout: 30
LAUNCH INFO 2022-05-18 11:53:09,773 gloo_port: 6767
LAUNCH INFO 2022-05-18 11:53:09,773 host: None
LAUNCH INFO 2022-05-18 11:53:09,773 job_id: default
LAUNCH INFO 2022-05-18 11:53:09,773 legacy: False
LAUNCH INFO 2022-05-18 11:53:09,773 log_dir: log
LAUNCH INFO 2022-05-18 11:53:09,773 log_level: INFO
LAUNCH INFO 2022-05-18 11:53:09,774 master: None
LAUNCH INFO 2022-05-18 11:53:09,774 max_restart: 3
LAUNCH INFO 2022-05-18 11:53:09,774 nnodes: 1
LAUNCH INFO 2022-05-18 11:53:09,774 nproc_per_node: None
LAUNCH INFO 2022-05-18 11:53:09,774 rank: -1
LAUNCH INFO 2022-05-18 11:53:09,774 run_mode: collective
LAUNCH INFO 2022-05-18 11:53:09,774 server_num: None
LAUNCH INFO 2022-05-18 11:53:09,774 servers:
LAUNCH INFO 2022-05-18 11:53:09,774 trainer_num: None
LAUNCH INFO 2022-05-18 11:53:09,774 trainers:
LAUNCH INFO 2022-05-18 11:53:09,774 training_script: demo.py
LAUNCH INFO 2022-05-18 11:53:09,774 training_script_args: []
LAUNCH INFO 2022-05-18 11:53:09,774 with_gloo: 0
LAUNCH INFO 2022-05-18 11:53:09,774 --------------------------------------------------
LAUNCH INFO 2022-05-18 11:53:09,783 Job: default, mode collective, replicas 1[1:1], elastic False
LAUNCH INFO 2022-05-18 11:53:09,784 Run Pod: gistdo, replicas 2, status ready
LAUNCH INFO 2022-05-18 11:53:09,806 Watching Pod: gistdo, replicas 2, status running
可以通过如下信息确认符合预期:
检查 launch 参数是否生效, 参考 launch API 文档设置各个参数
Job 默认为 default,当环境共用时,为避免冲突,请设置单独的 job_id 参数以区别
Job replicas 对应节点数,3[2:4] 表示当前 3 节点,允许最少 2 节点,最多 4 节点,非弹性任务三者一致
Pod 为逻辑节点,可以在一个物理节点上部署多个逻辑节点模拟分布式,Pod name 为 hash,和日志对应
Pod replicas 即节点上的进程数,在 GPU 训练时,一张卡对应一个进程
当 launch 日志显示 status running 即表示分布式运行已正确启动,后续默认输出 0 号进程的日志
GPU 分布式不生效? 节点数不对?¶
在 GPU 训练时,一张卡对应一个进程, 每个节点(Pod)分配到的卡数即 Pod replicas,确认显示的数量是否符合预期,如果不符合预期请检查遗下设置:
首先使用环境中使用 nvidia-smi 命令查看环境中的卡是否正常
检查 CUDA_VISIBLE_DEVICES 设置,卡必须可见才可用
检查 --devices 设置,该设置为卡号的绝对 index
当检查设置无误后可通过设置 --log_level 打印更多日志以排查,当任务启动后,可以查看日志文件查看节点 ip 信息,然后检查机器连通性。
为什么弹性不生效?¶
弹性使用需要满足以下条件:
使用 etcd 作为 master
任务需要使用唯一 id,即设置 job_id
设置 nnodes 需要设置范围,例如 2:4
检查超时设置是否过长