Hugging Face Hub 从 Git LFS 迁移至 Xet 并将向所有用户开放
Migrating the Hub from Git LFS to Xet
Hugging Face 宣布 Hub 存储后端从 Git LFS 迁移到 Xet,半年内 50 万个仓库、20PB 数据完成迁移,用户超 100 万,5 月起对新用户默认启用。
作者复盘了 Hub 从 Git LFS 迁到 Xet 的架构与经验,读者可借此了解大规模无感迁移的做法和后续变化。
今年1月,Hugging Face的Xet团队部署了一个新的存储后端,不久之后便将约6%的Hub下载量迁移到了该基础设施上。这是一个重要的里程碑,但这仅仅是个开始。6个月内,50万个存储库、共计20 PB的数据加入了向Xet的迁移,因为Hub已超出Git LFS的承载能力,转向一个能够随AI构建者工作负载扩展的存储系统。
如今,Hub上已有超过100万人正在使用Xet。5月,它成为了新用户和组织在Hub上的默认选项。仅有几十条GitHub issue、论坛帖子和Discord消息,这或许是如此规模下最安静的迁移。
怎么做到的?一方面,团队带着多年构建和支持内容寻址存储(CAS)及Rust客户端的经验有备而来,这些构成了系统的基础。没有这些,Git LFS可能仍是Hub的未来。然而,这次迁移的幕后英雄是:
- 一个内部称为Git LFS Bridge的核心基础设施组件
- 全天候运行的后台内容迁移
这些组件共同作用,使我们能够在几天内积极迁移PB级数据,而无需担心对Hub或社区的影响。它们让我们安心,能够在未来几周和几个月内走得更快(跳到末尾 👇 看看即将到来的内容)。
桥梁与向后兼容性
在规划向Xet迁移的早期,我们做出了几个关键的设计决策:
- 不会从Git LFS进行“硬切换”到Xet
- 启用Xet的存储库应能同时包含Xet和LFS文件
- 从LFS到Xet的存储库迁移不需要“锁”;也就是说,它们可以在后台运行,而不会中断下载或上传
出于我们对社区的承诺,这些看似简单的决策产生了重大影响。最重要的是,我们认为用户和团队不应该为了与启用Xet的存储库交互而立即改变工作流程或下载新客户端。
如果你有支持Xet的客户端(例如hf-xet,即Xet与huggingface_hub的集成),上传和下载会经过整个Xet栈。客户端在上传时要么使用内容定义分块将文件拆分为块,要么在下载时请求文件重建信息。上传时,块被传递到CAS并存储在S3中。下载时,CAS提供客户端需要从S3请求的块范围,以便在本地重建文件。
对于不支持基于块的文件传输的旧版huggingface_hub或huggingface.js,你仍然可以下载和上传到Xet存储库,但这些字节会走不同的路径。当通过resolve端点从Hub请求由Xet支持的文件时,Git LFS Bridge会构造并返回一个单一的预签名URL,模拟LFS协议。然后,Bridge会从S3中保存的内容重建文件并将其返回给请求者。
要查看实际效果,请右键点击上方图片并在新标签页中打开。该 URL 会从
https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/migrating-the-hub-to-xet/bridge.png 重定向到以 https://cas-bridge.xethub.hf.co/xet-bridge-us/... 开头的地址。你也可以对同一 URL 使用 curl -vL,在终端中查看重定向过程。
与此同时,当非 Xet 感知的客户端上传文件时,文件会先发送到 LFS 存储,然后再迁移到 Xet。这个“后台迁移过程”在我们的文档中只有简短提及,它同时支撑着向 Xet 的迁移和上传的向后兼容性。它支撑了远超十几个 PB 的模型和数据集的迁移,并让 500,000 个仓库与 Xet 存储保持同步,全程无一失误。
每当有文件需要从 LFS 迁移到 Xet 时,就会触发一个 webhook,将事件推送到分布式队列,由编排器进行处理。编排器会:
- 如果事件需要,则在仓库上启用 Xet
- 获取仓库中每个 LFS 文件的 LFS 修订列表
- 根据大小或文件数量将文件分批为作业;1000 个文件或 500MB,以先到者为准
- 将作业放入另一个队列,供迁移工作 pod 处理
这些迁移工作进程随后会领取作业,每个 pod 会:
- 下载批次中列出的 LFS 文件
- 使用 xet-core 将 LFS 文件上传到 Xet 内容寻址存储
扩展迁移
4 月,我们联系了 bartowski,询问他们是否想测试 Xet,以此测试该系统的极限。bartowski 的迁移涉及 2,000 个仓库、近 500 TB 数据,并暴露出了一些薄弱环节:
- 用于全局去重的临时 分片文件最初写入
/tmp,然后移动到分片缓存中。然而,在我们的工作 pod 上,/tmp和 Xet 缓存位于不同的挂载点。移动失败,分片文件从未被删除。最终磁盘被填满,引发了一波No space left on device错误。 - 在支持 Llama 4 发布之后,我们为突发下载扩展了 CAS,但迁移工作进程却让情况反转,数百个数 GB 的上传将 CAS 推到了资源极限之外
- 从理论上讲,迁移工作进程的吞吐量本应远高于实际报告值;对 pod 进行性能分析后发现存在网络和 EBS I/O 瓶颈
修复这个三头怪物意味着要触及每一层——修补 xet-core、调整 CAS 规模,并增强工作节点规格。幸运的是,bartowski 愿意与我们合作,让每个仓库都迁移到 Xet。这些经验也推动了 Hub 上最大存储用户的迁移,例如 RichardErkhov(1.7PB 和 25,000 个仓库)和 mradermacher(6.1PB 和 42,000 个仓库 🤯)。
与此同时,在首次和最近一次大规模迁移之间,CAS 吞吐量增长了一个数量级:
- Bartowski 迁移:CAS 持续约 35 Gb/s,其中约 5 Gb/s 来自常规 Hub 流量。
- mradermacher 和 RichardErkhov 迁移:CAS 峰值约为 300 Gb/s,同时仍承载约 40 Gb/s 的日常负载。
零阻力,更快传输
当我们开始替换 LFS 时,我们有两个目标:
- 不做有害之事
- 尽可能快地产生最大影响
按照最初的约束条件和这些目标进行设计,让我们能够:
- 在将
hf-xet作为必需依赖项纳入huggingface_hub之前,先引入并加固它 - 支持社区通过他们目前使用的任何方式向启用了 Xet 的仓库上传和下载,其余部分由我们的基础设施处理
- 从将 Hub 逐步迁移到 Xet 的过程中学到了宝贵的经验——从规模到我们的客户端如何在分布式文件系统上运行
与其等待所有上传路径都支持 Xet、强制硬切换,或推动社区采用特定工作流,我们可以立即开始将 Hub 迁移到 Xet,同时将用户影响降到最低。简而言之,让团队保留自己的工作流,并随着基础设施支持统一存储系统的长期目标,有机地过渡到 Xet。
Xet 面向所有人
在 1 月和 2 月,我们邀请了高级用户提供反馈并对基础设施进行压力测试。为了获得社区反馈,我们推出了一个等待列表,用于预览启用了 Xet 的仓库。不久之后,Xet 成为 Hub 上新用户的默认选项。
我们现在支持 Hub 上一些最大的创作者(Meta Llama、Google、OpenAI 和 Qwen),同时社区的工作不受干扰。
接下来是什么?
从本月开始,我们将把 Xet 带给所有人。请留意一封提供 Xet 访问权限的电子邮件,一旦获得访问权限,请更新到最新的 huggingface_hub(pip install -U huggingface_hub),即可立即解锁更快的传输速度。这也意味着:
- 你所有现有的仓库都将从 LFS 迁移到 Xet
- 所有新建的仓库都将默认启用 Xet
如果你使用浏览器或 Git 从 Hub 上传或下载,那没问题。对两者的基于分块的支持即将推出。在此期间,请使用你已有的任何工作流;没有任何限制。
下一步:开源 Xet 协议和整个基础设施栈。可扩展到 AI 工作负载的字节存储和传输的未来就在 Hub 上,我们的目标是将它带给所有人。
来源:Hugging Face:Blog · huggingface.co