根據 Gartner 對全球 CIO 的調查結果顯示,人工智能將成爲 2019 年組織革命的顛覆性力量。對於人工智能來講,算力即正義,成本即能力,利用 Docker 和 Kubernetes 表明雲原生技術爲 AI 提供了一種新的工做模式,將 GPU 機器放到統一的資源池進行調度和管理,這避免了GPU 資源利用率低下和人工管理的成本。所以,全球主要的容器集羣服務廠商 Kubernetes 都提供了 Nvidia GPU 容器集羣調度能力,可是一般都是將一個 GPU 卡分配給一個容器。這雖然能夠實現比較好的隔離性,確保使用 GPU 的應用不會被其餘應用影響;對於深度學習模型訓練的場景也很是適合,可是,針對模型開發和模型預測的場景仍是會顯得比較浪費。基於此,你們有了共享 GPU 的集羣調度需求。git
共享 GPU 的集羣調度就是可以讓更多的模型開發和預測服務共享同一個 GPU 卡,進而提升集羣中 Nvidia GPU 的利用率。而這就須要提供 GPU 資源的劃分,而這裏 GPU 資源劃分的維度指的就是 GPU 顯存和 Cuda Kernel 線程的劃分。一般在集羣級別談支持共享 GPU 是如下兩件事情:
1.調度
2.隔離,咱們這裏主要討論的是調度,隔離的方案目前須要用戶經過應用限制(好比使用 Tensorflow 的per_process_gpu_memory_fraction 來控制),將來會提供基於 Nvidia 的 MPS 的可選項, 也會考慮 GPU 的方案。
而對於細粒度的 GPU 卡調度,目前 Kubernetes 社區並無很好的方案,這是因爲 Kubernetes 對於 GPU 這類擴展資源的定義僅僅支持整數粒度的加加減減,沒法支持複雜資源的分配。好比用戶但願使用 Pod A 佔用半張 GPU卡,這在目前 Kubernetes 的架構設計中沒法實現資源分配的記錄和調用。這裏挑戰是多卡 GPU 共享是實際矢量資源問題,而 Extened Resource 是標量資源的描述。
針對此問題,咱們設計了一個 Out Of Tree 的共享 GPU 調度方案,該方案依賴於 Kubernetes 的現有的工做機制:github
這個 GPU 共享調度擴展的好處是:利用 Kubernetes 的擴展和插件機制實現,對於 API Server,Scheduler,Controller Manager 以及 Kubelet 等核心組件沒有侵入性。這就方便了使用者能夠在不一樣 Kubernetes 版本上應用這個方案,無需 rebase 代碼和從新構建 Kubernetes 二進制包。api
用戶場景架構
[](https://www.aatech.org/articles/132268#2)目標app
gpu_options.per_process_gpu_memory_fraction
控制應用的顯存使用量。那咱們要解決的問題就先簡化到以顯存爲調度標尺,而且把顯存使用的大小以參數的方式傳遞給容器內部。詳細設計ide
而咱們的工做首先是定義了兩個新的 Extended Resource: 第一個是 gpu-mem, 對應的是 GPU 顯存;第二個是 gpu-count,對應的是 GPU 卡數。 經過兩個標量資源描述矢量資源, 而且結合這一資源,提供支持共享 GPU 的工做機制。下面是基本的架構圖:學習
ListAndWatch()
將節點的 GPU 總顯存(數量 顯存)做爲另外 Extended Resource 彙報給 Kubelet; Kubelet 進一步彙報給 Kubernetes API Server。 舉例說明,若是節點含有兩塊 GPU 卡,而且每塊卡包含 16276MiB,從用戶的角度來看:該節點的 GPU 資源爲 16276 2 = 32552; 同時也會將節點上的 GPU 卡數量 2 做爲另一個 Extended Resource 上報。
2.1 Kubernetes 默認調度器在進行完全部過濾(filter)行爲後會經過 http 方式調用 GPU Share Scheduler Extender的filter 方法, 這是因爲默認調度器計算 Extended Resource 時,只能判斷資源總量是否有知足需求的空閒資源,沒法具體判斷單張卡上是否知足需求;因此就須要由 GPU Share Scheduler Extender 檢查單張卡上是否含有可用資源。
如下圖爲例, 在由 3 個包含兩塊 GPU 卡的節點組成的 Kubernetes 集羣中,當用戶申請gpu-mem=8138
時,默認調度器會掃描全部節點,發現 N1 所剩的資源爲 (16276 * 2 - 16276 -12207 = 4069 )不知足資源需求,N1 節點被過濾掉。
而 N2 和 N3 節點所剩資源都爲 8138MiB,從總體調度的角度看,都符合默認調度器的條件;此時默認調度器會委託 GPU Share Scheduler Extender 進行二次過濾,在二次過濾中,GPU Share Scheduler Extender 須要判斷單張卡是否知足調度需求,在查看 N2 節點時發現該節點雖然有 8138MiB 可用資源,可是落到每張卡上看,GPU0 和分別 GPU1 只有 4069MiB 的可用資源,沒法知足單卡 8138MiB 的訴求。而 N3 節點雖然也是總共有 8138MiB 可用資源,可是這些可用資源都屬於 GPU0,知足單卡可調度的需求。由此,經過 GPU Share Scheduler Extender 的篩選就能夠實現精準的條件篩選。測試
2.2 當調度器找到知足條件的節點,就會委託 GPU Share Scheduler Extender 的 bind 方法進行節點和 Pod 的綁定,這裏 Extender 須要作的是兩件事情ui
ALIYUN_COM_GPU_MEM_IDX
保存到 Pod 的 annotation 中;同時也保存該 Pod 申請的 GPU Memory 做爲ALIYUN_COM_GPU_MEM_POD
和ALIYUN_COM_GPU_MEM_ASSUME_TIME
保存至 Pod 的 annotation 中,而且在此時進行 Pod 和所選節點的綁定。注意:這時還會保存ALIYUN_COM_GPU_MEM_ASSIGNED
的 Pod annotation,它被初始化爲「false」。它表示該 Pod 在調度時刻被指定到了某塊 GPU 卡,可是並無真正在節點上建立該 Pod。ALIYUN_COM_GPU_MEM_ASSUME_TIME
表明了指定
時間。
若是此時發現分配節點上沒有 GPU 資源符合條件,此時不進行綁定,直接不報錯退出,默認調度器會在 assume 超時後從新調度。人工智能
如下圖爲例,當 GPU Share Scheduler Extender 要把 gpu-mem:8138 的 Pod 和通過篩選出來的節點 N1 綁定,首先會比較不一樣 GPU 的可用資源,分別爲 GPU0(12207),GPU1(8138),GPU2(4069),GPU3(16276),其中 GPU2 所剩資源不知足需求,被捨棄掉;而另外三個知足條件的 GPU 中, GPU1 偏偏是符合空閒資源知足條件但同時又是所剩資源最少的 GPU 卡,所以 GPU1 被選出。
3. 節點上運行
當 Pod 和節點綁定的事件被 Kubelet 接收到後,Kubelet 就會在節點上建立真正的 Pod 實體,在這個過程當中, Kubelet 會調用 GPU Share Device Plugin 的Allocate
方法, Allocate
方法的參數是 Pod 申請的 gpu-mem。而在Allocate
方法中,會根據 GPU Share Scheduler Extender 的調度決策運行對應的 Pod
ALIYUN_COM_GPU_MEM_ASSIGNED
爲false
的 GPU Share PodALIYUN_COM_GPU_MEM_POD
的數量與 Allocate 申請數量一致的 Pod。若是有多個符合這種條件的 Pod,就會選擇其中ALIYUN_COM_GPU_MEM_ASSUME_TIME
最先的 Pod。ALIYUN_COM_GPU_MEM_ASSIGNED
設置爲true
,而且將 Pod annotation 中的 GPU 信息轉化爲環境變量返回給 Kubelet 用以真正的建立 Pod。
目前項目已經開源到 http://github.com 上
gpushare-scheduler-extender
gpushare-device-plugin
請參照部署文檔
aliyun.com/gpu-mem
的應用apiVersion: apps/v1 kind: Deployment metadata: name: binpack-1 labels: app: binpack-1 spec: replicas: 1 selector: # define how the deployment finds the pods it manages matchLabels: app: binpack-1 template: # define the pods specifications metadata: labels: app: binpack-1 spec: containers: - name: binpack-1 image: cheyang/gpu-player:v2 resources: limits: # MiB aliyun.com/gpu-mem: 1024
請參照使用文檔
請參照如何構建
本文爲雲棲社區原創內容,未經容許不得轉載。