Source: iSlide

機器學習分享GPU的好處

Patrick Fu
Gemini Open Cloud 雙子星雲端
8 min readJun 18, 2021

--

上一篇跟大家介紹,如果K8S scheduler在派送機器學習工作時能考量到需要附載GPU的容器,就可能提升機器學習的效能。今天我們來看一下GPU的特性 — GPU Kernel Non-Preemptive,以及為何我們想要讓一個GPU給多個機器學習容器共同使用。

GPU 在機器學習中扮演的角色

GPU 特別的地方,是它有很多中央處理器 (GPU cores),所以它可以同時進行很多的平行運算。當然,前題是這些平行運算是沒有互相依賴性的。舉例來說,一顆V100 Nvidia GPU,就有5,120 cores,可同時做五千多個運算。

人工智慧機器學習的過程,往往需要做很多向量運算(vector computation),這類運算通常包含很多可以單獨平行運算的單元,所以在做向量運算時,GPU 的效率就會比CPU來得高許多。因此,GPU又稱為運算加速器(accelerator)。

要開發者在寫程式時,就得決定有沒有加速器,或者GPU的品牌型號,是件非常繁瑣的事情。為了開發者的方便,NVIDIA在2006年就開發了一套 CUDA 函式庫(library),讓開發人員能夠不管有沒有GPU,程式的寫法都一樣。開發人員不需要直接呼叫GPU的指令,但又可以在具有GPU的環境上,快速做大量平行運算。換句話說,對開發人員來說,使用GPU與否,最好對他們來說是無感的。

這裡無感的意思就是,開發人員只要呼叫CUDA library的API,CUDA就會自動判斷環境有沒有GPU;假若GPU存在,才把向量運算的單元交給GPU處理。

使用GPU加速還有另一個好處,就是在GPU進行運算的時候,CPU就可以切換到另一個Process去進行其他的工作。等GPU運算完畢後,才繼續往下。如下圖:

圖一:GPU 是加速器的概念

機器學習的運作架構在CUDA的模式下,一個程式可以區分為兩個部份,分別是在CPU上執行,以及在GPU上執行的部份。 CPU這一端被稱為「host」,而GPU這一端則是「device」。 在GPU上執行的程式,也被稱為是「kernel」。

GPU Kernel Non-Preemptive

GPU Kernel 有一個很特別的地方,跟CPU很不一樣,就是GPU Kernel 是不能被中斷的。在作業系統的領域裡,這個特徵叫 non-preemptive。也就是說,當一個kernel被指派到一個GPU上,它就不會與CPU同步,它一直執行向量運算直到結束。CPU無法預知GPU kernel 何時會結束,也無法在中途停止GPU kernel的運算。

相對來說,CPU的多流程/多線程功能(multi-process/multi-thread) ,其運算模式就大不相同。當一個任務被指派到一個CPU 上時,它經常會把指令分到其他的輔助處理器上,例如 disk I/O、network communications 等等,這時候任務就會被swap out,OS scheduler就會把另一個process指派到這個CPU上。原來的process會處於休眠狀態,直到I/O結束,產生interrupt,process才會往下跑下去。

GPU Kernel Non-Preemptive 這個特性,就會讓一個GPU很難被多個機器學習流程同時共用。

不能共用GPU的影響

目前大部份的機器學習(ML),都在容器上執行。當有多個 ML Project 在同一個伺服器上進行,我們就會用到K8S的叢集管理這些容器。K8S scheduler 會根據ML容器的需求,與叢集裡K8S worker上GPU 的數量,把容器派送到到最理想的worker node上。如下圖:

圖二:K8S Manager 指派需要GPU的機器學習容器

因為上述 GPU kernel non-preemptive 的特性,不能中斷GPU kernel的運算,因此目前K8S default scheduler 都只能把整個GPU 指派給一個容器。兩個容器是無法共用一個 GPU 的

這幾年來,GPU的性能突飛猛進,然而無法共用GPU,造成了一個十分困擾的問題:一個容器的CPU不能充分利用它被指派的GPU,變成GPU在空轉,只能等待CPU送來下一個 GPU kernel

