在使用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

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