OpenAI 是如何使用 Kubernetes 的

最近無意間看到一篇兩年前的文章《Scaling Kubernetes to 7,500 nodes》原文如下:https://openai.com/research/scaling-kubernetes-to-7500-nodes#unsolvedproblems。 雖然有點倔墳,但好在里面的東西并不算太落后,至少從OpenAI團隊之前的文章來看,也確實記錄了整個在Kubernetes集群規(guī)模的成長與經(jīng)驗的分享,非常的值得學(xué)習(xí)。正好最近我們 KubeGems PAI(機器學(xué)習(xí)平臺)也遇到一些調(diào)度方面的問題,便再三閱讀并簡單做個筆記與大家分享讀后感。

資源調(diào)度

[圖片上傳失敗...(image-10b29d-1689260468845)]

**解釋:**因為Kubernetes中的每個Node節(jié)點的GPU均采用NVLink和GPUDirect直通網(wǎng)卡,所以在一個Node上僅調(diào)度一個Pod獨占全部資源來達到算力最大化利用。 要實現(xiàn)這個效果,采用NodeSelector和DaemoSet可以最簡單滿足需求,對K8S的調(diào)度壓力也最?。ê竺嬲f到OpenAI并不是使用DaemonSet方式,且也無法做到更高級的調(diào)度策略,這里僅僅只是舉例)。在獨占Node場景下確實不需要調(diào)度支持Bin-Pack(盡可能將pod填充滿node)和Fragmentation(碎片化)算法,因為此時整個集群的資源最小粒度是Node而不是Pod,也自然不用考慮CPU NUMA拓撲結(jié)構(gòu)。也不存在Node資源爭強的問題。

**新知識:**full bisection bandwidth(全雙工切分帶寬)指一個集群中任何一半的節(jié)點都可以與另一半的節(jié)點進行最大帶寬的通信,而不會受到帶寬限制的影響。例如,假設(shè)一個系統(tǒng)有16個節(jié)點,每個節(jié)點都有一個10 Gb/s的網(wǎng)絡(luò)連接。如果系統(tǒng)設(shè)計得很好,那么任何8個節(jié)點都應(yīng)該能夠同時與其他8個節(jié)點進行10 Gb/s的通信。全雙工切分帶寬的主要優(yōu)點是它可以大大提高系統(tǒng)的并行處理能力,因為它可以讓所有的節(jié)點都能夠最大化地利用他們的網(wǎng)絡(luò)帶寬。

[圖片上傳失敗...(image-a8bfb9-1689260468845)]

解釋:我們根據(jù)團隊名字設(shè)計了一個污點openai.com/team=teamname:NoSchedule并把他標(biāo)記到服務(wù)器上,這樣不同團隊在使用資源時就必須要添加污點容忍才能協(xié)調(diào)到資源。同時我們還自己開發(fā)了個控制器,用于在準(zhǔn)入階段將忽略污點,優(yōu)先調(diào)度低優(yōu)先級的pod。這樣就可以讓團隊直接可以彼此借用資源。這個Webhook挺有意思的,熟悉Volcano的知道,它在做資源調(diào)度時也允許不同Queue之間互相借用資源,并reclaim這個布爾值來決定是否當(dāng)前Queue是否允許回收正在使用中的超額資源。這里可以說是英雄所見略同了。

[圖片上傳失敗...(image-bfe398-1689260468845)]

解釋:Gang scheduling在處理MPI作業(yè)時非常重要,原因在于MPI作業(yè)的同步通信特性。由于MPI是一種并行計算的編程模型,它允許進程間通過消息傳遞的方式進行通信,以完成一項共同的計算任務(wù)。在MPI中,一項常見的操作是集合通信,其中所有進程需要同時參與。如果任何一個進程滯后或者不可用,那么所有的進程都將被阻塞,等待該進程完成。這就導(dǎo)致了MPI作業(yè)非常依賴于所有參與進程的同步執(zhí)行。OpenAI實現(xiàn)Gang Scheduling的方式則是通過嵌入k8s scheuler plugis的方式實現(xiàn)。這個插件名叫Coscheduling,當(dāng)前已被合并到scheudler-plugin主線。https://github.com/kubernetes/enhancements/pull/1463. 上文也提到,Gang Scheduling也可通過Volcano來擴展Kubernetes的調(diào)度功能來實現(xiàn)。

并行作業(yè)處理

[圖片上傳失敗...(image-1f450-1689260468845)]

解釋: 參與到運行MPI作業(yè)任務(wù)的work節(jié)點都必須定期進行checkpoint,這是一種容錯機制,可以在作業(yè)出錯或者系統(tǒng)崩潰時恢復(fù)作業(yè)的狀態(tài),用來避免計算出錯后全部重頭來過。

新概念: semi-stateful pod (半狀態(tài)容器),由于并行任務(wù)的Runtime載體是Pod,它的狀態(tài)數(shù)據(jù)主要就是任務(wù)執(zhí)行是產(chǎn)生的checkpoint。顯然這部分數(shù)據(jù)需要被持久化到PVC中。之所以稱之為半狀態(tài),主要在于即便該容器掛了,最壞的情況也是任務(wù)整體暫停并回到上一次checkpoint重新開始,并不會像有狀態(tài)應(yīng)用產(chǎn)生不可逆的災(zāi)難

