JuiceFS 在多雲架構中加速大模型推理

JuiceFS發表於2024-08-23

在大模型的開發與應用中,資料預處理、模型開發、訓練和推理構成四個關鍵環節。本文將重點探討推理環節。在之前的部落格中,社群使用者 BentoML貝殼的案例提到了使用 JuiceFS 社群版來提高模型載入的效率。本文將結合我們的實際經驗,詳細介紹企業版在此場景下的優勢

下圖是一個典型的大模型推理服務的架構。我們可以觀察到幾個關鍵特點。首先,架構跨越多個雲服務或多個資料中心。目前在大模型領域, GPU 資源緊張,多數廠商或公司傾向於採用多雲、多資料中心或混合雲的策略來部署他們的推理服務。

另一個特點是,為了確保資料一致性和管理的便捷性,會在特定地區選擇公有云的物件儲存作為所有模型資料的儲存點。當進行推理任務排程時,可能會選取特定雲服務進行任務排程。資料模型的拉取過程需要人工介入,如提前進行資料複製。這是因為排程系統不清楚當前資料中心具體需要哪些資料,而這些資料又是動態變化的,所以資料複製過程會帶來額外成本。

此外,從每個推理計算叢集的內部情況來看,由於是規模龐大的叢集,會有數百到數千 GPU 卡,因此在推理伺服器初始化時,會有高併發模型資料拉取需求。

因此,概括地說在大模型推理與儲存相關的挑戰主要集中這樣幾個方面:高效訪問資料、跨區域資料快速分發、存量資料讀取以及資源最佳化。接下來將逐個為大家介紹我們在這些場景中的實踐經驗。

挑戰 1:如何保證大模型資料的高吞吐、高併發讀取?

推理環節常需處理百 GB 級別的模型檔案,滿足高併發順序讀取需求。載入速度是使用者最關注的問題之一。
為了滿足這種場景的效能需求,可以藉助 JuiceFS 企業版的分散式快取構建大規模的快取空間。將常用模型資料集中儲存在快取叢集中,能顯著提高資料讀取速度,特別是在同時啟動數千個推理例項時。此外,對於需要頻繁切換模型的 AI 應用場景,如 Stable Diffusion 文生圖服務,快取叢集可以大幅減少模型載入時間,從而直接提升使用者體驗。

例如在單機單卡載入 Safetensors 格式的 Stable Diffusion 模型時,從快取叢集讀取資料的延遲可低至 0.5ms,而從物件儲存讀取的延遲通常在 20ms 左右, 效能提升了將近 40 倍

下圖是 JuiceFS 分散式快取的架構圖,上層為推理叢集,中間層為 JuiceFS 快取叢集,底層為物件儲存,右上角是後設資料服務。在推理服務部署後,首先透過推理叢集上掛載的 JuiceFS 訪問所需的模型資料。如果資料可以在推理叢集的本地記憶體快取中找到,則直接使用;若未命中,則查詢位於中間的快取叢集。快取叢集如果也未命中,最後會從物件儲存讀取資料。

雖然推理叢集和快取層從圖上看似乎是分開的兩個層次,但在實際應用或部署中,如果GPU 機器上有 NVMe SSD,這兩層可以合併。

在每個 GPU 機器都配備多塊 SSD 的情況下,下圖示例中,每個 GPU 機器配有三塊 SSD,其中一塊 SSD 用作本地快取,其餘兩塊 SSD 則用作分散式快取的儲存盤。這種情況下,我們推薦一個部署方式:在一個 GPU 伺服器上部署兩個客戶端,FUSE daemon 和快取叢集客戶端。當推理任務需要讀取資料時,它首先會嘗試從本地 FUSE 掛載點讀取資料。如果本地快取中沒有相應的模型資料,推理任務將透過同一臺機器上的另一個 JuiceFS 客戶端訪問分散式快取。完成資料讀取後,資料將返回給推理任務,並在快取叢集管理的兩塊 SSD 及本地 FUSE 掛載點上快取,以便未來快速訪問。

這種在一個 GPU 伺服器上部署兩個客戶端的做法有兩個主要好處:

  • 首先,透過本地快取,可以儘量減少網路通訊的開銷,雖然 GPU 伺服器間透過高速網路卡進行網路通訊,但網路通訊本身還是會產生大量的開銷;
  • 其次,透過快取叢集客戶端,可以讓推理任務訪問其它 GPU 伺服器上的資料,實現一個分散式快取叢集的效果。

挑戰 2:如何在多雲、混合雲架構中有效地分發模型資料到各計算節點?

在多雲和混合雲架構中,由於資料分散在不同的雲平臺和資料中心,傳統的手動介入、複製和遷移方法不僅成本高,而且管理和維護也較為複雜,包括許可權控制在內的各種問題都十分棘手。