這會有什麼影響呢?

一方面是昂貴的GPU資源被浪費,未能有效運用;另一方面則是,GPU不能被共用,代表更多的ML容器必須等待GPU資源,造成ML專案的進展不彰,生產力不能提升。因此,有愈來愈多機器學習的專家,希望能夠讓多個 ML 容器,共同使用一個GPU。

我們的解決方案

雙子星雲端為各大公有雲、企業、科研機構服務多年,我們看到了上述的需求痛點,也尋思解決方案。因此我們與清大LSA Lab合作,將雙子星雲端的機器學習容器管理平台 Gemini AI Console,能夠讓多個機器學習容器,共用一個GPU。

這個產學合作的專案名稱就叫 Gemini,專案主要目的是要克服目前GPU在容器使用情境上的兩大挑戰:

  1. 相容於 CUDA library。目前機器學習容器使用GPU,絕大多數都是經過 CUDA library 的API,並不需要指明使用在哪個伺服器上的GPU、不需指定GPU Core 的數量 、也不需要在 K8S 叢集下Kubectl 的指令來指派 GPU 容器。為了持續相容這個使用方式,我們需要設計一個在不改變目前界面的前題下,而能使用一部份的、非整數的 GPU。因此我們發明了一個虛擬GPU(Virtual GPU)的概念,每個虛擬GPU映射到一個實體GPU上,而每個虛擬GPU可以切分成更小的單位,分配給不同的容器做使用
  2. 克服 GPU kernel non-preemptive。從前在GPU比較慢的時代,是CPU在等待GPU kernel結束,所以問題不大。但現在的問題是倒過來,GPU在等待容器的CPU派送下一個kernel。所以,我們希望能夠把多個GPU Kernel 塞進同一個GPU 上。這個概念叫 GPU kernel burst。再配合上面說的 Virtual GPU 概念,就可以增加GPU的使用率。

對照其他方案

這裡要特別說明的是,市面上也有其他共享GPU的解決方案,但大部分都是 GPU廠商用硬體配合軟體構成。例如NVIDIA的MPS、A100的MIG功能,都是要在特別的GPU型號上才能使用。而 Gemini AI Console 是一個純軟體的解決方案,只要是CUDA支援的GPU,就可以配置這個解決方案;也不需要更改GPU伺服器上的設定,只要在 Gemini AI Console 上註明,哪一個機器學習服務容器需要使用多少比率的GPU,就可以讓多個機器學習容器共用GPU了。

我們會再詳細介紹 Virtual GPU 與 kernel burst 的概念,如何配合 Kubernetes scheduler 和 CUDA 的優化,以達成使用者分享GPU的需求。

雙子星雲端的最新產品 AI Console 已提供 GPU Partitioning 分割共享功能,立刻預約 DEMO!我們的產品顧問將向您示範,並提供試用!

References:

  1. https://github.com/kubernetes/kubernetes/blob/release-1.3/plugin/pkg/scheduler/algorithm/predicates/predicates.go
  2. https://github.com/kubernetes/kubernetes/tree/release-1.3/plugin/pkg/scheduler/algorithm/priorities/
  3. https://github.com/fabric8io/jenkinshift/blob/master/vendor/k8s.io/kubernetes/docs/devel/scheduler_algorithm.md
  4. https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
  5. https://alibaba-cloud.medium.com/getting-started-with-kubernetes-scheduling-process-and-scheduler-algorithms-847e660533f1
  6. https://www.alibabacloud.com/blog/gpu-sharing-scheduler-extender-now-supports-fine-grained-kubernetes-clusters_594926

--

--

Patrick Fu
Gemini Open Cloud 雙子星雲端

符儒嘉於美國矽谷資訊軟體業工作約30 年,曾在IBM、Amdahl、Sun、Interwoven任職,2009回國加入雲端中心之研發團隊,擔任雲端中心關鍵計畫Cloud OS 系統軟體開發之計畫主持人,將其在美國所累積的系統軟體開發知識與經驗,運用於雲端中心之計畫執行中。