跳到正文
北京时间
原文
Hugging Face:Blog·· 2025-07-15精选AI 评分72

Hugging Face Hub 从 Git LFS 迁移至 Xet 并将向所有用户开放

Migrating the Hub from Git LFS to Xet

AI 导读

Hugging Face 宣布 Hub 存储后端从 Git LFS 迁移到 Xet,半年内 50 万个仓库、20PB 数据完成迁移,用户超 100 万,5 月起对新用户默认启用。

推荐理由

作者复盘了 Hub 从 Git LFS 迁到 Xet 的架构与经验,读者可借此了解大规模无感迁移的做法和后续变化。

正文 · AI 翻译

今年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的未来。然而,这次迁移的幕后英雄是:

  1. 一个内部称为Git LFS Bridge的核心基础设施组件
  2. 全天候运行的后台内容迁移

这些组件共同作用,使我们能够在几天内积极迁移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中保存的内容重建文件并将其返回给请求者。

Git LFS Bridge flow
Git LFS Bridge的极大简化视图——实际上,这条路径包含更多的API调用和组件,如为Bridge提供前端的CDN、用于文件元数据的DynamoDB以及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 内容寻址存储
Migration flow
由 webhook 事件触发的迁移流程;为简洁起见,从编排器开始展示。

扩展迁移

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 的日常负载。
Cas throughput
CAS 吞吐量;每个峰值对应一次重大迁移,基线吞吐量稳步上升,截至 2025 年 7 月已接近 100 Gb/s

零阻力,更快传输

当我们开始替换 LFS 时,我们有两个目标:

  1. 不做有害之事
  2. 尽可能快地产生最大影响

按照最初的约束条件和这些目标进行设计,让我们能够:

  • 在将 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 上,我们的目标是将它带给所有人。

如果你有任何问题,请在评论中给我们留言 👇,在 Xet 团队页面发起讨论。

来源:Hugging Face:Blog · huggingface.co