# Procesar conjuntos de datos grandes

Cada Job viene con una cantidad fija de disco local, definida por su [hardware flavor](./jobs-pricing#pricing) (la columna **Ephemeral Storage**, también mostrada por `hf jobs hardware`). No es necesario que un conjunto de datos completo quepa en ese disco para trabajar con él: los datasets y los [Storage Buckets](./storage-buckets) se pueden leer directamente desde el Hub, ya sea mediante streaming, consultas o montaje, de modo que un solo Job puede procesar datos mucho más grandes que su disco. Esta página cubre las opciones disponibles y cuándo conviene utilizar cada una.

## ¿Qué enfoque?

- **Cabe en el disco** → un simple `load_dataset(...)` funciona tal cual (o simplemente elige una versión más grande, hasta 1 TB de disco efímero).
- **Iterar sobre filas, procesar o entrenar** → [stream](#stream-the-dataset) it.
- **Escaneos filtrados o con columnas recortadas** → consúltalo [directamente sobre `hf://`](#read-and-filter-over-hf) con Polars o DuckDB.
- **Las herramientas que esperan rutas de archivos locales** → [montar](#mount-a-dataset-model-or-bucket) el repositorio y leerlo de forma perezosa.
- **Guardar los resultados** → escríbelos en un [Storage Bucket](#save-results) para que sobrevivan al Job.

## Transmitir el conjunto de datos

Las lecturas en streaming obtienen ejemplos del Hub a medida que tu código los consume: sin descargas, sin copia local y con capacidad para escalar a conjuntos de datos de varios TB. Las versiones recientes lo hicieron [hasta 100 veces más eficiente](https://huggingface.co/blog/streaming-datasets), alcanzando un rendimiento comparable al de los SSD locales al entrenar con muchos workers:

```python
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
```

Un dataset en streaming es un `IterableDataset` que admite `.filter()`, `.map()`, `.shuffle(buffer_size=...)` y `.batch()` de forma perezosa, y puede pasarse directamente a un `DataLoader` de PyTorch o a un `Trainer` para entrenar con datos más grandes que el disco. Consulte la [Guía de streaming](/docs/datasets/stream) para la API completa y [Ejemplos y tutoriales](./jobs-examples) para recorridos de entrenamiento de principio a fin en configuraciones de un solo nodo o distribuidas.

El streaming también funciona en configuraciones distribuidas, usando Spark:

```python
import pyspark_huggingface

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

El dataframe de Spark resultante está distribuido: cada worker transmite desde su propio subconjunto de archivos. Consulte la [documentación de Spark](./datasets-spark) para ejemplos de lectura, escritura y filtrado eficiente de filas y columnas.

## Leer y filtrar sobre `hf://`

Muchas bibliotecas de datos leen conjuntos de datos de Hub directamente a través de rutas `hf://`: **Polars**, **DuckDB** y **pandas** escanean Parquet de Hub de forma nativa, delegando los filtros y la selección de columnas en el escaneo, de modo que un solo Job puede procesar mucho más datos de los que caben en memoria o en disco. Esta consulta resume unos 28 GB de Parquet en aproximadamente cuatro minutos en la variante de CPU predeterminada:

```python
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)
```

Escaneos como este están limitados por la red y no por la memoria, y los motores difieren en cómo paralelizan de forma agresiva las lecturas remotas, por lo que los tiempos varían según la biblioteca. Dos consecuencias prácticas: configure `--timeout` por encima del valor predeterminado de 30 minutos para escaneos largos, y divida el trabajo entre varios Jobs que se ejecutan en paralelo para ir más rápido. Consulte [Polars](./datasets-polars), [DuckDB](./datasets-duckdb) y [pandas](./datasets-pandas) para ejemplos por biblioteca, y [Python data tools](./storage-buckets-access#python-data-tools) para leer **buckets** a través de `hf://` (que pasa por [`HfFileSystem`](/docs/huggingface_hub/guides/hf_file_system)).

## Montar un conjunto de datos, un modelo o un bucket

Monta un repositorio o cubo en el Job como una ruta local con `-v` / `--volume`; los archivos se obtienen de forma perezosa a través de la red a medida que tu código los lee, por lo que cualquier herramienta que lea archivos locales funciona sin problemas:

```bash
hf jobs uv run --flavor cpu-upgrade \
  -v hf://datasets/HuggingFaceFW/fineweb-edu:/mnt/data \
  process.py
```

```python
# /// 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
```

Montar es la opción natural cuando los archivos se consumen completos: pesos de modelos, archivos de audio o imagen, archivos comprimidos, o cuando una herramienta solo acepta rutas de archivo. Para escaneos de Parquet con múltiples archivos de gran tamaño, consultar [directamente sobre `hf://`](#read-and-filter-over-hf) suele ser varias veces más rápido que escanear a través de un montaje.

Los conjuntos de datos y los modelos se montan en solo lectura; los buckets son de lectura y escritura, lo que los convierte en un buen lugar para [guardar resultados](#save-results). Consulte [Configuración](./jobs-configuration#volumes) para la sintaxis completa de `-v` y [patrones de acceso a buckets](./storage-buckets-access#volume-mounts-in-jobs-and-spaces) para más detalles.

> [!TIP]
> Los archivos leídos a través de un montaje se almacenan en caché en el disco efímero del Job, por lo que leerlos de forma perezosa (un archivo a la vez) mantiene la huella pequeña. Al ejecutar un script local con `hf jobs uv run`, el directorio del script se monta en `/data`, por lo que debe montar sus datos en otra ubicación (p. ej., `/mnt/data`).

## Guardar resultados

El disco efímero no sobrevive al Job, por lo que escriba en un [Storage Bucket](./storage-buckets) montado en modo lectura-escritura todo lo que desee conservar, o publíquelo en el Hub como un dataset. DuckDB puede filtrar la fuente sobre `hf://` y escribir las coincidencias directamente en un bucket montado en una sola consulta out-of-core, de modo que el resultado nunca tiene que caber en memoria:

```bash
hf jobs uv run --flavor cpu-upgrade --timeout 1h \
  -v hf://buckets/username/my-output:/mnt/out \
  filter.py
```

```python
# /// 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)
    """
)
```

Los archivos escritos en la ruta de montaje del bucket persisten después de que el Job termina. Para publicar un dataset procesado en su lugar, use [`Dataset.push_to_hub`](/docs/datasets/upload_dataset).

## Ejemplo práctico: consultar Common Crawl sin descargarlo

Common Crawl replica su archivo en el bucket [`commoncrawl/commoncrawl`](https://huggingface.co/buckets/commoncrawl/commoncrawl) — cientos de TB. Transmite un shard WET (texto plano) directamente desde `hf://`, analízalo y consulta con DuckDB; solo unos pocos MB transitan porque el gzip se lee de forma secuencial y se detiene anticipadamente:

```python
# /// 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()
```

Ejecútalo con `hf jobs uv run cc_wet.py` — se completa en aproximadamente un minuto en el sabor de CPU predeterminado e imprime:

```
┌─────────┬───────┐
│  lang   │ docs  │
│ varchar │ int64 │
├─────────┼───────┤
│ eng     │  1974 │
│ zho     │   586 │
│ rus     │   434 │
│ jpn     │   244 │
│ …       │    …  │
└─────────┴───────┘
```

## Véase también

- [Stream](/docs/datasets/stream) · [Conjuntos de datos en streaming: 100 veces más eficientes](https://huggingface.co/blog/streaming-datasets)
- [Precios y hardware](./jobs-pricing#pricing) — disco efímero por sabor · [Configuración](./jobs-configuration#volumes) — volúmenes
- [Buckets de almacenamiento](./storage-buckets) · [patrones de acceso](./storage-buckets-access) · [integraciones](./storage-buckets-integrations)

