在使用GPU进行深度学习时,务必使用集群管理器

本文最初发布于Logical Clocks AB的官方博客,经原作者授权由InfoQ中文站翻译并分享。

如果你正在雇用一个数据科学家团队或使用深度学习,那么可以在团队之间共享GPU的集群管理器将可以最大化GPU的利用率,并使数据科学家保持愉快的心情。

共享GPU的反模式

在Logical Clocks,我们与许多客户讨论过他们如何在团队之间共享GPU,令人惊讶的是,许多公司仍然使用谷歌日历或固定的时间表来共享GPU。许多公司甚至不跨业务部门共享GPU,这更糟糕。不用说,这些方法不利于充分利用你的GPU投资,也不利于开发人员——因为他们可能无法在需要时使用所有可用的GPU。

GPU即资源(GPUs-as-a-Resource)

资源管理器用于管理数据中心或组织中可用的计算和GPU资源。开发人员可以通过向集群提交应用程序请求来使用资源管理器运行应用程序:请使用X容器启动我的应用程序,其中每个容器都有Y个CPU和X GB内存。然后,当资源管理器可以将这些资源分配给应用程序时,它就会调度应用程序执行。对于深度学习,我们需要GPU,有一些现代化的资源管理器支持“GPU即资源”,你可以请求在容器中加入N个GPU。深度学习应用程序可以对资源管理器提出具体的要求。对于分布式训练(使用1个以上的GPU),应用程序会同时请求所有的GPU——即所谓的分组调度(Gang Scheduling)。但是,对于超参数优化,应用程序开始时可以只使用1个GPU,并在资源管理器增量分配GPU时使用更多的GPU。为了让分组调度和增量分配正常工作,需要应用程序软件和资源管理器都支持。

image

分布式训练需要资源管理器提供分组调度支持,以便可以同时提供GPU。如果不支持或不完全支持分组调度,则分布式训练可能会无限期地中断,或者导致资源管理器死锁。

image

超参数优化可以使用资源管理器增量分配的GPU。它可以仅使用1个GPU,也可以使用更多的GPU获得更快的速度。

机器学习工作流

当机器学习从研发转移到生产时,模型训练通常会成为一个更长的机器学习工作流程中的一个阶段,其中包括(1)收集和准备训练数据,(2)训练/验证模型,以及(3)部署模型以提供服务。如果数据量很大,阶段(1)可能需要许多容器以及许多CPU,用于ETL和/或特征工程。Spark/PySpark是用于这个阶段的流行框架。对于阶段(2),可以使用PyTorch或Keras/TensorFlow等框架进行训练。分布式训练可以在HopsML等框架的帮助下完成。最后,阶段(3)涉及到将模型部署到生产环境中以提供服务。这可以在不同的集群或相同的集群上完成。Kubernetes是一个流行的模型服务框架,因为它支持负载平衡和伸缩性。

image

机器学习工作流包含DataPrep阶段、训练阶段和模型服务阶段,每个阶段需要集群提供不同的资源集。DataPrep通常需要CPU,训练需要GPU,服务需要CPU(低延迟模型服务可能也需要GPU)。

YARN、Mesos、Slurm、Kubernetes

有多种数据中心资源管理器支持GPU即资源:

  • YARN
  • Kubernetes
  • Mesos (DC/OS)
  • Slurm

YARN是本地数据湖的主要资源调度程序,自Hadoop 3.1版以来,它就对GPU即资源提供了全面支持。Hops的YARN是Hadoop的一个分支,自2017年10月以来一直支持GPU即资源。这两个版本都不支持分组调度,但是Hops在YARN上提供的层次分组调度语义使用了PySpark和HopsML API。实际上,训练应用程序是在单个map操作中运行的,而该操作由HopsML在PySpark执行器上进行分组调度。在Spark 2.4中,有一种新的障碍执行模式,也支持分布式训练的分组调度。

Mesos不支持分组调度,但是,与HopsML使用Spark向YARN添加分组调度支持类似,Uber在一个名为Peleton的平台上添加了对使用Spark进行分布式训练的分组调度支持。遗憾的是,Peleton目前不是开源的,Uber正在讨论将Peleton迁移到Kubernetes。Kubernetes目前正致力于支持分组调度(或者他们称之为协同调度),并且有望在2019年晚些时候将其包含在KubeFlow这样的框架中。传统上,Slurm用于HPC集群,在云或数据湖集群中没有得到广泛的应用,但提供了原生分组调度支持。

我们现在讨论使用以下两个开源框架的数据科学家如何使用资源管理器:KubeFlow on Kubernetes和Hopsworks on Hops YARN。

使用KubeFlow的数据科学家的经验

Kubernetes支持使用YAML中的集群规范创建包含GPU的集群,例如:

apiVersion: v1
kind: Pod
metadata:
 name: cuda-vector-add
