Hub documentation
处理大型数据集
处理大型数据集
每个 Job 都配有固定大小的本地磁盘,由其 硬件规格(即 Ephemeral Storage 列,也可通过 hf jobs hardware 查看)决定。您无需将整个数据集放入该磁盘才能进行处理:数据集和 Storage Buckets 可以直接从 Hub 读取——支持流式读取、查询或挂载——因此单个 Job 可以处理远超其磁盘容量的数据。本页将介绍这些选项以及各自的适用场景。
选择哪种方法?
- 可放入磁盘 → 直接运行普通的
load_dataset(...)即可(或者选择更大的规格——最高支持 1 TB 的临时磁盘)。 - 逐行迭代、处理或训练 → 将其 stream 化。
- 经过过滤或列裁剪的扫描 → 使用 Polars 或 DuckDB 直接在
hf://上查询。 - 期望本地文件路径的工具 → 挂载 该仓库并延迟读取。
- 持久化结果 → 将其写入 Storage Bucket,以便在 Job 结束后仍然保留。
流式传输数据集
流式读取会在代码消费示例时从 Hub 获取数据——无需下载,无需本地副本,并且可扩展至多 TB 数据集。最近的版本使其效率提高了多达 100 倍,在跨多个工作进程进行训练时,性能可与本地 SSD 相媲美:
from datasets import load_dataset
ds = load_dataset("HuggingFaceFW/fineweb-edu", "sample-10BT", split="train", streaming=True)
for example in ds.take(1000):
... # streams in as you iterate, nothing hits disk流式数据集是一种 IterableDataset,支持惰性 .filter()、.map()、.shuffle(buffer_size=...) 和 .batch(),可以直接传递给 PyTorch DataLoader 或 Trainer,用于训练比磁盘容量更大的数据。完整的 API 请参阅 Stream 指南,单节点或分布式环境的端到端训练教程请参阅 示例与教程。
在分布式环境中,使用 Spark 也可以实现流式处理:
import pyspark_huggingface
df = spark.read.format("huggingface").option("config", "sample-10BT").load("HuggingFaceFW/fineweb-edu")生成的 Spark 数据帧是分布式的:每个工作节点从自己的文件子集中进行流式读取。有关读取、写入以及高效过滤行和列的示例,请参阅 Spark 文档。
在 hf:// 上读取和过滤
许多数据库可以直接通过 hf:// 路径读取 Hub 数据集——Polars、DuckDB 和 pandas 均能原生扫描 Hub Parquet,并将过滤条件和列选择下推至扫描层,因此单个 Job 可处理远超内存或磁盘容量的数据。以下查询在默认 CPU 配置下,约四分钟即可汇总约 28 GB 的 Parquet 数据:
import polars as pl
agg = (
pl.scan_parquet("hf://datasets/HuggingFaceFW/fineweb-edu/sample/10BT/*.parquet")
.filter(pl.col("int_score") >= 4)
.group_by("int_score")
.agg(pl.len().alias("docs"), pl.col("token_count").sum().alias("tokens"))
.sort("int_score")
.collect()
)
print(agg)此类扫描受网络限制而非内存限制,且各引擎在并行化远程读取方面的激进程度不同,因此耗时因库而异。两个实用建议:对于长时间扫描,请将 --timeout 设置为高于默认的 30 分钟;并将工作拆分到多个并行运行的 Job 中以提升速度。请参阅 Polars、DuckDB 和 pandas 获取各库的示例,以及 Python data tools 了解如何通过 hf:// 读取 buckets(该方式经由 HfFileSystem 处理)。
挂载数据集、模型或存储桶
使用 -v / --volume 将仓库或存储桶挂载到 Job 的本地路径;文件会在代码读取时通过网络按需获取,因此任何读取本地文件的工具都能直接使用:
hf jobs uv run --flavor cpu-upgrade \
-v hf://datasets/HuggingFaceFW/fineweb-edu:/mnt/data \
process.py# /// script
# dependencies = ["polars"]
# ///
# process.py — the mounted repo is just a directory of files
from pathlib import Path
import polars as pl
for path in Path("/mnt/data/sample/10BT").glob("*.parquet"):
shard = pl.read_parquet(path)
... # process one shard at a time, write results out当文件被整体读取时——例如模型权重、音频或图像文件、归档文件——或者当工具仅接受文件路径时,挂载是自然的选择。对于大型多文件 Parquet 扫描,通过 直接在 hf:// 上查询 通常比通过挂载进行扫描快数倍。
数据集和模型以只读方式挂载;存储桶为读写模式,因此是保存结果的理想位置。有关完整的-v语法,请参阅配置;有关详细信息,请参阅存储桶访问模式。
通过挂载读取的文件会缓存在 Job 的临时磁盘上,因此采用惰性读取(一次读取一个文件)可以保持占用空间较小。使用
hf jobs uv run运行本地脚本时,脚本目录会挂载到/data,因此请将数据挂载到其他位置(例如/mnt/data)。
保存结果
临时磁盘不会在 Job 结束后保留,因此请将需要保留的内容写入以读写方式挂载的 Storage Bucket,或将其作为数据集推送到 Hub。DuckDB 可以通过 hf:// 对源数据进行过滤,并在一个外存查询中直接将匹配结果写入已挂载的存储桶,因此结果无需全部装入内存:
hf jobs uv run --flavor cpu-upgrade --timeout 1h \
-v hf://buckets/username/my-output:/mnt/out \
filter.py# /// script
# dependencies = ["duckdb"]
# ///
# filter.py — scan ~28 GB of Parquet, keep only the matching rows
import duckdb
duckdb.sql(
"""
COPY (
SELECT text, url, token_count
FROM 'hf://datasets/HuggingFaceFW/fineweb-edu/sample/10BT/*.parquet'
WHERE int_score >= 4 AND token_count >= 4000
) TO '/mnt/out/result.parquet' (FORMAT parquet)
"""
)写入到存储桶挂载路径下的文件在作业结束后会保留。若要发布处理后的数据集,请改用 Dataset.push_to_hub。
实战示例:查询 Common Crawl 而无需下载
Common Crawl 将其归档镜像到存储桶 commoncrawl/commoncrawl——容量达数百 TB。直接从 hf:// 流式读取一个 WET(纯文本)分片,对其进行解析,并使用 DuckDB 进行查询;由于 gzip 是顺序读取且会提前停止,因此传输的数据量仅为几 MB:
# /// script
# requires-python = ">=3.11"
# dependencies = ["huggingface_hub>=1.9", "fastwarc>=0.15", "duckdb>=1.0"]
# ///
import duckdb
from fastwarc.warc import ArchiveIterator, WarcRecordType
from huggingface_hub import hffs
WET = (
"buckets/commoncrawl/commoncrawl/crawl-data/CC-MAIN-2026-17/"
"segments/1775805908305.14/wet/"
"CC-MAIN-20260410081153-20260410111153-00000.warc.wet.gz"
)
rows = []
with hffs.open(WET, "rb") as f:
for rec in ArchiveIterator(f, record_types=WarcRecordType.conversion):
lang = (rec.headers.get("WARC-Identified-Content-Language", "") or "und").split(",")[0]
rows.append((rec.headers.get("WARC-Target-URI", ""), lang, len(rec.reader.read())))
if len(rows) >= 5000:
break
con = duckdb.connect()
con.execute("CREATE TABLE wet(url VARCHAR, lang VARCHAR, n_chars BIGINT)")
con.executemany("INSERT INTO wet VALUES (?,?,?)", rows)
con.sql("SELECT lang, count(*) AS docs FROM wet GROUP BY lang ORDER BY docs DESC LIMIT 10").show()使用 hf jobs uv run cc_wet.py 运行它——在默认的 CPU 规格上大约一分钟即可完成,并输出:
┌─────────┬───────┐
│ lang │ docs │
│ varchar │ int64 │
├─────────┼───────┤
│ eng │ 1974 │
│ zho │ 586 │
│ rus │ 434 │
│ jpn │ 244 │
│ … │ … │
└─────────┴───────┘