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_xetPython 包正在集成到huggingface_hub中。transformers或datasets的用户可以在其环境中安装hf_xet以利用其优势。 - 兼容性:通过 LFS Bridge,旧版客户端仍保持兼容,但若要获得完整的性能提升,则需要升级到
hf_xet。
Sources
- OriginalXet is on the Hub