spec:
 restartPolicy: OnFailure
 containers:
   – name: cuda-vector-add
# https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
     image: "k8s.gcr.io/cuda-vector-add:v0.1"
     resources:
       limits:
         nvidia.com/gpu: 1 # requesting 1 GPU

数据科学家通常不直接使用Kubernetes,因为这涉及太多DevOps:YAML规范、安装Python库和其他包的Dockerfile。相反,Kubeflow通常用于配置集群,并在命令行中使用GPU训练深层神经网络。

首先,数据科学家可以使用命令行,通过以下命令检查集群中GPU的可用性:

$ kubectl describe nodes | grep -B 3 gpu
Capacity:
cpu:             8
memory:          32879772Ki
nvidia.com/gpu:  2
—
Allocatable:
cpu:             8
memory:          32777372Ki
nvidia.com/gpu:  2

然后,假设你已经安装了Kubeflow(比如使用本教程),那么你可以通过以下命令使用Kubeflow在GPU上训练深度神经网络:

ks generate tf-job mnist –name=mnist –namespace=mykubeflow
# examine, then set the cluster configuration parameters
ks param list
COMPONENT                  PARAM          VALUE
=========                  =====         =====
mnist             args          "null"
mnist             image         "null"
mnist             image_gpu.    "null"
mnist             name                 "mnist"
mnist             namespace     "mykubeflow"
mnist             num_gpus 0
mnist             num_masters 1
mnist             num_ps  0
mnist             num_workers 0

IMAGE=docker.io/raddaoui/tfjob_mnist_image:2.0
ks param set mnist image ${IMAGE}
ks param set mnist num_ps 2
ks param set mnist num_workers 3
ks param set mnist num_masters 0
ks param set  mnist args — python,/opt/mnist_replica.py

# start training
ks apply default -c

使用Hopsworks的数据科学家的经验

Hopsworks是我们面向机器学习和数据分析的扩展平台,它基于下一代Hadoop平台Hops。在Hopsworks UI中,数据科学家可以快速查看集群中可用GPU的数量:

image

启动一个有多个GPU的集群非常简单,只需确定要分配给应用程序主程序和执行程序的GPU数量和内存量即可:

image

最后,数据科学家可以使用pipconda安装Python库(不需要编写Dockerfile):

image

Hopsworks中的机器学习工作流

在Hopsworks,我们为(1)DataPrep和(2)训练阶段和(3)模型服务Kubernetes提供YARN支持,如下图所示。通常,DataPrep是在PySpark或Spark上完成的,该阶段的输出是将训练数据写入我们的分布式文件系统HopsFS。训练通常通过使用PySpark启动PyTorch或TensorFlow/Keras应用程序来完成,经过训练的模型存储在HopsFS上。最后,在Kubernetes中通过从HopsFS读取模型来提供服务。

image

HopsML中的机器学习工作流可以在PySpark上运行DataPrep阶段,在TensorFlow/PyTorch上进行(分布式)训练,在Kubernetes上提供模型服务。一个分布式文件系统HopsFS用于集成不同的阶段,YARN用于为PySpark阶段分配CPU以及为训练阶段分配GPU。

有集群管理器就够了吗?

2018年Spark欧洲峰会上的演讲中,我们指出,集群管理器本身不足以最有效地利用GPU。数据科学家可以在Jupyter笔记本上编写Python程序,在那里他们可以使用相同的资源进行训练和可视化。例如,开发人员可以在Jupyter中编写一个cell在一个或多个GPU上训练网络,然后编写后续cell来评估该模型的性能,然后会有一个或多个cell来可视化或验证经过训练的模型。当数据科学家可视化地分析训练好的模型时,她不必使用宝贵的GPU资源。

GPU应该在训练/评估完成后立即释放——与如何实现分组调度无关。你可以使用(1)规则和分布式文件系统或(2)HopsML确保GPU立即被释放。对于(1),开发人员可以将他们训练过的模型和评估数据集写入分布式文件系统,并在训练完成后关闭用于训练模型的容器。然后打开一个新的Python笔记本,访问相同的分布式文件系统,以直观地检查经过训练的模型。对于(2),在HopsML中,开发人员将他们的训练代码放在Python中的一个函数里,这个函数在GPU上运行,当函数返回时,与其关联的GPU会在几秒钟的不活动状态后释放。HopsML使用PySpark中的动态执行器实现了这种行为——要了解更多细节,请阅读这篇博文。下面的例子展示了如何在HopsML中构造代码:

   def train_fn():
    # training code goes here

   from hops import experiment
    experiment.launch(train_fn)

小结

集群管理器(例如YARN for Hopsworks)将帮助你最大化GPU的价值,并通过模型的分布式训练和超参数优化提高数据科学家的工作效率,从而使他们保持愉快的心情。

查看英文原文:When Deep Learning with GPUs, use a Cluster Manager

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章