Xet 已登陸 Hub
在過去幾周裡,Hugging Face 的 Xet 團隊邁出了重要一步,將首批模型和資料集倉庫從 LFS 遷移到了 Xet 儲存。
這是實現 Hugging Face 對 Hub 的願景的眾多步驟之一,旨在賦能 AI 構建者更有效地構建、迭代和協作處理海量模型和資料集。如果您對技術本身的深入探討感興趣,請檢視以下文章:
但這篇博文並非關於核心技術,而是揭秘 Xet 登陸 Hub 幕後的故事,帶您瞭解從概念驗證到首批倉庫遷移的全過程。
這次遷移將 Hub 約 6% 的下載流量轉移到了 Xet 基礎設施上,驗證了幾個關鍵元件,並測試了與各種倉庫訪問方式(例如,透過本地開發環境、不同的庫、CI 系統、雲平臺等)的整合。對於擁有近兩百萬開發者和超過兩百萬個公開倉庫的平臺來說,真實世界的使用是最終的試驗場。設計像 Xet 儲存這樣複雜的系統需要權衡多方因素。你需要為規模、效能和可靠性做規劃,但一旦位元組開始流動,挑戰便會浮現。關鍵在於知道何時從設計和理論轉向實踐。
Xet 的不同之處
LFS 是目前倉庫背後的儲存系統,它將大檔案儲存在倉庫之外的一個獨立的物件儲存中。LFS 在檔案級別進行去重。即使是微小的編輯也會建立一個需要完整上傳的新版本,這對於許多 Hub 倉庫中數 GB 大小的檔案來說是十分痛苦的。
相比之下,Xet 儲存使用基於內容的資料分塊 (CDC) 技術,在位元組級別(約 64KB 的資料塊)進行去重。如果您在 Parquet 檔案中編輯一行,或在 GGUF 模型中調整一小段元資料,只有那些發生變化的資料塊會被傳輸。
這為大檔案傳輸帶來了顯著的好處。例如,Xet 團隊維護一個約 5GB 的內部 SQLite 資料庫,用於驅動一個指標儀表板。使用 LFS,追加 1MB 的資料(大約是目前的平均更新量)需要重新上傳整個 5GB 的檔案。而使用 Xet 儲存,我們只需推送新的資料。

這意味著儀表板的上傳只需十分之一秒(在 50Mb/s 的速率下),而不是如果資料庫由 LFS 支援所需的 13 分鐘。
要實現這一點,需要以下元件之間的協調:
- 一個支援 Xet 的客戶端
- 將資料分割成約 64 KB 的資料塊。
- 在本地對相同的資料塊進行去重,並將它們聚合成約 64 MB 的資料塊後再上傳。
- Hugging Face Hub
- 接收客戶端請求並將其路由到正確的倉庫。
- 提供認證和安全保障。
- 內容定址儲存 (CAS)
- 對上傳和下載強制執行基於資料塊的去重。
- 為舊的、不支援 Xet 的客戶端提供一個 LFS 橋,其行為類似於傳統的 LFS 伺服器,併為下載提供單一 URL。
- Amazon S3
在進入生產環境之前,該系統被部署到一個臨時環境中,我們在其中構建了一個核心功能鏈路,以支援透過 huggingface_hub
進行上傳和下載。下面的影片展示了我們一個月後的進展:
在快速完成概念驗證的興奮之後,團隊開始著手解決與 Hub 這個複雜生態系統之間棘手的整合問題(隱私、向後相容性、碎片化等)。最終,該基礎設施進入了供 Hugging Face 團隊成員使用的生產環境。隨著真實使用資料的不斷湧入,我們推進了首次大規模遷移。
遷移日
2 月 20 日上午 10 點,全體人員嚴陣以待。在此前的幾周裡,團隊已經構建了內部工具,用於將檔案從 LFS 遷移到 Xet,同樣重要的是,在必要時可以將倉庫回滾到 LFS。現在是檢驗成果的時候了。Grafana 和 Kibana 上亮起了新的日誌和指標,即時顯示著負載的轉移情況。

Kibana 中的情況也一樣,只是在這裡你能看出我們什麼時候去吃了午飯。

到當天結束時,我們成功地將所有目標倉庫遷移完成,總共 4.5 TB 的資料進入了 Xet 儲存。每個倉庫的下載現在都由我們的基礎設施提供服務。
遷移後的挑戰
沒有哪次釋出是沒有教訓的。系統平穩地處理了負載,遷移也沒有出現任何重大中斷,但隨著資料流經各個元件,我們開始看到一些趨勢。
資料塊格式帶來的下載開銷
在審查遷移後的網路吞吐量時,我們發現 CAS 下載的資料量是其返回給客戶端的四倍。

經過進一步調查,我們發現絕大多數對 CAS 的請求都是針對檔案內 10MB 的資料範圍。這些請求來自使用 hf_transfer
加速大檔案下載的使用者。請求的範圍與資料塊邊界不對齊,而且資料塊格式沒有提供未壓縮的資料塊長度,以便直接跳到資料塊內的資料。相反,CAS 從頭開始流式傳輸資料塊,並一直讀取直到找到請求的資料。
對於一個平均大小為 60MB 的資料塊,以及多個對其內部範圍的部分請求,開銷會累積起來。CAS 讀取了 210MB,卻只交付了 60MB,下載與傳送給客戶端的位元組比為 3.5:1。在不規則大小的資料塊和可能跨越多個數據塊的範圍上進行擴充套件時,最終達到了 4:1 的下載與傳送位元組比。
常言道,一圖勝千言:

