杭州2016年12月30日電 /美通社/ -- Kubernetes上游計劃在其1.6 發行版本中加入GPU功能,提升應用程序運行效率。因為很多應用使用GPU可以提升效率,比如大(da)數據(ju)平臺應用TensorFlow通(tong)過使(shi)用GPU效率可以提升幾十甚(shen)至幾百倍。
那么,GPU是如何應用在Docker/K8S/TensorFlow這些平臺上起到提升效率的作用的呢?近(jin)日,才云新晉大神趙慧智用(yong)本篇(pian)文章(zhang)給出了答(da)案。在(zai)文中,趙慧智主要描寫了GPU在Docker、Kubernetes、TensorFlow以及Kubernetes+TensorFlow領域中的應用,并介紹了在開發領域的(de)實(shi)踐經驗,希望給大家帶來借鑒和指導意義,原文如下:
趙慧智
2016 年下旬加入才云,他是前HPE的(de)(de)Container team的(de)(de)Tech Lead,Kubernetes Member,在軟件研發領(ling)域有10多年的(de)(de)經驗。曾在HP和HPE工作(zuo)五年多,先前負(fu)責(ze)過Linux Kernel及(ji)driver開發,后(hou)負(fu)責(ze)Container在HPE Server上的(de)(de)性能(neng)及(ji)團隊管(guan)理工作(zuo),之后(hou)負(fu)責(ze)Kubernetes/Mesos在HPE服務器上的(de)(de)硬件enablement及(ji)開源工作(zuo)。
為什么離開惠普,加入才云?
2016年下旬,前惠普Kubernetes技術領域的GPU專家趙慧智加盟才云。趙慧智(zhi)從國內(nei)Kubernetes現(xian)狀、未來(lai)發(fa)展(zhan)趨勢幾個方面(mian)(mian)大致說(shuo)了一(yi)下(xia)加入(ru)才云的(de)(de)原因:“當時(shi)自(zi)己對Kubernetes有(you)(you)(you)很(hen)多想法,覺(jue)得在云平臺里面(mian)(mian)其實(shi)有(you)(you)(you)很(hen)多有(you)(you)(you)意思的(de)(de)事情。比(bi)方說(shuo),如何(he)提供穩定的(de)(de)中間層來(lai)讓企業的(de)(de)業務更加的(de)(de)穩定和安(an)全;如何(he)降(jiang)低硬件的(de)(de)成本;如何(he)應對業務的(de)(de)突飛猛進和彈性支持,諸如此類。一(yi)開始喜歡Kubernetes,覺(jue)得在這兩個技(ji)(ji)術以后將在技(ji)(ji)術領(ling)(ling)域大有(you)(you)(you)作為(wei)。在技(ji)(ji)術領(ling)(ling)域,了解到才云研發(fa)實(shi)力(li)很(hen)強(qiang),并且在Kubernetes里面(mian)(mian)有(you)(you)(you)影響力(li),來(lai)到公司(si)體(ti)驗之后感覺(jue)工作氛圍(wei)很(hen)好(hao),于是就(jiu)過來(lai)了。”
對于Kubernetes1.6中GPU功能的想法
趙(zhao)慧智說(shuo):“關于Kubernetes1.6,我是(shi)希望把GPU的(de)功能(neng)加進去,因(yin)為(wei)目前很(hen)多應用都能(neng)在GPU上(shang)(shang)跑出比CPU高很(hen)多的(de)性能(neng),而在云里面(mian)一(yi)(yi)個(ge)很(hen)好(hao)的(de)地方是(shi)通用化,例(li)如一(yi)(yi)個(ge)應用遷(qian)移到另外一(yi)(yi)個(ge)VM 或者Server上(shang)(shang)可以繼續運(yun)行,但是(shi)通用化也導(dao)致了一(yi)(yi)些硬件(jian)特性被屏蔽(bi)了,GPU就是(shi)其中(zhong)之一(yi)(yi),所(suo)以在Kubernetes這樣一(yi)(yi)種container編排的(de)環(huan)境中(zhong)如果能(neng)支持GPU,那么(me)將(jiang)會對一(yi)(yi)些應用的(de)性能(neng)產生質的(de)影響,例(li)如深度(du)學習、AI 等(deng)。”
以下是趙慧智GPU分享具體內容:
GPU
圖形處理(li)器(英語(yu):graphics processing unit,縮寫:GPU),又稱顯示(shi)核心、視(shi)覺處理(li)器、顯示(shi)芯片(pian),是一(yi)種專門在個(ge)人電腦、工(gong)作站、游戲機和一(yi)些移動設備(如平板(ban)電腦、智能手機等)上運行繪(hui)圖運算工(gong)作的微(wei)處理(li)器。
GPU較大的好(hao)處就(jiu)在于(yu)可以通過(guo)遠遠多于(yu)CPU的core數(shu)量(liang)來達到并(bing)行計算。
CUDA(Compute Unified Device Architecture,統一(yi)計算(suan)架(jia)構)是(shi)由NVIDIA所推出的(de)(de)一(yi)種(zhong)集成(cheng)技術,是(shi)該(gai)公司對于GPGPU的(de)(de)正式名稱(cheng)。通(tong)過這個技術,用戶可利用NVIDIA的(de)(de)GeForce 8以后的(de)(de)GPU和較新的(de)(de)QuadroGPU進行計算(suan)。亦是(shi)首次可以利用GPU作為C-編(bian)譯(yi)器的(de)(de)開發環境。NVIDIA營銷的(de)(de)時(shi)候,往(wang)往(wang)將編(bian)譯(yi)器與(yu)架(jia)構混合推廣,造成(cheng)混亂。實(shi)際(ji)上,CUDA可以兼容OpenCL或者NVIDIA的(de)(de)C- 編(bian)譯(yi)器。
CUDA提供(gong)了對于一般性通(tong)用需(xu)求的(de)大規模并發編(bian)程模型(xing),使用戶可以對NVIDIA GPU方便的(de)對于 GPU進行并發性編(bian)程。
CUDA編程(cheng)模型與傳統編程(cheng)模型比較(jiao):
樣例:將數組a與數組b相加,并將結果賦值(zhi)給(gei)c
傳統方式:
數組(zu)會按照(zhao)從a[0] + b[0] 一直順(shun)序執(zhi)行到a[n] + b[n]。
多核計算方式:
如果(guo)進行(xing)(xing)編(bian)(bian)譯(yi)優(you)化會(hui)在(zai)特定操作系統里面把這個數組的(de)(de)相(xiang)加分配(pei)到(dao)不(bu)同(tong)的(de)(de)core里面執行(xing)(xing),這樣(yang)所有(you)的(de)(de)計(ji)算(suan)就(jiu)會(hui)按照core的(de)(de)數量進行(xing)(xing)并(bing)發(fa),那么(me)我(wo)們可(ke)以(yi)(yi)(yi)看(kan)到(dao)在(zai)數組操作中,效率的(de)(de)高低取決于(yu)core的(de)(de)多(duo)少。而通常個人的(de)(de)計(ji)算(suan)機一般會(hui)有(you)2-8個core不(bu)等,而大(da)部分服務(wu)器也很(hen)少會(hui)超過100個core。然而,一個GPU很(hen)容易就(jiu)可(ke)以(yi)(yi)(yi)達到(dao)上(shang)(shang)(shang)千(qian)個core,這樣(yang)在(zai)進行(xing)(xing)并(bing)行(xing)(xing)計(ji)算(suan)的(de)(de)時候可(ke)以(yi)(yi)(yi)實現十幾甚至上(shang)(shang)(shang)百上(shang)(shang)(shang)千(qian)倍的(de)(de)效率提升。而GPU的(de)(de)價(jia)(jia)格遠遠低于(yu)相(xiang)同(tong)個數core的(de)(de)CPU(多(duo)個)的(de)(de)價(jia)(jia)格。既然CUDA可(ke)以(yi)(yi)(yi)提供一般性(xing)的(de)(de)并(bing)發(fa)編(bian)(bian)程(cheng)模型,那么(me)我(wo)們來看(kan)看(kan)在(zai)CUDA平臺上(shang)(shang)(shang)上(shang)(shang)(shang)面的(de)(de)代碼(ma)該怎么(me)寫。
代碼示例:
申請一塊GPU的內存(cun),然(ran)后就可以(yi)把(ba)所有的并發操(cao)作都交給GPU。
GPU in Docker
關(guan)鍵詞:--device
Docker是具有把(ba)device通(tong)過(guo)cgroup里面的(de)deivce來mapping到container上的(de)能(neng)力(li)的(de),我們可以通(tong)過(guo)“--device”來達到這(zhe)個(ge)目的(de)。
docker run -it --device/dev/nvidia0:/dev/nvidia0 \ // 第一個 Nvidia 卡
--device /dev/nvidia1:/dev/nvidia1 \ // 第二個 Nvidia 卡
--device /dev/nvidiactl:/dev/nvidiactl \ // 這個是作(zuo)為Nvidia操作(zuo)的必須mount的設備
--device /dev/nvidia-uvm:/dev/nvidia-uvm \ // 這(zhe)個是(shi)作為Nvidia操作的必須(xu)mount的設備
tf-cuda:v1.1beta/bin/bash
然后我們可以通過“docker inspect:” 來檢(jian)查container所指定的設備(bei)。
然后(hou)我們在(zai)container的內部就(jiu)可(ke)(ke)以(yi)看到(dao)相應的設備并且可(ke)(ke)以(yi)使用了。
在設(she)備已經(jing)可以綁定了之后,我們就可以提供driver和CUDA的(de)(de)支持(chi)(chi)了,而Nvidia給了一個(ge)關于(yu)如何在 container層面支持(chi)(chi)GPU的(de)(de)原型,是(shi)基于(yu)Docker的(de)(de),叫做Nvidia Docker。
Nvidia Docker所提(ti)供的功(gong)能:
Volume: Nvidia driver/NVML tools.
Assign GPUs to container automatically.
Basic cuda container build.
Multi-platform environment.
目(mu)前(qian)我(wo)們已經支(zhi)持(chi)了(le)如何在(zai)container的層面(mian)(mian)(mian)支(zhi)持(chi)GPU,但是這還遠遠不夠(gou)在(zai)container編排環境里面(mian)(mian)(mian)支(zhi)持(chi)GPU,譬(pi)如我(wo)們在(zai)Kubernetes里面(mian)(mian)(mian)支(zhi)持(chi)GPU。
GPU in K8S:
在Kubernetes里面我們做一些關于(yu)GPU的工作(zuo)才能(neng)(neng)讓GPU能(neng)(neng)夠被調(diao)度起(qi)來,功能(neng)(neng)如下:
GPU discovery.(kubelet):加(jia)入這個功(gong)能(neng)是為了能(neng)夠讓Kubelet在啟動的(de)同時就(jiu)可(ke)以查找本機上的(de) GPU,而這個GPU消息(xi)可(ke)以發送給(gei)apiserver,但(dan)apiserver里(li)面(mian)有GPU的(de)信息(xi)后,就(jiu)可(ke)以通過kube-scheduler進行調(diao)度了。
GPUassignment/release. (kubelet):當一個container存在(zai)GPU需求的時候,我們可以通(tong)過docker的--device 層面來支持對(dui)于(yu)GPU的assign和release Resource API.(kube-apiserver/kube-scheduler):在(zai) kube-scheduler和kubelet之間需要(yao)一個關于(yu)GPU資(zi)(zi)源的協議支持,譬如(ru)目前有CPU,memory等(deng),為了(le)讓GPU能夠被調(diao)度,我們需要(yao)引入GPU作為一個資(zi)(zi)源可以被調(diao)度。
GPU in TensorFlow:
在分布式(shi)TensorFlow環(huan)境里面(mian),各個(ge)worker不互相通(tong)信(xin),只會(hui)跟(gen)parameter server通(tong)信(xin)。所(suo)以(yi)即使將各個(ge)worker部署(shu)到(dao)不同(tong)的機器上(shang)也不會(hui)造(zao)成性能(neng)損耗。目(mu)前(qian)TensorFlow支持GPU進行(xing)training的運算,但(dan)需要進行(xing)編(bian)譯時設置。
GPU in K8S + TensorFlow
由于在(zai)部署分布式TensorFlow時極(ji)其(qi)繁瑣,并(bing)且在(zai)每(mei)次(ci)擴容都(dou)需(xu)要(yao)進(jin)行(xing)很多(duo)設置(zhi)和操作。所(suo)以(yi)提供基于容器化的(de)TensorFlow并(bing)運行(xing)在(zai)Kubernetes上就使其(qi)變得相當容易,而我們需(xu)要(yao)做的(de),就是在(zai)上面提到的(de)如何(he)讓Kubernetes支持GPU的(de)情況下,將(jiang)TensorFlow容器化。