面向大模型的存儲加速方案設計和實踐

1. 大模型對存儲的全新挑戰

從過去的經典 AI,到今天人人談論的大模型,我們看到 AI 模型的參數規模呈現出指數級的爆發增長一方面,大模型的應用效果開始給大家帶來非常大的驚喜,另一方面,也給整個基礎設施帶來巨大的挑戰。

其一,模型規模大,訓練時間長。一個 175B 參數的模型,萬卡同時訓練仍然需要長達 22 天。這就要求基礎設施提供超高的性能和超長時間的穩定。

其二,大模型要結合具體應用才能發揮巨大的威力。家今天談論大模型,不再只停留在模型本身,更多的關注已經聚焦於結合業務的應用落地。面對互聯網級的應用迭代,要求我們具備大規模的敏捷部署能力。

第三,大模型離不開持續更新的海量數據,這就需要與整個數據生態互通,讓數據能在各個環節便捷地流動。

在這樣的背景下,我們來對大模型全流程做一個拆分,大致可以劃分爲四個主要的環節。

  • 第一是海量數據的存儲和處理,包括採集導入、清洗、轉換、標註、共享和長期歸檔,是後面各環節的基礎。這裏對存儲的要求跟以前的大數據應用具有很大的共性,也帶有大模型自身的特點,總結起來主要是生態的互通、高吞吐和大容量。

  • 第二是模型開發,講究效率爲王,包括實驗管理、交互式開發和效果評估等。對存儲的要求更多集中在 POSIX 兼容性、可靠性和可共享等方面。

  • 第三是模型訓練。真正做過大模型訓練的朋友一定深有體會,每分每秒都是經費在燃燒。所以時間就是金錢,拒絕等待,拒絕失敗。這裏的主要場景,一是訓練數據的讀取,二是爲了容錯做的 checkpoint 的保存和加載。數據集的部分就是要儘量讀得快,減少計算對 I/O 的等待,而 checkpoint 主要要求高吞吐、減少訓練中斷的時間。

  • 最後是模型推理,需要把訓練完的模型快速分發部署到線上,產生業務效果。而這個過程會高頻、反覆發生,既要求高併發、高吞吐,又要求整個流程儘量簡單高效。

從這四個環節的分析,我們總結出大模型對存儲的第一個挑戰:不同環節對存儲提出了複雜多樣的需求。

進一步,我們又把大模型的各個環節按照業務流程串聯起來。整體上可分爲大模型應用、數據系統和 AI 系統三大部分。

其中數據系統的部分在過去的大數據應用中大家都比較熟悉了,最終是讓數據與應用產生一個正向反饋的閉環。

而加入 AI 系統以後,面臨着更多環節的數據流動。首先經過預處理的數據由數據系統流入 AI 系統被加載訓練,訓練結果進入模型倉庫,再由模型倉庫部署到線上提供推理服務,而推理效果的相關數據又會回到數據系統,用於下一步的評估和後續迭代。

因此可以看到,大模型應用、數據系統、AI 系統三大部分實際上構成了一個更大的閉環。其中各環節間的銜接,本質上都是對數據廣泛、高效流動的需求。這是大模型對於存儲的第二個挑戰。

接下來,我們就帶着這兩個挑戰,一起來看大模型各環節具體存儲問題的解決思路。

2. 大模型全流程存儲問題的解決思路

我們首先來關注第二個挑戰,解決海量數據的存儲和流動問題,這是解決其它問題的基礎。

當我們把數據系統中,數據流入、處理和流出的具體手段稍作展開,就會發現大模型依賴的數據需要與如此廣泛的生態頻繁交互,基於原來的本地存儲或者自建的小規模商用存儲已經無法充分利用這些生態的優勢。因此數據湖存儲已經成爲這裏事實上的首選方案。

而數據湖存儲其實有兩個主要的選擇。一是以 HDFS 爲代表的分佈式文件系統,另一個是對象存儲。從兩類系統的架構來對比,可以觀察到兩點:

  1. 其一是擴展能力。HDFS 採用集中式元數據管理,規模相對受限,而對象存儲通常採用分佈式平坦元數據,具有更強的水平擴展能力,單集羣可支持萬億文件、EB 級規模。在我們對於實踐的觀察中,曾經有業務基於 HDFS 做大模型訓練,受限於擴展能力,不得不將海量小文件進行打包存儲,在訓練時再下載解壓,實際上引入了非常多的流程開銷;

  2. 其二是成本考量。HDFS 誕生於存算一體的時代,而對象存儲天然面向存算分離設計,結合 EC 編碼、分級存儲等豐富的能力,可以實現大規模數據長期保存的更優成本。

