Hugging Face Storage 成为 SkyPilot 一级后端:零出站费跨云存储
阅读原文· huggingface.coHugging Face 和 SkyPilot 把存储和算力真正解耦了,跨云读取模型零出口费,用过 SkyPilot 的团队可以立刻省下那块 egress 账单。
Hugging Face Storage 现为 SkyPilot 的一级后端。用户通过 hf:// URL 和现有 HFTOKEN 即可将 Hugging Face Bucket(读写)或模型/数据集/Space 仓库(只读)挂载到 SkyPilot 任务中,支持 MOUNT(FUSE 懒加载)或 COPY 模式。SkyPilot 可将任务调度到 20+ 云、Kubernetes、Slurm 及本地集群的任意可用 GPU 上。Hugging Face 不收取出站及 CDN 费用,故跨云读取数据无额外成本。存储价格 $12–18/TB/月,低于 AWS S3 加出站费。Bucket 基于 Xet,增量检查点和模型变体仅存储和传输改动部分。
在任何云上运行 AI 工作负载,数据存储在 Hugging Face:SkyPilot 实现零出站存储
发布于 2026 年 7 月 7 日
Nikhil Jha njha 关注
特邀作者
对大多数团队而言,模型和数据集都存放在某个单一云的单一区域的一个存储桶中。而你能获取的 GPU——无论是用于开发、训练还是推理服务——却越来越多地位于与数据不同的云上。一旦这两者分离,你就得支付跨云数据传输费用,仅仅是为了将你自己的数据读取到自己的 GPU 上。现在,与 Hugging Face 合作,我们将这两部分连接了起来:你的模型和数据集留在 Hub 上,而 SkyPilot 则在任何拥有 GPU 的集群上运行计算任务(开发、训练或推理服务)。只需一个 `hf://` URL 和你已有的 `HF_TOKEN`,就能将 Hugging Face Bucket 或任何 Hub 仓库挂载到 SkyPilot 任务中,然后在任何有算力的地方启动它。Hugging Face 不收取任何出站费用,因此在任何云上将数据读取到那些 GPU 上都不花一分钱。
以下是新功能:
- 在任何任务中使用你的 Hub 数据。`store: hf` 通过一个 `hf://` URL 和你现有的 `HF_TOKEN`,利用 `MOUNT` 或 `COPY` 方式,将 Hugging Face Bucket(可读写)或任何模型/数据集/Space 仓库(只读)挂载到 SkyPilot 任务中。
- 在任何云上的任何 GPU 上运行。SkyPilot 能在 20 多个云平台、Kubernetes、Slurm 以及本地环境中找到该任务所需的计算资源,因此同一个运行任务可以使用你预留或按需获取的任何可用的 GPU,不限供应商。
- 读取数据无出站费用。Hugging Face Storage 不收取任何出站或 CDN 费用,因此无论 SkyPilot 将任务部署在哪里,它都能直接从同一个存储桶中读取你的模型和数据集,无需为每个云单独拷贝数据,也不会产生拉取数据的出站账单。
- 基于 Xet 的去重。存储桶构建在 Xet 之上,因此增量检查点和模型变体仅存储和传输发生变化的块。
- 联合构建。Hugging Face 和 SkyPilot 共同发布了此功能,并且 Hugging Face 团队已向上游提交了 `hf-mount` FUSE 的修复程序,使其能在非特权容器中正常工作。
Hugging Face Storage 现已成为 SkyPilot 的一等后端
SkyPilot 任务已经可以通过在本地路径挂载的方式读写云对象存储(S3、GCS、Azure、R2 等)。Hugging Face Storage 现在也加入了这一行列,成为 `store: hf`,通过 `hf://` 协议访问。
file_mounts:
# A Hugging Face Bucket, read-write, for checkpoints, logs, processed data.
/checkpoints:
source: hf://buckets/my-org/qwen-sft
store: hf
mode: MOUNT # or COPY
# A model repo, mounted read-only.
/base-model:
source: hf://Qwen/Qwen3.5-4B
store: hf
mode: MOUNT
# A dataset repo, pinned to a revision, read-only.
/data:
source: hf://datasets/my-org/my-dataset@main
store: hf
mode: MOUNT
这个 hf:// 方案覆盖了整个生命周期:从仓库中读取模型和数据集,训练时将检查点写入存储桶,将训练完成的模型发布回仓库,以及在提供服务时将其拉取到推理服务器上。大多数团队已经将模型和数据集保存在 Hub 上,因此无需迁移步骤,也无需创建新的存储账户。
MOUNT 使用 Hugging Face 的 hf-mount FUSE 后端,因此存储桶或仓库会显示为本地路径,与 SkyPilot 的其他 FUSE 挂载(gcsfuse、blobfuse2、rclone、goofys)并列。数据获取发生在文件系统层面:当你的代码发出 read() 调用时,驱动程序仅从 Xet 后端拉取那些字节,因此只有你实际触及的数据才会通过网络传输,而 hf-mount 会保留一个磁盘缓存,以便重复读取时使用本地数据。这种磁盘缓存行为正是 SkyPilot 在 MOUNT_CACHED 模式下为其其他后端提供的效果,而在普通 MOUNT 模式下,每次读取都会从存储桶中流式传输,本地不保留任何内容。对于 hf 存储,MOUNT 和 MOUNT_CACHED 的行为相同,因此无论哪种模式都会保留缓存。
由于读取是惰性的,进程可以在整个文件下载完成之前就开始处理一个大文件,而不是先阻塞等待完整复制完成。这使 GPU 几乎立即处于忙碌状态,一边流式接收数据一边进行训练,而不是在数据集或检查点下载时闲置(并产生费用)。这在第一个 epoch 时效果最为显著,因为此时尚未缓存任何内容。COPY 则采用另一种方式,通过 huggingface_hub 提前下载,无需特殊要求。
身份验证使用的是你已有的 token。在环境中设置 HF_TOKEN,并通过 --secret HF_TOKEN 将其传递给运行任务;SkyPilot 会在任务所在任何云平台上使用该 token 进行挂载。无论任务部署在 AWS、GCP、Azure、Nebius、Lambda 还是你自己的 Kubernetes 集群上,同一个 token 都适用,因此无需为每个云平台分别管理存储桶密钥。
零出站流量:存储不再决定你在哪里运行。
GPU容量几乎不再来自单一来源。为了获得足够的H100和H200,团队会同时在多家供应商处预留和承诺容量(比如超大规模云上的一块资源、新型云上的一个集群,也可能是一台本地机架),然后根据配额在任何地方运行。SkyPilot正是为此而构建:一份作业规范,跨20多个云、Kubernetes和本地调度,落到任一空闲的预留集群上。
对象存储一直是个难题。对象存储是区域性的且每个云独立,因此,给位于不同供应商数据中心的GPU或推理服务器提供数据,要么在每个供应商的存储桶里都保留一份数据副本,要么付费将其拉取过来。大多数云服务商在数据离开其网络时收取出口流量费(AWS约$0.09/GB),而且往往在同一云的不同区域之间也要收费。将基础模型拉到每个推理节点,或者从另一个云上的集群对数据集进行多个epoch的迭代,都会在已经预留的GPU之上增加一笔巨额账单。团队最终只能将每次运行固定在存储数据的那个供应商上,而让其他容量闲置。
Hugging Face Storage消除了最让人头疼的那部分成本:读取端。没有出口或CDN费用,存储费为$12-18/TB/月(而AWS S3大约$23/TB外加出口费),同一个存储桶可以从所有这些集群访问,无论GPU在哪里运行,读取都是免费的。写回数据仍需支付计算云的标准出口费,与任何云外存储一样,但对于大多数AI工作来说,读取占主导:跨多个epoch流式传输的数据集,或拉到每个新训练/推理节点上的模型权重。因此,你不再需要将每次运行固定在拥有数据副本的供应商上。
快速基准测试
为了收集一些基准数据,我们运行了一次小的微调:使用TRL的SFTTrainer,在HuggingFaceH4/Multilingual-Thinking数据集上微调Qwen/Qwen3.5-4B,从Hub仓库以只读方式挂载模型,并将所有检查点写入Hugging Face Bucket。同一份SkyPilot YAML在AWS、GCP和Lambda上运行,只更改了--infra。SkyPilot将每个作业放置到GPU空闲的地方,所有三个云都读写同一个存储桶。
# qwen-sft.yaml. Launch anywhere: sky launch qwen-sft.yaml --infra aws|gcp|...
resources:
accelerators: H100:1 # or whatever the cloud has
file_mounts:
/base-model:
source: hf://Qwen/Qwen3.5-4B # read-only, lazy-mounted from the Hub
store: hf
mode: MOUNT
/checkpoints:
source: hf://buckets/my-org/qwen-sft # read-write Bucket
store: hf
mode: MOUNT
run: |
python train.py --model /base-model --output_dir /checkpoints
我们测量的结果是:
- 该模型在每个云平台上免费加载。惰性读取只拉取 `from_pretrained` 实际触及的部分,因此大约 30 秒即可准备就绪进行训练(速度最高可达 500 MB/s)。由于 Hugging Face 不收取出口流量费,这次拉取完全免费;如果模型存放在 S3 中,每次从其他云平台的 GPU 上读取都会被收取出口流量费用(AWS 上为 $0.09/GB)。
- 检查点直接以最高约 170 MB/s 的速度流式写入存储桶(每个检查点包含 8.43 GB 权重),并在 GPU 实例停止后继续保留。
在各个云平台上,检查点写入存储桶的速度如下:
| 云平台 | GPU | 检查点写入速度 |
|---|---|---|
| AWS (us-east-2) | L40S | ~168 MB/s |
| GCP (us-central1) | L4 | ~123 MB/s |
| Lambda (us-west-3) | H100 | ~112 MB/s |
基于 Xet 的存储:检查点和模型变体的去重
Hugging Face Buckets 构建于 Xet 之上,Xet 使用内容定义的切块技术,将文件分割成约 64 KB 的块,并且每个唯一块只存储一次。由于切块边界跟随内容变化,因此一次编辑只会改变其触及的块,而其余块会被识别为已存储。这在以下几个方面带来了好处:
- 增量检查点和适配器检查点。当冻结层、训练适配器或在保存之间大部分权重保持不变时,只有发生变化的块会上传,而不是整个检查点。
- 共享基础模型的模型变体。同一个基础模型的微调版本和量化版本之间存在大量重叠,因此这些共享块在所有变体之间只存储一次。
- 追加数据的数据集。日志(如对话记录或推理输出)通过向大型 Parquet 文件追加行来增长。现有的行组保持字节完全一致,因此只有新行会传输:在 Hugging Face 的测试中,向一个 100K 行的表格追加 10K 行,只移动了约 10 MB,而不是完整的约 106 MB。(如果原地编辑或删除行,请使用 `use_content_defined_chunking=True` 写入,以保持变更局部化。)
- 重复上传会跳过已经存储的内容。在我们的测试中,重新上传一个已在存储桶中的 8.43 GB 数据块大约需要 8 秒,而首次上传则需要 24 秒,因为只移动了块的哈希值。同样的机制使得服务端的 `hf buckets cp` 命令可以在仓库和存储桶之间通过引用进行复制,而无需重新上传字节。
你能节省多少取决于你的工件重叠程度,但去重是自动的:你像往常一样写入检查点,只有新的数据块会离开机器。
pip install "skypilot[huggingface]"
hf auth login # or: export HF_TOKEN=<your-token>
为任何 SkyPilot 任务添加一个 hf:// 挂载点并启动。MOUNT 需要基于 glibc 2.34+ 和 /dev/fuse 的基础镜像。
共同构建:Hugging Face 和 SkyPilot
初始存储:hf 支持最初来自 Nikhil Jha 的贡献。Hugging Face 团队将其推进并将 hf-mount FUSE 修复上游化,使其能够在非特权容器中挂载——这是许多 Kubernetes 集群的默认配置。SkyPilot 团队将其接入存储后端。整个流程都是开源的:SkyPilot、Hugging Face 的 hf-mount 以及 huggingface_hub 客户端。
资源
- SkyPilot 存储文档
- Hugging Face 存储桶指南
- hf-mount
- Xet:基于内容的分块与去重
- SkyPilot Slack 社区
本文提及的模型 1
本文提及的数据集 1
来自我们博客的更多文章
合作 音频 开源协作 ## Hugging Face 和 Cerebras 将 Gemma 4 引入实时语音 AI * * * * 71 2026年7月1日 A-Mahla 等人
指南 开源协作 ## 我们让本地模型免费对 OpenClaw 仓库进行分诊!* * * * osolmaz 等人 7 2026年6月22日 osolmaz, burtenshaw 等人
社区
编辑预览
通过拖拽、粘贴或点击此处上传图片、音频和视频
点击或粘贴此处上传图片
评论 · 或 发表评论
