Hugging Face Xet 存储集成

Hugging Face 已将 Xet 存储集成到 Hub 中,并将第一批模型和数据集仓库从 Git LFS 迁移出来。这次转型引入了内容定义分块 (CDC),以实现字节级去重,从而大幅减少更新大文件所需的时间和带宽。

Xet 存储架构

Xet 存储使用内容定义分块 (CDC) 取代了文件级去重。虽然 Git LFS 将对大文件的任何更改视为需要重新上传整个文件的要求,但 Xet 会将数据拆分为约 64KB 的分块。只有发生变化的分块才会在网络上传输。

例如,在 5GB 的 SQLite 数据库中追加 1MB 的数据,在 LFS 下需要重新上传完整的 5GB,但在 Xet 中,只需推送新数据。在内部测试中,在 50Mb/s 的带宽下,这将上传时间从 13 分钟缩短到了十分之一秒。

系统组件

  • Xet-aware Client:负责将数据拆分为约 64KB 的分块,在本地对相同分块进行去重,并在上传前将其聚合为约 64MB 的块。
  • Hugging Face Hub:负责管理路由、身份验证和安全保障。
  • Content Addressed Store (CAS):在传输过程中执行基于分块的去重。它包含一个 LFS Bridge,通过充当传统的 LFS 服务器来确保非 Xet 客户端的向后兼容性。
  • Amazon S3:作为最终的持久层,存储块 (file contents) 和分片 (reconstruction metadata)。

生产环境迁移与验证

2025 年 2 月 20 日,Hugging Face 将目标仓库中 4.5 TB 的数据迁移到了 Xet 存储。这次迁移将 Hub 总下载流量的约 6% 转移到了 Xet 基础设施,为系统的可靠性和性能提供了现实世界的验证场所。

技术挑战与优化

迁移后的分析揭示了两个主要的性能瓶颈,这些瓶颈已通过架构更新得到解决:

下载开销与块格式

初始指标显示,内容寻址存储 (CAS) 从 S3 下载的数据量是返回给客户端数据量的四倍。这是由于 hf_transfer 请求的 10MB 范围与 Xet 的块边界不匹配造成的。由于块格式缺乏未压缩的分块长度信息,CAS 必须从头开始流式传输整个块才能找到请求的数据。

解决方案:Hugging Face 更新了块格式以存储分块长度元数据。这使得 CAS 仅需下载每个请求所需的特定数据,从而使 GET 延迟降低了约 35%,并实现了平衡的下载与发送数据比例。

Pod 负载不平衡

团队观察到意外的负载峰值,即 CAS 集群中的单个 pod 处理数百个活动上传,而其他 pod 则处于闲置状态。这归因于操作系统页面缓存 (page cache) 在验证期间缓冲写入临时文件时未调用 fsync。高上传量导致了内存压力和来自 AWS EBS 块存储的吞吐量限制,从而形成了延迟和积压的循环。

解决方案:团队对每台机器接受的并发上传数量实施了限制。一旦 pod 达到限制,请求将被推送到集群中的其他 pod,如果所有 pod 都已饱和,则会触发自动扩缩容策略。

用户实施方案

用户可以通过加入等待名单来使用 Xet 支持的存储。一旦被接受,新仓库将自动使用 Xet,现有仓库将被迁移。

  • 工具链:一个 hf_xet Python 包正在集成到 huggingface_hub 中。transformersdatasets 的用户可以在其环境中安装 hf_xet 以利用其优势。
  • 兼容性:通过 LFS Bridge,旧版客户端仍保持兼容,但若要获得完整的性能提升,则需要升级到 hf_xet

Sources