DeepSeek開(kāi)源的文件系統(tǒng),是如何提升大模型效率的?
在 AI 領(lǐng)域里,大模型通常具有百億甚至數(shù)千億參數(shù),訓(xùn)練和推理過(guò)程對(duì)計(jì)算資源、存儲(chǔ)系統(tǒng)和數(shù)據(jù)訪問(wèn)效率提出了極高要求。
2 月 28 日,DeepSeek 開(kāi)源了一種高性能分布式文件系統(tǒng) 3FS,官方表示其目的是解決人工智能訓(xùn)練和推理工作負(fù)載的挑戰(zhàn)。
作為一種并行文件系統(tǒng),3FS 可以在 180 節(jié)點(diǎn)集群中實(shí)現(xiàn) 6.6 TiB/s 的聚合讀取吞吐量,對(duì)于提高 DeepSeek V3、R1 大模型的訓(xùn)練數(shù)據(jù)預(yù)處理、數(shù)據(jù)集加載、檢查點(diǎn)保存/重新加載、嵌入向量搜索和 KVCache 查找等工作的效率有重要幫助。
人們認(rèn)為,DeepSeek 通過(guò)開(kāi)源 3FS 與 smallpond 等工具,在 AI 基礎(chǔ)設(shè)施領(lǐng)域樹(shù)立了新的設(shè)計(jì)范式。其價(jià)值不僅在展現(xiàn)技術(shù)實(shí)力,更是在驅(qū)動(dòng)核心基礎(chǔ)設(shè)施創(chuàng)新。
DeepSeek 提出的文件系統(tǒng)是如何運(yùn)作的,又能如何提高模型效率?最近,來(lái)自伊利諾伊大學(xué)厄巴納-香檳分校的在讀博士生 Henry Zhu 對(duì) 3FS 進(jìn)行了解讀。
以下是博客原文:
什么是 3FS?
3FS(Fire-Flyer File System)是 DeepSeek 在開(kāi)源發(fā)布周期間發(fā)布的分布式文件系統(tǒng),旨在充分利用現(xiàn)代固態(tài)硬盤(SSD)和遠(yuǎn)程直接內(nèi)存訪問(wèn)(RDMA)網(wǎng)絡(luò)的全部帶寬,能夠加速和推動(dòng) DeepSeek 平臺(tái)上所有數(shù)據(jù)訪問(wèn)操作。
本文將深入探討什么是分布式文件系統(tǒng)以及 3FS 的運(yùn)作方式,首先介紹一些背景知識(shí)。
什么是分布式文件系統(tǒng)?
分布式文件系統(tǒng)會(huì)欺騙應(yīng)用程序,使其以為它們正在對(duì)一個(gè)常規(guī)的本地文件系統(tǒng)進(jìn)行通信。這種抽象非常強(qiáng)大:一個(gè)實(shí)際上分散在 10 臺(tái)不同機(jī)器上的文件,看起來(lái)就像一個(gè)簡(jiǎn)單的文件路徑,例如 /3fs/stage/notes.txt。
使用分布式文件系統(tǒng)與使用本地文件系統(tǒng)并無(wú)二致。
在上圖中,我們通過(guò)運(yùn)行 mkdir 和 cat 命令在本地和分布式文件系統(tǒng)上創(chuàng)建了相同的文件夾和文件,命令完全相同。使用分布式文件系統(tǒng),所有這些細(xì)節(jié)都被抽象出來(lái),用戶只需操作文件即可,無(wú)需擔(dān)心后臺(tái)涉及多少臺(tái)機(jī)器、有多少網(wǎng)絡(luò)調(diào)用或多少硬盤。
分布式文件系統(tǒng)的優(yōu)勢(shì)
與本地存儲(chǔ)相比,分布式文件系統(tǒng)主要有兩大優(yōu)勢(shì):它們可以處理海量數(shù)據(jù)(高達(dá) PB 級(jí)),并提供超越單機(jī)能力的高吞吐量。它具備容錯(cuò)能力(即使一臺(tái)機(jī)器宕機(jī),系統(tǒng)仍能繼續(xù)運(yùn)行)和冗余能力(即使一個(gè)節(jié)點(diǎn)上的數(shù)據(jù)損壞,其他節(jié)點(diǎn)仍可獲得原始副本)。
分布式文件系統(tǒng)廣泛應(yīng)用于許多實(shí)際應(yīng)用:
- 并行處理框架(支持 Spark 的 HDFS);
- 帶有數(shù)據(jù)加載器和 check point 的機(jī)器學(xué)習(xí)訓(xùn)練流水線;
- 由 Google Colossus 支持的內(nèi)部大型代碼/數(shù)據(jù)存儲(chǔ)庫(kù);
- 旅行等行業(yè)應(yīng)用;
- 照片存儲(chǔ)服務(wù)等業(yè)務(wù)。
深入了解 3FS
那么,DeepSeek 開(kāi)源的 3FS 是如何工作的呢?
它的核心由四種主要節(jié)點(diǎn)類型組成:
3FS 中涉及的組件。
這些組件的作用各不相同:
1. Meta – 管理元數(shù)據(jù):文件位置、屬性、路徑等;
2. Mgmtd – 管理服務(wù)器控制集群配置:其他節(jié)點(diǎn)在哪里、哪些節(jié)點(diǎn)處于活動(dòng)狀態(tài)以及復(fù)制系數(shù);
- 可以將其視為一個(gè)路由器,它知道每個(gè)節(jié)點(diǎn)的地址,并可以幫助節(jié)點(diǎn)相互查找。(類似的類比是 NAT hole 中使用的集中式服務(wù)器)
3. Storage – 保存物理磁盤上實(shí)際文件數(shù)據(jù)的節(jié)點(diǎn);
4. Client – 與所有其他節(jié)點(diǎn)通信以查看和修改文件系統(tǒng):
- 請(qǐng)求 Mgmtd 發(fā)現(xiàn)其他節(jié)點(diǎn)
- 請(qǐng)求 Meta 服務(wù)器執(zhí)行文件操作(打開(kāi)、統(tǒng)計(jì)、關(guān)閉、符號(hào)鏈接)
- 與存儲(chǔ)節(jié)點(diǎn)傳輸數(shù)據(jù)
現(xiàn)在讓我們更詳細(xì)地了解每個(gè)組件。
Mgmtd
Mgmtd 注冊(cè)
Mgmtd 跟蹤集群中正在運(yùn)行的節(jié)點(diǎn)。存儲(chǔ)節(jié)點(diǎn)和元節(jié)點(diǎn)在啟動(dòng)時(shí)會(huì)注冊(cè),并定期發(fā)送心跳信號(hào)以確認(rèn)它們?nèi)匀惶幱诨顒?dòng)狀態(tài)。這提供了系統(tǒng)的集中視圖,可以立即識(shí)別哪些節(jié)點(diǎn)處于宕機(jī)狀態(tài)。
管理請(qǐng)求
節(jié)點(diǎn)無(wú)需與網(wǎng)絡(luò)中其他所有節(jié)點(diǎn)保持連接。相反,它們可以通過(guò)查詢管理節(jié)點(diǎn)來(lái)發(fā)現(xiàn)節(jié)點(diǎn)。雖然這會(huì)增加定位節(jié)點(diǎn)的額外往返次數(shù),但由于節(jié)點(diǎn)發(fā)現(xiàn)并不靜態(tài)的,因此可以降低復(fù)雜性。
Mgmtd 鏈。
此外,Mgmtd 維護(hù)分布式算法中不同節(jié)點(diǎn)的配置。具體來(lái)說(shuō),復(fù)制鏈(CRAQ 是一種非常簡(jiǎn)潔的算法,通過(guò)將節(jié)點(diǎn)視為鏈來(lái)實(shí)現(xiàn)強(qiáng)一致性和容錯(cuò)性。)被建立,其節(jié)點(diǎn)作為配置存儲(chǔ)在 mgmtd 中。
Meta
Meta 概覽。
元節(jié)點(diǎn)比 mgmtd 稍微復(fù)雜一些。客戶端通過(guò) RPC 調(diào)用與其通信。元服務(wù)器在元存儲(chǔ)上執(zhí)行典型的文件系統(tǒng)操作(打開(kāi)、創(chuàng)建、統(tǒng)計(jì)、取消鏈接)。文件元數(shù)據(jù)駐留在 inode 中,存儲(chǔ)大小、權(quán)限、所有者和時(shí)間戳等屬性。DirEntry 對(duì)象將路徑映射到 inode,單個(gè)文件可以有多個(gè) DirEntry(類似于符號(hào)鏈接)。inode 和 DirEntry 都存儲(chǔ)在 FoundationDB 中。
有人可能想知道 founationdb 的鍵是什么樣的?inode:「INOD」+ inode id,dir entry:「DENT」+ nodeid + path,使用 transaction 進(jìn)行冪等操作。會(huì)話管理器跟蹤打開(kāi)的文件,并將文件會(huì)話存儲(chǔ)在 FoundationDB 中。如果客戶端斷開(kāi)連接但未關(guān)閉文件,會(huì)話管理器將啟動(dòng)文件同步。文件刪除請(qǐng)求排隊(duì)到垃圾收集器,垃圾收集器會(huì)在刪除目錄條目和 inode 之前從存儲(chǔ)節(jié)點(diǎn)中刪除數(shù)據(jù)。
Storage
存儲(chǔ)概覽。
存儲(chǔ)節(jié)點(diǎn)的主要功能是通過(guò)將數(shù)據(jù)分解成塊來(lái)管理物理存儲(chǔ)上的數(shù)據(jù):
Rust 有一個(gè)名為 ChunkStore 的舊版塊管理器,是用 C++ 編寫的。我不太明白為什么是用 Rust,可能是因?yàn)樗闷饋?lái)很有趣,而且提供了更安全的保障,可以跟蹤磁盤存儲(chǔ)塊。
- Chunk 代表一塊物理磁盤,并跟蹤其元數(shù)據(jù)(ID、大小、磁盤偏移量、物理磁盤、校驗(yàn)和、版本等)。這是所有其他結(jié)構(gòu)用來(lái)跟蹤數(shù)據(jù)塊的最原始數(shù)據(jù)結(jié)構(gòu)。
- Chunk 引擎不允許用戶直接與 Chunk 交互,因?yàn)檫@會(huì)增加引擎使用的復(fù)雜性。引擎接口提供了一些操作,為用戶提供了一種嚴(yán)格清晰的與引擎交互的方式(查找、分配、提交、元數(shù)據(jù)等)。
- 默認(rèn)情況下,所有這些數(shù)據(jù)都存儲(chǔ)在 LevelDB 中,前綴字節(jié)表示操作類型(查詢?cè)獢?shù)據(jù)),并以 Chunk ID 作為鍵。
不同的 Worker 使用塊引擎來(lái)維護(hù)物理存儲(chǔ)
- AllocateWorker 在塊引擎中分配新的塊
- PunchHoleWorker 回收不再使用的塊
- AioReadWorker 處理對(duì)塊的讀取請(qǐng)求,并將讀取請(qǐng)求放入 io_uring 隊(duì)列,提交并等待完成
起初,我感到很驚訝。塊引擎并不對(duì)實(shí)際的物理磁盤執(zhí)行操作,它實(shí)際上只管理元數(shù)據(jù)。這樣做的原因之一可能是為了讓 ChunkEngine 實(shí)現(xiàn)保持精簡(jiǎn),讓它只負(fù)責(zé)管理元數(shù)據(jù)。
存儲(chǔ)節(jié)點(diǎn)需要知道如何將寫入操作轉(zhuǎn)發(fā)到 CRAQ 鏈中的下一個(gè)目標(biāo)。
目前,只需知道寫入操作需要轉(zhuǎn)發(fā)到其他節(jié)點(diǎn)即可。
- 目標(biāo)由多個(gè)塊組成(可以將其視為包含不同塊的邏輯存儲(chǔ))。
- 一個(gè)鏈由多個(gè)目標(biāo)組成(通常跨越多個(gè)節(jié)點(diǎn))。
- 存儲(chǔ)節(jié)點(diǎn)向 mgmtd 服務(wù)器查詢其他節(jié)點(diǎn)的鏈,以及該鏈中寫入操作需要轉(zhuǎn)發(fā)到的相應(yīng)目標(biāo)(節(jié)點(diǎn))。
CRAQ
CRAQ(Chain Replication with Apportioned Queries)是一種實(shí)現(xiàn)強(qiáng)一致性和線性一致性的協(xié)議。它是確保數(shù)據(jù)塊容錯(cuò)的核心機(jī)制。這里將解釋 CRAQ 的工作原理,并展示其在 3FS 中的實(shí)現(xiàn)。
Craq 寫入傳播。
寫入操作從頭部開(kāi)始。在我們的示例中,我們將 name=henry 寫入系統(tǒng)。隨著寫入操作沿鏈向下移動(dòng),每個(gè)條目都會(huì)被標(biāo)記為「臟」,并附帶一個(gè)版本號(hào)。臟條目不可安全讀取。一旦寫入操作到達(dá)尾部,它就會(huì)被提交并標(biāo)記為「干凈」。
Craq 寫入提交。
隨著提交消息從尾部向頭反向傳播,寫入操作將變得干凈。每個(gè)節(jié)點(diǎn)提交該條目并將其標(biāo)記為干凈。
Craq clean read
對(duì)于讀取來(lái)說(shuō),過(guò)程很簡(jiǎn)單:如果對(duì)象是干凈的,則立即將其返回給客戶端。
Craq dirty read
挑戰(zhàn)發(fā)生在臟對(duì)象上。每個(gè)鏈都會(huì)跟蹤臟版本和干凈版本。由于尾部始終包含最新提交的數(shù)據(jù),因此副本會(huì)查詢尾部以獲取最新提交的對(duì)象,從而確保強(qiáng)一致性。
CRAQ 性能
CRAQ 的讀寫性能因工作負(fù)載而異。寫入吞吐量和延遲受鏈中最慢節(jié)點(diǎn)的限制,因?yàn)閷懭氡仨毎错樞蛱幚砻總€(gè)節(jié)點(diǎn)。例如,在 Zipfian 工作負(fù)載(其中頻繁訪問(wèn)的數(shù)據(jù)占主導(dǎo)地位)中,讀取性能會(huì)受到影響,因?yàn)閷?duì)象可能很臟,從而迫使查詢到尾部節(jié)點(diǎn)。這會(huì)造成瓶頸,因?yàn)槲膊勘仨毺幚泶蠖鄶?shù)讀取請(qǐng)求。
如何在 3FS 中使用 CRAQ
存儲(chǔ)采用條帶化,CRAQ 在其上運(yùn)行。
在本例中,集群由 5 個(gè)節(jié)點(diǎn)組成,每個(gè)節(jié)點(diǎn)配備 5 個(gè) SSD。存儲(chǔ)目標(biāo)復(fù)制到 3 個(gè)節(jié)點(diǎn),旨在避免數(shù)據(jù)重疊,從而避免節(jié)點(diǎn)故障大幅影響整體吞吐量。
考慮一個(gè)極端場(chǎng)景,所有鏈都部署在節(jié)點(diǎn) 1、2、3 上。如果節(jié)點(diǎn) 1 發(fā)生故障,分布式系統(tǒng)將損失總吞吐量的 1/3,而不是上圖所示的 1/5。3FS 設(shè)計(jì)說(shuō)明中提供了一個(gè)示例,并進(jìn)行了更深入的解釋。CRAQ 在頂層運(yùn)行,管理頭、中、尾節(jié)點(diǎn)。
3FS 默認(rèn)采用強(qiáng)一致性讀取。寫入操作從頭到尾,再?gòu)念^到尾,吞吐量受最慢節(jié)點(diǎn)的限制,延遲由所有鏈節(jié)點(diǎn)的總延遲決定。
不同復(fù)制協(xié)議比較表。
如上表所示,在常見(jiàn)情況下,與其他協(xié)議和系統(tǒng)相比,CRAQ 以高寫入延遲為代價(jià),實(shí)現(xiàn)了可擴(kuò)展的低延遲讀取。
其他分布式文件系統(tǒng)
這時(shí)候有人可能會(huì)問(wèn)了:這種架構(gòu)與其他分布式文件系統(tǒng)有什么不同?從高層次來(lái)看,這些組件很常見(jiàn),幾乎每個(gè)分布式系統(tǒng)中都會(huì)出現(xiàn)客戶端、元數(shù)據(jù)、存儲(chǔ)和管理節(jié)點(diǎn)的概念。
區(qū)別在于其實(shí)際適用性和實(shí)際實(shí)現(xiàn):
- 它擅長(zhǎng)處理哪些工作負(fù)載
- 它的調(diào)優(yōu)靈活性
- 部署簡(jiǎn)便性
- 吞吐量擴(kuò)展能力
- 在服務(wù)等級(jí)目標(biāo) (SLO) 內(nèi)保持延遲
- 可靠性
以及決定其可用性的更精細(xì)的技術(shù)細(xì)節(jié):
- 存在哪些瓶頸
- 如何管理瓶頸
- 它的鎖定方法(或不使用鎖定方法)
- 采用的具體數(shù)據(jù)結(jié)構(gòu)
- 軟件設(shè)計(jì)所針對(duì)的硬件
- 使用哪種容錯(cuò)算法或糾刪碼
考慮到這一點(diǎn),我想深入分析一下這個(gè)相對(duì)較新的開(kāi)源分布式文件系統(tǒng)的性能。分布式文件系統(tǒng)的開(kāi)發(fā)具有挑戰(zhàn)性,目前的基準(zhǔn)測(cè)試相當(dāng)有限,我們也還沒(méi)有將 3FS 與單節(jié)點(diǎn)系統(tǒng)和其他分布式文件系統(tǒng)的比較,因此很難評(píng)估它的性能。
還有一些問(wèn)題是值得探討的:
- DeepSeek 的一些說(shuō)法是否成立,尤其是關(guān)于 FUSE 瓶頸的說(shuō)法?
- 我們能以某種方式復(fù)現(xiàn)他們的性能圖嗎?
- 在什么情況下性能會(huì)下降?
- 系統(tǒng)的瓶頸是什么(CPU/內(nèi)存/磁盤/網(wǎng)絡(luò))?
- 這個(gè)文件系統(tǒng)在哪些類型的工作負(fù)載下表現(xiàn)優(yōu)異?
- 與其他分布式文件系統(tǒng)相比如何?
- 它如何解決現(xiàn)有系統(tǒng)面臨的問(wèn)題?
- 我能對(duì)系統(tǒng)進(jìn)行一些改進(jìn)嗎?
在本系列文章的其余部分中,作者將經(jīng)歷做出初步假設(shè)、測(cè)試它們以及從差異中學(xué)習(xí)的過(guò)程,以更深入地了解 3FS 的實(shí)際表現(xiàn)。