JuiceFS 企業版映象檔案系統功能允許使用者將資料從一個地區複製到多個地區,形成一對多的複製關係。整個複製流程對使用者和應用來說是透明的:只需將資料寫入指定區域,系統便會自動規劃並複製到其它多個區域。

下圖展示了在映象檔案系統中資料寫入與資料讀取時的流程。圖中展示了兩個區域:源區域和映象區域。當資料在源區域寫入時,JuiceFS 會自動將資料從源區域複製到映象區域。

在讀取資料時,映象區域的客戶端首先嚐試從其所在區域的物件儲存中拉取資料。如果資料不存在或因同步延遲未到達,則自動回退到源區域儲存,透過備用資料來源鏈路拉取資料。因此,映象區域的所有客戶端最終都能訪問到資料,雖然部分資料可能來自備用資料來源。

寫資料流程示例

這裡展示了一個大模型企業實際部署映象檔案系統的案例,其架構與文章開頭展示的典型架構圖相似。在圖的頂部有一箇中心叢集,該叢集作為資料生產的源頭。

  • 步驟 1:寫資料。資料首先在中心叢集中被建立並寫入;
  • 步驟 2:全量映象後設資料。資料生產完成後,將寫入到 JuiceFS 中,觸發後設資料的全量映象流程。如圖所示,資料從中心的 JuiceFS 後設資料服務被映象到一個或多個邊緣叢集(本例中為三個),使得邊緣叢集能夠就近訪問本地叢集內的後設資料;
  • 步驟 3:預熱快取(可選)。這一步是為了最佳化資料訪問速度。當有新資料新增後,除了複製後設資料外,還希望能夠就近訪問這些資料。在沒有物件儲存的環境中,可以結合分散式快取功能,在每個機房內部署一個分散式快取叢集。然後透過快取預熱,將新增的資料複製到每個邊緣叢集的快取叢集中,從而加速資料訪問。

讀資料流程示例

  • 步驟 1:訪問映象的後設資料服務。如上圖綠色編號所示,當 GPU 叢集需要獲取模型資料時,首先會訪問映象的後設資料服務;
  • 步驟 2:讀取後設資料並獲取資料。在讀取到後設資料後,客戶端會首先嚐試透過機房內的快取叢集獲取所需資料。如果之前進行了快取預熱,那麼大多數情況下可以直接在機房內的快取叢集中命中所需的模型資料;
  • 步驟 3:回源資料。如果由於某種原因未能在快取叢集中找到資料,也無需擔心,因為所有快取叢集的節點都會自動回源至中心的物件儲存桶中獲取最終的原始資料。

因此,整個資料讀取流程是暢通無阻的。即使部分資料未被預熱或新資料尚未預熱成功,也可以透過自動回源的方式,從中心的 JuiceFS 儲存桶中拉取資料。

挑戰 3:低成本高效讀取海量存量資料

除了多雲、混合雲架構下資料分發的挑戰,還有一個常見的需求,在與多家大模型公司的交流中,我們瞭解到許多公司希望將其積累的大量原始資料(如數 PB 級別)直接遷移到 JuiceFS 中。這種需求增加了大規模資料管理的複雜性,並可能需要進行資料雙寫等調整,這些都可能影響業務流程的正常運作。

JuiceFS 企業版的「匯入物件儲存後設資料」功能使得企業可以更高效地完成資料匯入,同時減少對業務的侵入性。使用者無需進行資料複製,只需持續匯入後設資料即可。同時,匯入的資料可以透過 JuiceFS 的分散式快取進行加速,從而提升資料訪問速度。下圖是該功能的工作流程示意圖:

第一步,匯入後設資料。透過 JuiceFS 的命令列工具,使用者可以選擇性地匯入原始資料桶中的部分資料,而不必匯入整個儲存桶。這一過程主要透過字首匹配實現,此步驟僅涉及後設資料的匯入,不複製物件儲存中的資料,因此匯入流程會很快完成。

後設資料匯入不是一次性的操作,隨著原始資料的增加或修改,使用者可以再次執行增量匯入,無需擔心重複匯入造成額外開銷。每次增量匯入時,系統只會匯入新增或修改的部分資料的後設資料,不會重複匯入已處理的檔案,從而避免額外負擔。

第二步,讀取後設資料。當後設資料匯入到 JuiceFS 後,應用(例如推理任務)便能透過 JuiceFS 客戶端訪問這些匯入的資料。因此,應用可以立即開始執行,無需等待原始資料桶中的資料複製到 JuiceFS 中。

第三步,讀取資料。在推理等場景中,通常會配置分散式快取以最佳化資料讀取。由於在第一步中僅匯入了後設資料而未匯入實際資料,初次透過分散式快取讀取時將無法直接獲取資料。