網(wǎng)絡(luò)

[圖片上傳失敗...(image-6f568d-1689260468845)]

解釋: 訓(xùn)練過程中幾乎沒有外部的網(wǎng)絡(luò)開銷(個人理解不包含存儲數(shù)據(jù)集的數(shù)據(jù)訪問),所以對Kubernetes的kube-proxy,ingress組建沒有特別的依賴。之前調(diào)度部分說過,很多時候一個Node上就調(diào)度一個Pod獨占,我甚至認為有可能Pod直接使用了Host網(wǎng)絡(luò)來最小化網(wǎng)絡(luò)的影響。 此外對Kubernets的服務(wù)發(fā)現(xiàn)應(yīng)用場景也主要是為參與到MPI并行作業(yè)的進程提供網(wǎng)絡(luò)拓撲結(jié)構(gòu),并用在各個Worker之間進行集體通信。

[圖片上傳失敗...(image-79166a-1689260468845)]
解釋: 當(dāng)K8S集群擴大到7500臺時,網(wǎng)絡(luò)方案不管是基于overlay的flannel還是基于路由實現(xiàn)的組網(wǎng),都無法在IP地址擴展性和性能方面做到同時兼顧。所以我們使用了Azure的VMSS解決了我們的問題。

**新知識:**VMSS是Azure上管理大規(guī)模虛擬機集群的網(wǎng)絡(luò)服務(wù)和解決方案。

資料較少,看起來這里看起想表達的意思是OpenAI將Azure上管理虛擬機地址的VMSS服務(wù)通過CNI給Kuberntes Pod用了起來。

[圖片上傳失敗...(image-a69597-1689260468845)]

解釋: 我們的Pod對外訪問還是基于NAT的,只不過用了Iptables來標(biāo)記流量的來源以及使用量,這個主要用來評估Pod間或者說是并行作業(yè)間網(wǎng)絡(luò)通訊是否存在瓶頸

存儲

[圖片上傳失敗...(image-b30272-1689260468845)]

解釋:因為沒有更多資料參考OpenAI中Blob存儲的設(shè)計,按照這里意思,我們存儲的用途主要來放訓(xùn)練時所需要的數(shù)據(jù)集以及記錄訓(xùn)練過程中的checkout(上文有提到)。并且該存儲還支持數(shù)據(jù)的預(yù)熱以加速數(shù)據(jù)訪問效率,同時這個存儲對上還實現(xiàn)了操作系統(tǒng)標(biāo)準(zhǔn)的POSIX接口方便開發(fā)人員直接操作。

API servers

[圖片上傳失敗...(image-b2e76d-1689260468845)]

**解釋:**我們用5臺獨立的ETCD服務(wù)器和5臺獨立的api server服務(wù)器支撐了7500個節(jié)點,并當(dāng)前的配置還足以應(yīng)對未來的擴容的需求。這里面我們的主要優(yōu)化點是將Kuebrnetes Events分離到其它Etcd集群上以減少記錄大量事件的IO帶來的延遲

[圖片上傳失敗...(image-7c1f82-1689260468845)]

解釋:運行大量節(jié)點場景下,每個Node上的List-Watch帶來的泛洪效應(yīng)比較明顯,涓流成河,當(dāng)所有請求都匯聚到API Server后所帶來的傳輸帶寬高達1GB/s! 好在我們用了Kubernete 1.1之后的版本,通過EndpointSlices在服務(wù)器將壓力縮小了1000倍

[圖片上傳失敗...(image-9135d2-1689260468845)]

新知識:EndpointSlices是Kubernetes 1.16 版本引入的新Feature。它將Endpoint信息分散在多個較小的對象中,每個對象只包含一部分Endpoint信息。這樣,對端點的添加、刪除或修改只需要更新一個較小的 EndpointSlice 對象,而不需要更新整個 Endpoints 對象。這大大提高了 Kubernetes 在處理大規(guī)模集群時的性能和可擴展性。

監(jiān)控

[圖片上傳失敗...(image-f78d26-1689260468845)]解釋: 我們也遇到了海量無效的指標(biāo),這真的很"煩人",大部分我們都不從來不關(guān)注。我們Prometheus也經(jīng)常OOM,后來發(fā)現(xiàn)是大量的histogram指標(biāo)查詢堆積造成的。所以我們在后端查詢時設(shè)置了執(zhí)行超時時間,這樣promtheus的內(nèi)存就再沒爆過了。

另外Prometheus重啟后對WAL文件的重放事件慢得我們也無法忍受,后來在Robust Perception的幫助下知道了調(diào)大GOMAXPROCS參數(shù)來設(shè)置goroutine數(shù)來加快重放速度

啊?原來OpenAI的工程師居然不知道 - -!

總結(jié)

OpenAI 將 Kubernetes 集群擴展到 7,500 個節(jié)點,并為 GPT-3、CLIP 和 DALL·E 等大型模型提供了可擴展的基礎(chǔ)設(shè)施,足以證明Kubernetes 是一個非常靈活的平臺,隨著AI行業(yè)的這波浪潮,Kubernetes也會跟著機器學(xué)習(xí)、更大規(guī)模和精細化的調(diào)度迎來一波新的高點。

[圖片上傳失敗...(image-ce1e43-1689260468845)]

[圖片上傳失敗...(image-39a212-1689260468845)]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容