另外,從可用性、吞吐、生態支持等方面來對比,對象存儲也具有一定的優勢。所以雖然 HDFS 起步較早,但綜合來看對象存儲纔是數據湖存儲的更優選擇。

尤其是在今天這個雲原生的時代,基於對象存儲的數據湖更是成爲了雲上的數據中樞。

帶着這個結論回到我們開始的問題,可以看到利用基於對象存儲的雲原生數據湖就能很好地解決數據系統內各環節的銜接。但是 AI 系統各環節的數據流動和銜接問題,能否也用同一套存儲來解決呢?

假如答案是肯定的,那麼我們就能得到一個非常統一和簡潔的存儲架構。最下面是數據湖,上面承接從數據系統到 AI 系統所有環節的需求,數據流動會被大大簡化,各環節的銜接運轉效率也會得到很大的提升。

而這裏的關鍵就是要接着回答我們最開始提出的第一個挑戰,如何用對象存儲滿足大模型開發、訓練、推理等各環節的多樣化需求。

首先我們以大家比較關心的模型訓練環節爲例做一個分析。

對於一個典型的訓練來說,可能迭代多輪 epoch。在每個 epoch 內,首先需要對數據集進行隨機打散,然後將打散後的數據劃分爲若干 batch,每讀取一個 batch 的數據,進行一次訓練迭代。同時會週期性保存 checkpoint 用於故障快速恢復。

如果我們把訓練過程進一步展開,可以觀察到這樣的時序關係。每一輪 epoch 的耗時都是由數據 shuffle、數據讀取等待、checkpoint 和真正的訓練時間相加得到。因此爲了儘量提高訓練效率,減少 GPU 的空閒,我們的主要優化就集中在三個思路:

  • 優化 shuffle 過程,儘量將耗時控制在較小比例;

  • 優化讀取過程,儘量讓每一輪讀取數據的耗時小於計算耗時,這樣就能讓 I/O 時間被計算時間完全隱藏掉;

  • 優化 checkpoint 過程,儘量縮短 checkpoint 耗時,減少訓練中斷時間。

接下來我們先分析數據的 shuffle 和讀取,checkpoint 過程隨後再討論。

如果我們對 shuffle 和讀操作進行具體的分析,就會發現,shuffle 是一個純元數據操作的過程,主要依賴大量文件的 LIST,讀取過程則元數據和數據操作都有。

而對於大模型訓練用到的 KB 級小文件而言,文件越小,元數據操作的耗時佔比也就越高;I/O 越小,延時和 QPS 越超過吞吐成爲主要矛盾。因此,對於小文件的 shuffle 和讀取,延時和 QPS 是提升性能的關鍵。

分析完典型的訓練過程以後,我們再來看對象存儲面對小文件時有哪些影響性能的因素。

其一,元數據方面,對象存儲採用分佈式 KV 或 NewSQL 維護平坦目錄元數據,很好地解決了小文件的規模擴展問題。雖然大部分操作性能很好,但恰恰 shuffle 用到的 LIST 操作性能在部分場景下不夠理想,延時偏高;

其二,對象存儲協議的整個處理路徑較長,對於大文件吞吐爲主的場景可以忽略,但對於小文件的頻繁讀取則會帶來不可忽視的延時開銷。

不難發現,對象存儲的高吞吐能力給小文件讀取帶來的幫助比較有限,而在延時上也並不具有優勢。面對這樣的問題,我們有哪些解決思路呢?

我們分爲幾個方向來總結:

  • 讓敵人變弱,也就是通過一些打包格式減少小文件元數據操作的佔比。比如 TFRecord、HDF5 等格式已經被大量應用。如果存儲能配合這些格式做一些優化,那麼效率將得到進一步提升;

  • 讓自己變強。硬件上通過燃燒經費購買高性能硬件不需要過多解釋。軟件上則一般通過架構升級提升系統的擴展能力,縮短 I/O 路徑,這裏的典型方案就是並行文件系統;

  • 儘可能近身攻擊。讓存儲和計算靠得更近,這裏的典型方案就是緩存系統。利用數據集只讀的特點,將元數據和數據緩存到計算節點,或者靠近計算節點的地方,也能大幅提高數據的訪問效率。

從整體來看,前面我們已經基於對象存儲的雲原生數據湖解決了海量數據的存儲和流動問題。這裏我們可以進一步基於並行文件系統或緩存系統的數據存儲加速層來彌補對象存儲的短板,滿足大模型各環節的性能需求。

有了這一套「數據湖 加速層」的思路,我們就來詳細看看大模型的訓練、推理幾個具體場景下的問題如何被一一解決。

第一個場景,先來看數據集的讀取加速。