第四步,回源原始桶並快取資料。這一步需要透過分散式快取系統回源到原始資料桶中,從中檢索並讀取資料。讀取完成後,資料會自動快取到 JuiceFS 的分散式快取中,這樣在後續訪問相同資料時,就無需重新回到原始資料桶中進行資料讀取,從而提高資料訪問效率。

經過這幾個步驟,推理任務便能夠快速訪問存量資料,並獲得高效能分散式快取的加速效果。

挑戰 4:在異構環境中,如何充分利用硬體資源以最佳化儲存和計算效能?

異構環境涉及到一個系統內部整合多種不同型別或配置的硬體裝置,只有充分利用異構的硬體資源才能為企業帶來最大價值。在下面這個示例中,我們有三臺機器,每臺機器配備的 SSD 數量和容量如下表所示,根據每臺機器的總儲存容量,這三臺機器的快取容量比例為 1:2:3。

編號 SSD 數量 單塊 SSD 容量(TB) 總容量(TB)
機器 1 2 4 8
機器 2 2 8 16
機器 3 3 8 24

預設情況下,JuiceFS 的分散式快取假設所有機器的硬體配置是同構的,因此所有快取節點的權重相同。在這種配置下,整個系統的效能將被最小容量機器的容量上限所限制,在這個示例中是 8TB,其它機器快取盤無法被充分利用,第三臺機器中甚至有 ⅔ 可能未被利用。

為了避免這種情況,我們引入了「快取節點權重」的概念,允許使用者根據實際環境動態或靜態地調整每個 GPU 節點的權重。例如,第一臺 GPU 伺服器的快取權重可以設定為預設值 100,第二臺為 200,第三臺為 300,這些權重與 SSD 容量的比例(1:2:3)相對應。透過這種差異化權重設定,可以更有效地利用各快取機器的儲存資源,最佳化整體系統的效能。這種方法為處理不同硬體配置的機器提供了一個典型的解決方案。

除了上述這個場景外,快取節點權重還可以應用於其它場景。例如,GPU 機器容易出現故障,使用者可能每週需要對一兩臺機器進行下線和更換硬體等常規運維操作。因機器直接停機將導致該機器上的快取資料丟失或暫時無法訪問,這可能影響整個快取叢集的命中率。在這個場景中,也可以使用「快取節點權重」功能,來儘可能減少機器故障或維護過程中對快取叢集利用率的影響。

未來展望

最後,讓我們探討一下未來我們在推理場景以及其它潛在應用場景中將要進行哪些改進。

首先,引入分散式快取的多副本特性。目前,分散式快取系統中的資料通常是單副本形式,意味著如果某臺機器(如 GPU 伺服器)意外當機,該機器上的快取資料將因缺乏備份而丟失,從而直接影響快取命中率。由於這種情況是突發的,我們無法透過人工干預來逐步遷移資料至其它節點。

在這種背景下,單副本快取將不可避免地影響整個快取叢集的效率。因此,我們正在考慮將其從單副本升級為多副本。這種升級的好處顯而易見:儘管使用了更多的儲存空間,但是可以顯著提高機器頻繁故障場景的快取命中率和快取的可用性。

第二點,我們正在探索使用者態客戶端的實現。當前,基於 FUSE 掛載方式的檔案系統雖然能有效地實現檔案系統功能,但由於其依賴 Linux 系統核心,涉及使用者態與核心態之間的多次切換和資料複製,因此帶來了一定的效能開銷。尤其在雲上的無伺服器(serverless)和 Kubernetes 環境中,FUSE 掛載可能無許可權使用,這限制了 JuiceFS 的應用場景。

因此,我們正在考慮開發一個純使用者態的客戶端,這將是一個不依賴核心態的元件,可以顯著降低使用門檻,並在不支援 FUSE 的環境中提供服務。此外,由於避免了核心態與使用者態的頻繁切換和記憶體複製,這種客戶端在效能上也可能有顯著提升,特別是在需要高吞吐量的 GPU 密集型環境中。

然而,這種客戶端的一個潛在缺點是它可能不如 POSIX 介面透明,因為它可能需要使用者透過引入特定的庫(如 JuiceFS 庫)來實現功能,這種方式可能會對應用程式產生一定的侵入性。

第三,提升可觀測性。鑑於 JuiceFS 架構中包含多個複雜環節,如從 GPU 機器到快取叢集,再透過專線回到中心的物件儲存,以及快取預熱等,我們計劃引入更便捷的工具和方法來增強整體架構的可觀測性。這將有助於 JuiceFS 的使用者更快更方便地定位及分析問題。未來我們將進一步最佳化包括分散式快取在內的各個元件的可觀測性,幫助使用者在出現問題時進行快速的問題排查和解決。

希望這篇內容能夠對你有一些幫助,如果有其他疑問歡迎加入 JuiceFS 社群與大家共同交流。

相關文章