Hugging Face 与 SkyPilot 推出零出口存储方案,开发者可在任意云平台运行 AI 工作负载,数据存储在 HF 无需额外费用,显著降低 MLOps 成本。
我们与 Hugging Face 携手,把两个部分真正连接了起来:你的模型和数据集继续留在 Hub 上,而 SkyPilot 则在任何拥有 GPU 的集群上运行计算任务,包括开发、训练和服务。只需使用一个 hf:// URL 和你已有的 HF_TOKEN,就能把 Hugging Face Bucket 或任意 Hub 仓库挂载到 SkyPilot 作业中,然后在任何有可用算力的地方启动任务。Hugging Face 不收取出口流量费,因此无论使用哪家云,把数据读取到这些 GPU 上都不需要额外费用。
让任何作业访问你的 Hub 数据。 store: hf 可以通过 MOUNT 或 COPY,使用一个 hf:// URL 和你现有的 HF_TOKEN,将可读写的 Hugging Face Bucket,或者只读的模型、数据集、Space 仓库挂载到 SkyPilot 任务中。
在任意云的任意 GPU 上运行。 SkyPilot 可以在 20 多家云平台、Kubernetes、Slurm 和本地基础设施中为作业寻找计算资源,因此,同一个任务可以使用任何厂商当前可用的预留 GPU 或按需 GPU。
读取数据无需支付出口流量费。 Hugging Face Storage 不收取出口流量费或 CDN 费用。因此,无论 SkyPilot 把作业调度到哪里,它都能直接从同一个 Bucket 读取模型和数据集,既不需要为每家云分别保存副本,也不用为拉取数据支付出口流量费。
由 Xet 提供支持的去重能力。 Bucket 构建在 Xet 之上,因此,增量 checkpoint 和模型变体只会存储并传输发生变化的数据块。
双方共同打造。 Hugging Face 与 SkyPilot 联合发布了这项功能,Hugging Face 团队还将相关的 hf-mount FUSE 修复提交到了上游,使其能够在非特权容器中正常运行。
SkyPilot 任务原本就可以把云对象存储挂载到本地路径,从而读写 S3、GCS、Azure、R2 等众多对象存储。现在,Hugging Face Storage 也以 store: hf 的形式加入了这一行列,并通过 hf:// scheme 访问:
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:// scheme 覆盖了完整生命周期:从模型和数据集仓库中读取内容;训练期间把 checkpoint 写入 Bucket;将最终模型发布回仓库;提供推理服务时,再把模型拉取到推理服务器上。大多数团队本来就把模型和数据集存放在 Hub 上,因此不需要执行迁移,也不用新建存储账户。
MOUNT 使用 Hugging Face 的 hf-mount FUSE 后端,因此 Bucket 或仓库会像 SkyPilot 的其他 FUSE 挂载方式(gcsfuse、blobfuse2、rclone、goofys)一样,以本地路径的形式呈现。数据获取发生在文件系统层:当代码发起 read() 调用时,驱动只会从 Xet 后端拉取对应的字节,因此只有你真正访问的数据才会通过网络传输。hf-mount 还会维护磁盘缓存,让重复读取直接在本地完成。对于 SkyPilot 的其他后端,这种磁盘缓存是 MOUNT_CACHED 模式的行为;普通 MOUNT 则会直接从 Bucket 流式读取每一次请求,不在本地保留任何内容。对于 hf store,MOUNT 和 MOUNT_CACHED 的行为相同,因此无论使用哪种模式,都会保留缓存。
由于读取是惰性进行的,进程无须等待整个大文件下载完毕,就能开始处理其中的内容,而不是先被完整复制过程阻塞。这让 GPU 几乎可以立即投入工作:数据一边流入,一边用于训练,不必让 GPU 在等待数据集或 checkpoint 下载时持续空转和计费。这种方式在第一个 epoch 中尤其划算,因为此时还没有任何缓存。COPY 则采用另一种方式,通过 huggingface_hub 预先下载数据,并且没有特殊环境要求。
身份验证直接使用你已有的 token。在环境中设置 HF_TOKEN,并通过 --secret HF_TOKEN 将它传给任务;无论作业最终落在哪家云上,SkyPilot 都会使用该 token 完成挂载。同一个 token 可以用于 AWS、GCP、Azure、Nebius、Lambda,也可以用于你自己的 Kubernetes 集群,因此不需要管理各家云不同的 Bucket 密钥。
如今,GPU 算力很少只来自一个地方。为了获得足够的 H100 和 H200,团队通常会同时在多家供应商处持有预留或承诺使用的算力,例如 hyperscaler 上的一组实例、neocloud 上的一个集群,再加上一套本地机架,然后根据实际配额选择运行位置。SkyPilot 正是为此而生:只需一份作业配置,即可跨 20 多家云平台、Kubernetes 和本地基础设施进行调度,把任务放到任何当前空闲的预留集群上。
问题一直出在对象存储上。对象存储通常受限于特定区域和特定云平台,因此,当 GPU 或推理服务器位于另一家供应商的数据中心时,要么必须在每家供应商的 Bucket 中各保存一份数据,要么就得付费跨云拉取。数据一旦离开云厂商的网络,大多数云平台都会收取出口流量费——例如 AWS 的费用约为每 GB 0.09 美元;即使只是在同一家云的不同区域之间传输,通常也要收费。把基础模型拉取到每一个推理节点,或者让另一家云上的集群对数据集迭代多个 epoch,都会在已经预留的 GPU 成本之上再增加一笔可观费用。结果是,团队不得不把每个任务固定在保存数据的供应商那里,却让其他地方的算力闲置。
Hugging Face Storage 消除了最关键一侧的成本:读取。它不收取出口流量费或 CDN 费用,存储价格为每月每 TB 12~18 美元;相比之下,AWS S3 的价格约为每月每 TB 23 美元,另外还要支付出口流量费。因此,同一个 Bucket 可以被所有这些集群访问,而且无论 GPU 在哪里运行,读取数据都是免费的。写回数据时,你所使用的计算云仍会收取常规出口流量费,就像写入任何云外存储一样;但对于大多数 AI 工作负载,读取才是主要流量来源,例如多个 epoch 持续流式读取的数据集,或者每个新训练节点、推理节点都要拉取的模型权重。这样一来,你就不必再把每个任务固定到持有数据副本的供应商上。
为了采集一些 benchmark 数据,我们进行了一次小规模 fine-tune:使用 TRL 的 SFTTrainer,在 HuggingFaceH4/Multilingual-Thinking 数据集上微调 Qwen/Qwen3.5-4B。模型以只读方式从其 Hub 仓库挂载,训练产生的每个 checkpoint 都写入 Hugging Face Bucket。同一份 SkyPilot YAML 分别运行在 AWS、GCP 和 Lambda 上,唯一需要修改的参数是 --infra。SkyPilot 会把每个作业放到有空闲 GPU 的位置,而三个作业读写的都是同一个 Bucket。
# 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 上约为每 GB 0.09 美元。
Checkpoint 会以最高约 170 MB/s 的速度直接流式写入 Bucket,每份权重大小为 8.43 GB,并且在 GPU 实例终止后仍然持久保存。
在各家云平台上,checkpoint 写入 Bucket 的速度如下:
Hugging Face Bucket 构建在 Xet 之上。Xet 使用内容定义分块,将文件切分成约 64 KB 的数据块,并且每个唯一数据块只存储一次。由于分块边界取决于内容本身,一次编辑只会改变它所触及的数据块,其余部分仍会被识别为已经存储。这种机制在以下几种场景中尤其有效:
增量 checkpoint 和 adapter checkpoint。 当你冻结部分层、训练 adapter,或者采用其他方式让大部分权重在两次保存之间保持不变时,只需上传发生变化的数据块,而不是整个 checkpoint。
共享同一个基础模型的模型变体。 同一个基础模型的 fine-tune 和量化版本之间存在大量重叠,因此,它们共享的数据块只需要存储一次。
持续追加内容的数据集。 对话 trace 或推理输出等日志,通常通过向大型 Parquet 文件追加新行来增长。原有 row group 的字节保持完全一致,因此只需要传输新增加的行。在 Hugging Face 的测试中,向一个包含 10 万行的表追加 1 万行数据,只传输了约 10 MB,而不是完整的约 106 MB。(如果要原地编辑或删除行,请使用 use_content_defined_chunking=True 写入,以便将变化限制在局部。)
重新上传时会跳过已经存储的内容。 在我们的测试中,重新上传一个 Bucket 中已经存在的 8.43 GB blob 大约需要 8 秒,而首次上传需要 24 秒,因为重新上传时只需要传输数据块的 hash。同样的机制还让服务端的 hf buckets cp 能够在仓库和 Bucket 之间按引用复制,而不必重新上传实际字节。
具体能节省多少,取决于 artifact 之间的重叠程度;但去重过程是自动的:你仍然像往常一样写入 checkpoint,只有新数据块会离开当前机器。
pip install "skypilot[huggingface]"
hf auth login # or: export HF_TOKEN=<your-token>
在任意 SkyPilot 任务中添加一个 hf:// 挂载,然后启动即可。MOUNT 需要基础镜像提供 glibc 2.34 或更高版本,并且能够访问 /dev/fuse。
最初的 store: hf 支持源自 Nikhil Jha 的贡献。Hugging Face 团队在此基础上继续推进,并将 hf-mount FUSE 的相关修复提交到了上游,使其能够在非特权容器中完成挂载——许多 Kubernetes 集群默认使用的正是这种容器。SkyPilot 团队则将它接入了存储后端。整条技术链路都是开源的,包括 SkyPilot、Hugging Face 的 hf-mount,以及 huggingface_hub client。
SkyPilot 存储文档
Hugging Face Storage Bucket 指南
Xet:内容定义分块与去重
SkyPilot Slack 社区
本文提到的模型 1
本文提到的数据集 1
更多博客文章
Hugging Face 与 Cerebras 将 Gemma 4 引入实时语音 AI
我们让本地模型免费分诊 OpenClaw 仓库中的问题!*
· 注册或登录后发表评论
本文提到的模型 1
本文提到的数据集 1