基于Kubernetes使用Horovod进行弹性训练

弹性模型训练通过对接Horovod的Elastic模式,可以让Horovod运行的分布式训练任务具备动态调整训练Workers数量的能力。您可以通过实时的弹性模型训练,并结合抢占实例,充分利用空闲的算力资源,以降低单位时间的训练成本。本文介绍如何部署弹性模型训练任务,以及如何扩容和缩容训练任务。

前提条件

背景信息

传统分布式深度学习任务,一旦提交训练任务,无法在运行中动态调整Workers的数量。

模型训练是深度学习中重要的环节,模型复杂的训练任务有运行时间长、算力需求大的特征。通过弹性模型训练,可以为深度学习的模型训练任务提供动态修改Workers数量的能力。

部署弹性模型训练任务

提交训练任务

使用以下代码示例提交一个训练任务。

arena submit etjob \
    --name=elastic-training \
    --gpus=1 \
    --workers=3 \
    --max-workers=9 \
    --min-workers=1 \
    --image=registry.cn-hangzhou.aliyuncs.com/ai-samples/horovod:0.20.0-tf2.3.0-torch1.6.0-mxnet1.6.0.post0-py3.7-cuda10.1 \
    --working-dir=/examples \
    "horovodrun \
    -np \$((\${workers}*\${gpus})) \
    --min-np \$((\${minWorkers}*\${gpus})) \
    --max-np \$((\${maxWorkers}*\${gpus})) \
    --host-discovery-script /etc/edl/discover_hosts.sh \
    python /examples/elastic/tensorflow2_mnist_elastic.py
    "

本文示例是一个Horovod任务,通过horovodrun指定运行弹性模型训练。在运行时需要指定npmax-npmin-np,Arena会将这些信息写入环境变量,所以在提交时指定环境变量即可。

参数解释如下表所示。

参数名

说明

--name

指定训练任务名称,全局唯一,不能重复。

--gpus

指定每个worker的GPU数。

--max-workers

指定训练任务最大Workers节点数。

--min-workers

指定训练任务最小Workers节点数。

--image

指定训练任务运行的容器镜像。

--working-dir

指定当前执行命令所在的目录。

--np

运行时的Workers数。

--max-np

运行时的最大Workers数。

--min-np

运行时的最小Workers数。

--host-discovery-script

et-operator/etc/edl/discover_hosts.sh位置将创建一个服务发现脚本, 该文件路径通过host-discovery-script指定。

系统输出类似以下结果:

configmap/elastic-training-etjob created
configmap/elastic-training-etjob labeled
trainingjob.kai.alibabacloud.com/elastic-training created
INFO[0000] The Job elastic-training has been submitted successfully
INFO[0000] You can run `arena get elastic-training --type etjob` to check the job status

查看训练任务

执行以下命令查看训练任务:

arena get elastic-training

系统输出类似以下结果:

Name:        elastic-training
Status:      RUNNING
Namespace:   default
Priority:    N/A
Trainer:     ETJOB
Duration:    13s

Instances:
  NAME                       STATUS   AGE  IS_CHIEF  GPU(Requested)  NODE
  ----                       ------   ---  --------  --------------  ----
  elastic-training-launcher  Running  13s  true      0               cn-huhehaote.192.168.0.173
  elastic-training-worker-0  Running  13s  false     1               cn-huhehaote.192.168.0.174
  elastic-training-worker-1  Running  13s  false     1               cn-huhehaote.192.168.0.174

查看训练日志

执行以下命令查看训练日志:

arena logs elastic-training --tail 10

系统输出类似以下结果:

[0]<stdout>:Step #340    Loss: 0.047924
[1]<stdout>:Step #340    Loss: 0.116303
[0]<stdout>:Step #350    Loss: 0.068762
[1]<stdout>:Step #350    Loss: 0.040847
[0]<stdout>:Step #360    Loss: 0.057501
[1]<stdout>:Step #360    Loss: 0.111952
[0]<stdout>:Step #370    Loss: 0.085895
[1]<stdout>:Step #370    Loss: 0.075529
[0]<stdout>:Step #380    Loss: 0.063450
[1]<stdout>:Step #380    Loss: 0.054253

扩容弹性模型训练任务

提交扩容任务

执行以下命令提交一个扩容任务:

arena scaleout etjob --name="elastic-training" --count=1 --timeout=10m
  • --name:指定操作的训练任务。

  • --count:指定扩容的Workers数量。

  • --timeout:指定扩容的超时时间。