假如數據已經進入加速層,那麼讀性能的問題就能得到很好的解決。剩下需要解決的是數據怎麼進入加速層的問題。

在過去我們大量依賴人工和外圍工具做不同存儲之間的數據流轉,帶來不少弊端。今天的加速層設計,通常會選擇內置自動的數據流轉功能。比如在加速層通過 bucket link 建立對象存儲某一個 bucket 到加速層的關聯,就能自動完成數據在兩層之間的流動。這種方式有諸多優點:

  • 同步速度快,各節點可以併發同步數據,大大加快數據流轉效率;

  • 同步策略可定製,可以按照場景需求進行增量同步、選擇性同步;

  • 能夠與調度器集成,實現數據準備與資源調度的高效配合;

  • 避免了人工方式需要處理各類異常,做垃圾回收的問題。

這裏就是一個基於自動數據流轉實現調度優化,減少訓練過程數據讀取等待的例子。當兩個任務都需要先加載數據然後才能開始訓練,通過訓練平臺的流水線化調度,在一個任務做訓練的同時發起下一個任務所需數據的提前加載,就能大大提高計算資源的利用率。

第二個場景,我們接着來看訓練中的 checkpoint 部分。

與訓練數據以小文件爲主不同,大模型單個節點的 checkpoint 通常就能達到幾十上百 GB。而多個訓練節點同時寫,需要恢復時又同時讀,對存儲提出了很高的吞吐要求。同時一個關鍵的問題是 checkpoint 期間整個訓練是中斷的。因此通過提高吞吐,將 checkpoint 耗時控制在儘量小的佔比,對於減少訓練等待、提高計算資源利用率同樣非常重要。

在之前有一種樸素的做法。訓練程序先將 checkpoint 寫到性能相對容易保證的本地存儲,然後再通過外圍工具向遠端對象存儲上傳。這裏需要考慮一個問題,如果要保證每個 checkpoint 都成功寫入,那麼總耗時就等於寫本地耗時加上傳對象存儲的耗時,總體等待時間較長。因此實際應用中也有延遲一個 checkpoint 異步上傳的方案。但無論如何,都引入了額外的複雜度,需要外圍工具來處理各種異常情況。

現在基於數據湖存儲加速以後,我們可以有新的做法。訓練程序直接將 checkpoint 寫入加速層的 Memory 或 NVME SSD,加速層採用流式上傳的方式,不必等待 checkpoint 數據全部寫完就開始向對象存儲上傳。此外,加速層也會採用分塊上傳的辦法,充分利用對象存儲的後端併發能力。

這個方案看上去比樸素方案有了很大的進步,但是由於需要保證 close 完成時數據已經完整寫入對象存儲,因此吞吐瓶頸仍然可能出現在上傳對象存儲的帶寬限制上。我們稱這種方案爲同步方案。

其實對 checkpoint 場景稍加分析就能發現,我們並不一定需要同步方案,因爲訓練過程的 checkpoint 會週期不斷地進行,而發生故障恢復不應該是常態。因此要突破上傳對象存儲的帶寬限制,異步寫是一種值得嘗試的思路。

這個方案最大的變化,就是對 checkpoint 文件的 close 操作變成了異步,訓練程序不用等待數據上傳完成,即可恢復訓練,剩下的工作全部交給加速層透明完成。此時耗時主要取決於加速層的 Memory 和 NVME SSD 寫入能力,可以大大縮短 checkpoint 寫入時間。

另外,這裏還有一個相關的優化,就是對於最新的一個 checkpoint 採用異步寫的同時,讓它駐留在加速層的緩存內。當訓練需要恢復的時候就能直接從加速層讀取,解決了 checkpoint 的快速加載問題。

最後我們來看第三個場景,也就是推理階段的模型分發部署。大模型的部署通常是百 GB 模型文件的高併發重複讀取。由於推理服務規模大,模型迭代更新頻繁,我們需要從提高吞吐和縮短流程兩個方面考慮如何優化。

首先來看過去常用的基於鏡像分發的方案。

訓練產出的模型首先需要落到臨時存儲,完成鏡像的製作,包括數據打包、壓縮等過程,然後再從臨時存儲寫入持久化的鏡像倉庫。在推理部署時,再從鏡像倉庫併發拉取到各推理實例的本地存儲,然後進行解壓和數據校驗。可以看到在這個方案下,吞吐主要取決於鏡像倉庫底層存儲的能力,而流程上在鏡像製作和鏡像分發兩個階段都需要引入額外的開銷。

如果基於數據湖存儲加速的方案,整個過程會變得非常簡單。

首先從流程上看,訓練產出的模型直接寫入統一的數據湖存儲。這時可以通過對象存儲的事件通知機制,讓加速層立即感知並提前把模型文件的元數據和數據預加載到靠近推理服務的緩存內。當啓動模型部署時,就能直接從緩存讀取到數據。