為了解決這個問題,我們更新了資料塊格式,以儲存資料塊長度的元資料,使 CAS 能夠只下載每個請求實際需要的內容。這種格式更改需要跨多個元件進行協調更新:
- CAS API
- 資料塊元資料格式
- S3 上的
2^16 + 1
個數據塊(我發誓這純屬巧合)
所有這些都是在沒有停機的情況下完成的。這不僅使 CAS 下載與返回資料的比例達到了平衡,還將所有 GET 請求的延遲降低了約 35%。

Pod 負載不均衡
與此同時,我們還發現 CAS 叢集中出現了意外的負載不均衡。一個 Pod 的活躍上傳數會飆升到數百個,而其他 Pod 則以個位數的速度緩慢執行。更換負載均衡器的路由演算法(從輪詢到最少未完成請求)和增加更多節點在當時並沒有太大效果。
深入研究後我們意識到,在上傳過程中,CAS 在上傳前會寫入一個臨時檔案進行驗證,但沒有呼叫 fsync
,這使得作業系統將寫入操作快取在頁面快取中。當上傳請求激增時,未重新整理的頁面快取會導致記憶體壓力增加。
當作業系統試圖將頁面快取重新整理到磁碟時,Pod 會因塊儲存而經歷吞吐量限制,導致上傳延遲增加。在上傳緩慢處理的同時,新的請求不斷湧入,將更多資料推向磁碟。這形成了一個惡性迴圈,導致上傳積壓和我們在遷移期間看到的負載不均衡。

為了防止 Pod 進入這種狀態,我們限制了每臺機器接受的併發上傳數量,在達到限制時會拒絕請求,從而將請求推送到叢集中的其他 Pod。如果叢集中的所有 Pod 都進入這種狀態,那麼我們的自動擴縮容策略就會啟動。長期的解決方案可能包括強制磁碟同步、移除磁碟上的緩衝,或者切換到吞吐量更好的臨時儲存。
遷移的經驗總結
這兩個問題帶來了重要的架構改進,但它們並非團隊在遷移後幾周內解決的唯一挑戰。我們還解決了其他效能問題、一個記憶體洩漏(我們修復了但仍無法確定根本原因),並根據 AWS 的建議,將 LFS 橋從應用負載均衡器 (ALB) 遷移到網路負載均衡器 (NLB),以提高流量突發時的可擴充套件性。
經驗教訓
- 沒有什麼能比得上生產環境:沒有任何測試環境能夠模擬大規模的使用者行為。即使經過了仔細的整合工作和 Hugging Face 團隊數月的測試,一些極端情況也只有在我們透過系統輸送真實流量後才浮出水面。
- 遷移能模擬真實流量:透過分階段增量遷移,並在更多流量進入基礎設施之前發現這些問題,我們避免了停機和中斷。與從第一天起就將整個 Hub 遷移到 Xet 相比,管理一小部分流量和儲存相對容易得多。
- 積累學習成果:基礎設施和系統設計在幾周內透過迭代得到了強化。未來在 Xet 上的每一個位元組和網路請求都將受益於這些經驗教訓。
簡而言之,真實世界的負載對於暴露這些挑戰至關重要,而增量遷移讓我們能夠安全地應對它們。這就是我們確保由 Xet 支援的倉庫能夠為整個 Hugging Face 社群可靠地擴充套件,實現更快的上傳、更少的瓶頸和最小的中斷。
準備就緒,Xet,出發!
隨著初步遷移的完成,Xet 現已正式登陸 Hugging Face Hub。
我們正在完成與 huggingface_hub
的正式整合,這意味著您無需對當前工作流程進行重大更改即可享受 Xet 帶來的好處。開始使用:
- 加入等候名單
- 在這裡註冊,使用您的使用者或組織賬戶(如果您有管理員/寫入許可權)。
- 一旦透過,您的新倉庫將自動使用由 Xet 支援的儲存。
- 我們也會遷移您現有的倉庫,讓您不會錯過更快的傳輸體驗。
- 使用您常用的工具
- 一個名為
hf_xet
的 Python 包即將加入huggingface_hub
。如果您使用transformers
或datasets
庫,它已經在使用huggingface_hub
,所以您只需在同一環境中安裝hf_xet
即可。安裝步驟和文件即將釋出。 - 繼續使用您已有的命令來下載和上傳大檔案。
- 一個名為
- 享受好處
- 減少等待上傳和下載的時間,更快地迭代大檔案。
- 您團隊中的每個人都應該升級到
hf_xet
以獲得全部好處,但舊版客戶端仍可透過 LFS 橋保持相容。
如果您有任何問題,請在下方的評論區給我們留言 👇 或在 Xet 團隊頁面發起討論。敬請期待我們推出更多功能(更快的網頁上傳、更快的 Git 工作流),為 Hugging Face 上的每一位 AI 構建者帶來更快的大檔案協作體驗!