如果在指定时间内未成功创建Workers,部署弹性任务的调度器会回滚扩容操作。

系统输出类似以下结果:

configmap/elastic-training-1609914643-scaleout created
configmap/elastic-training-1609914643-scaleout labeled
scaleout.kai.alibabacloud.com/elastic-training-1609914643 created
INFO[0003] The scaleout job elastic-training-1609914643 has been submitted successfully

查看训练任务

执行以下命令查看训练任务:

arena get elastic-training

系统输出类似以下结果:

Name:        elastic-training
Status:      RUNNING
Namespace:   default
Priority:    N/A
Trainer:     ETJOB
Duration:    3m 

Instances:
  NAME                       STATUS   AGE  IS_CHIEF  GPU(Requested)  NODE
  ----                       ------   ---  --------  --------------  ----
  elastic-training-launcher  Running  3m   true      0               cn-huhehaote.192.168.0.173
  elastic-training-worker-0  Running  3m   false     1               cn-huhehaote.192.168.0.174
  elastic-training-worker-1  Running  3m   false     1               cn-huhehaote.192.168.0.174
  elastic-training-worker-2  Running  1m   false     1               cn-huhehaote.192.168.0.173

从以上输出的信息,可以看到新部署的Workerelastic-training-worker-2

查看训练日志

执行以下命令查看训练日志:

arena logs elastic-training --tail 10

系统输出类似以下结果:

[1]<stdout>:Step #1670    Loss: 0.131210
[2]<stdout>:Step #1680    Loss: 0.020876
[0]<stdout>:Step #1680    Loss: 0.030605
[1]<stdout>:Step #1680    Loss: 0.074515
[2]<stdout>:Step #1690    Loss: 0.029105
[0]<stdout>:Step #1690    Loss: 0.015216
[1]<stdout>:Step #1690    Loss: 0.022670
[0]<stdout>:Step #1700    Loss: 0.105407
[1]<stdout>:Step #1700    Loss: 0.037623
[2]<stdout>:Step #1700    Loss: 0.032874

从以上输出的日志信息,可以看到当前共有3个Workers参与训练。

缩容弹性模型训练任务

提交缩容任务

执行以下命令提交一个缩容任务:

arena scalein etjob --name="elastic-training" --count=1 --timeout=10m
  • --name:指定操作的训练任务。

  • --count:指定缩容的Workers数量。

  • --timeout:指定缩容时间,即等待进程结束的时间。

系统输出类似以下结果:

configmap/elastic-training-1609914720-scalein created
configmap/elastic-training-1609914720-scalein labeled
scalein.kai.alibabacloud.com/elastic-training-1609914720 created
INFO[0002] The scalein job elastic-training-1609914720 has been submitted successfully

查看训练任务

执行以下命令查看训练任务:

arena get elastic-training

系统输出类似以下结果:

Name:        elastic-training
Status:      RUNNING
Namespace:   default
Priority:    N/A
Trainer:     ETJOB
Duration:    3m

Instances:
  NAME                       STATUS   AGE  IS_CHIEF  GPU(Requested)  NODE
  ----                       ------   ---  --------  --------------  ----
  elastic-training-launcher  Running  3m   true      0               cn-huhehaote.192.168.0.173
  elastic-training-worker-0  Running  3m   false     1               cn-huhehaote.192.168.0.174
  elastic-training-worker-1  Running  3m   false     1               cn-huhehaote.192.168.0.174

从以上输出的信息,可以看到Workerelastic-training-worker-2已被回收。

查看训练日志

执行以下命令查看训练日志:

arena logs elastic-training --tail 10

系统输出类似以下结果:

[1]<stdout>:Step #2180    Loss: 0.001739
[0]<stdout>:Step #2180    Loss: 0.004853
[0]<stdout>:Step #2190    Loss: 0.000846
[1]<stdout>:Step #2190    Loss: 0.007900
[0]<stdout>:Step #2200    Loss: 0.039376
[1]<stdout>:Step #2200    Loss: 0.024672
[0]<stdout>:Step #2210    Loss: 0.012985
[1]<stdout>:Step #2210    Loss: 0.010956
[0]<stdout>:Step #2220    Loss: 0.009604
[1]<stdout>:Step #2220    Loss: 0.002531

从以上输出的日志信息,可以看到当前仅有2个Workers参与训练。