其次從吞吐上看,基於 Memory 或 NVME SSD 提供靠近推理服務的分佈式緩存,提供了很強的讀吞吐能力,並且多實例重複讀取同一份模型數據時不需要消耗大量的對象存儲 I/O 和帶寬。

另外,加速層可以通過不同的策略滿足不同規模的分發加速需求。比如對於幾十實例以下的小規模部署,採用單副本即可將所有緩存盤的 I/O 能力均衡地利用起來,滿足讀性能要求,同時還能大幅節省緩存空間,保證更多模型數據的緩存命中率。而對於數百實例的部署規模,採用多副本即可提高加速層的讀吞吐能力。到了數千實例的規模,還能進一步結合客戶端的 P2P 加速滿足性能需求。

到這裏爲止,我們分析了模型訓練、推理等環節的三個具體場景。可以看到,在引入數據湖存儲加速層以後,這些場景的具體問題都一一得到了解決。

因此,「數據湖 + 加速層」能夠同時解決最開始提出的兩個挑戰,爲大模型全流程提供了統一的存儲解決方案。

同時也能看到,使用「數據湖 + 加速層」這統一的存儲方案,既能獲得如同過去使用本地盤的便捷體驗,又能充分享受背後數據湖存儲帶來的擴展性、高性能和繁榮的生態。這正是一直以來大家對於存儲的一大夢想。

3. 百度滄海·存儲加速方案和實踐

接下來我向大家介紹百度滄海·存儲加速的解決方案以及具體實踐。

這是百度滄海·存儲加速方案的產品架構圖。底層是我們的對象存儲 BOS,提供了大規模、可擴展、低成本的雲原生數據湖存儲產品,支持豐富的周邊生態和便捷的數據流動。中間就是我們的數據湖存儲加速層,有兩類產品可供選擇。一是並行文件系統 PFS,通過獨立部署、高性能硬件和網絡、全並行軟件架構滿足極致性能需求。二是數據湖存儲加速 RapidFS,通過近計算部署提供更具性價比的分佈式緩存加速能力。最上面是我們的 AI 計算,包括異構算力、高速網絡、雲原生 AI 平臺等。

在雲原生時代,大模型全流程的存儲需求在百度滄海存儲得到了很好的答案:

  • 對象存儲 BOS 及周邊生態提供了雲原生數據湖的完整方案,解決了海量數據的存儲和流動,以及大模型各環節間的銜接問題。

  • RapidFS / PFS 提供了數據湖存儲加速的能力,滿足了大模型各環節內的存儲性能需求。

  • 同時 RapidFS / PFS 通過與 AI 框架和訓練平臺的配合完成資源調度優化,整體效率做到最優。

這是 PFS 和 RapidFS 在雲環境下的部署和應用模式。

數據入湖後,無論選擇哪種存儲加速產品,使用模式都足夠簡單。只需選擇好 BOS 中待加速的數據和加速策略,PFS 和 RapidFS 即可自動完成數據集的加載和預熱,無需任何操心。當訓練任務完成後,PFS 和 RapidFS 透明地將訓練結果同步回 BOS,並回收資源。

最後跟大家分享幾組我們具體實踐中的存儲加速效果。

首先是訓練加速,可以看到使用 RapidFS 相對直接使用 BOS,整體訓練耗時有數倍的縮短,與使用本地存儲的效果基本一致。

同時,RapidFS 和 PFS 兩個加速方案下,GPU 資源利用率相對直接使用 BOS 均有大幅提升。

第二個場景是 checkpoint 寫加速。基於本地盤的方案耗時 245s,上傳 BOS 的耗時 355s。因此如果同步寫完 BOS,整體耗時爲兩者相加,接近 10 分鐘。而使用 RapidFS 方案,整體耗時大幅縮短到 2 分鐘,加速效果明顯。

最後是模型分發場景。橫軸是推理實例數量,縱軸是 RapidFS 的模型分發總吞吐。從這三條曲線的變化可以看出,RapidFS 用滿了緩存盤的所有能力,並且隨着緩存節點規模的增加可以實現接近線性的性能擴展。

以上就是今天分享的全部內容。希望今天的分享能夠幫助大家更好地理解大模型背景下存儲面臨的挑戰和可能的解法。
「加速」從來不止於單純的性能提速,流程的高效和環節的順暢也同樣重要。 希望百度滄海·存儲加速的整體方案能夠幫助大家掃清障礙,加快實現大模型帶來的時代紅利和業務價值。


本文分享自微信公衆號 - 百度開發者中心(baidudev)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章