Hub documentation

Обработка больших наборов данных

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Обработка больших наборов данных

Каждый Job имеет фиксированный объём локального диска, определяемый его hardware flavor (колонка Ephemeral Storage, также отображаемая командой hf jobs hardware). Чтобы работать с данными, не обязательно помещать весь датасет на этот диск: датасеты и Storage Buckets можно читать напрямую из Hub — стримингом, запросами или монтированием — так что один Job способен обрабатывать данные, значительно превышающие объём его диска. На этой странице описаны доступные варианты и случаи, когда стоит использовать каждый из них.

Какой подход выбрать?

  • Помещается на диск → обычный вызов load_dataset(...) работает как есть (или просто выберите более крупную версию — до 1 ТБ временного диска).
  • Итерация по строкам, обработка или обучение → stream.
  • Фильтрованные или обрезанные по столбцам сканы → запросите их напрямую через hf:// с помощью Polars или DuckDB.
  • Инструменты, ожидающие локальные пути к файлам → mount репозитория и чтение по требованию.
  • Сохранение результатов → записывайте их в Storage Bucket, чтобы они сохранились после завершения Job.

Потоковая загрузка набора данных

Функция Streaming читает примеры из Hub по мере их потребления вашим кодом — без загрузки и локальной копии, и она масштабируется до датасетов объёмом в несколько ТБ. В последних релизах её эффективность выросла до 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(). Его можно напрямую передать в DataLoader PyTorch или в Trainer для обучения на данных, превышающих объём диска. Полный API описан в руководстве по стримингу, а пошаговые инструкции по обучению в одноузловых и распределённых конфигурациях — в разделе Примеры и учебные материалы.

Стриминг также работает в распределённых конфигурациях с использованием Spark:

import pyspark_huggingface

df = spark.read.format("huggingface").option("config", "sample-10BT").load("HuggingFaceFW/fineweb-edu")

Полученный Spark dataframe распределён: каждый воркер читает данные из собственного подмножества файлов. Примеры чтения, записи и эффективной фильтрации строк и столбцов приведены в документации Spark.

Чтение и фильтрация по hf://

Многие библиотеки для работы с данными читают наборы данных Hub напрямую по путям hf:// — Polars, DuckDB и pandas нативно сканируют Parquet из Hub, перекладывая фильтрацию и выбор столбцов на этап сканирования, благодаря чему одна задача может обработать значительно больше данных, чем помещается в оперативной памяти или на диске. Этот запрос суммирует ~28 ГБ Parquet примерно за четыре минуты на стандартной CPU-версии:

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 минут для длительных сканов и распределите работу между несколькими параллельно выполняемыми Jobs, чтобы ускорить процесс. Примеры для каждой библиотеки приведены в разделах Polars, DuckDB и pandas, а о чтении buckets по hf:// (через HfFileSystem) см. в разделе Python data tools.

Подключение набора данных, модели или хранилища

Подключите репозиторий или бакет к Job как локальный путь с помощью -v / --volume; файлы загружаются по мере необходимости по мере чтения кодом, поэтому любой инструмент, работающий с локальными файлами, будет работать без изменений:

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)
    """
)

Файлы, записанные в путь монтирования бакета, сохраняются после завершения Job. Чтобы опубликовать обработанный датасет, используйте Dataset.push_to_hub.

Пример: запрос к Common Crawl без его загрузки

Common Crawl зеркалирует свой архив в бакете commoncrawl/commoncrawl — сотни ТБ. Прочитайте один WET-шард (в формате plaintext) напрямую из hf://, распарсите его и выполните запрос с помощью DuckDB; передаётся лишь несколько МБ, так как gzip-файл читается последовательно и чтение останавливается досрочно:

# /// 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 │
│ …       │    …  │
└─────────┴───────┘

См. также

Update on GitHub