Phase 00 - Lesson 09

Gestión de Datos

Los datos son el combustible. Cómo los gestionas determina qué tan rápido avanzas.

Tipo: Build Lenguaje: Python Requisitos previos: Fase 0, Lección 01 Tiempo: ~45 minutos

Objetivos de Aprendizaje

  • Cargar, transmitir (stream) y almacenar en caché conjuntos de datos usando la biblioteca datasets de Hugging Face
  • Convertir entre los formatos CSV, JSON, Parquet y Arrow y explicar sus ventajas y desventajas
  • Crear particiones de entrenamiento/validación/prueba reproducibles con semillas aleatorias fijas
  • Gestionar archivos grandes de modelos y conjuntos de datos usando .gitignore, Git LFS o DVC

El Problema

Todo proyecto de IA comienza con datos. Necesitas encontrar conjuntos de datos, descargarlos, convertir entre formatos, dividirlos para entrenamiento y evaluación, y versionarlos para que los experimentos sean reproducibles. Hacerlo manualmente cada vez es lento y propenso a errores. Necesitas un flujo de trabajo repetible.

El Concepto

graph TD
    A["Hugging Face Hub"] --> B["datasets library"]
    B --> C["Load / Stream"]
    C --> D["Local Cache<br/>~/.cache/huggingface/"]
    B --> E["Format Conversion<br/>CSV, JSON, Parquet, Arrow"]
    E --> F["Data Splits<br/>train / val / test"]
    F --> G["Your Training Pipeline"]

La biblioteca datasets de Hugging Face es la forma estándar de cargar datos para el trabajo con IA. Maneja la descarga, el almacenamiento en caché, la conversión de formato y el streaming de forma nativa.

Manos a la Obra

Paso 1: Instalar la biblioteca datasets

pip install datasets huggingface_hub

Paso 2: Cargar un conjunto de datos

from datasets import load_dataset

dataset = load_dataset("imdb")
print(dataset)
print(dataset["train"][0])

Esto descarga el conjunto de datos de reseñas de películas IMDB. Después de la primera descarga, se carga desde la caché en ~/.cache/huggingface/datasets/.

Paso 3: Transmitir conjuntos de datos grandes

Algunos conjuntos de datos son demasiado grandes para caber en disco. El streaming los carga fila por fila sin descargar todo.

dataset = load_dataset("wikimedia/wikipedia", "20220301.en", split="train", streaming=True)

for i, example in enumerate(dataset):
    print(example["title"])
    if i >= 4:
        break

El streaming te da un IterableDataset. Procesas las filas a medida que llegan. El uso de memoria permanece constante sin importar el tamaño del conjunto de datos.

Paso 4: Formatos de conjuntos de datos

La biblioteca datasets usa Apache Arrow por debajo. Puedes convertir a otros formatos según lo que necesite tu pipeline.

dataset = load_dataset("imdb", split="train")

dataset.to_csv("imdb_train.csv")
dataset.to_json("imdb_train.json")
dataset.to_parquet("imdb_train.parquet")

Comparación de formatos:

Formato Tamaño Velocidad de Lectura Mejor Para
CSV Grande Lenta Legibilidad humana, hojas de cálculo
JSON Grande Lenta APIs, datos anidados
Parquet Pequeño Rápida Analítica, consultas columnares
Arrow Pequeño La más rápida Procesamiento en memoria (lo que usa datasets internamente)

Para el trabajo con IA, Parquet es el mejor formato de almacenamiento. Arrow es con lo que trabajas en memoria. CSV y JSON son para intercambio.

Paso 5: Particiones de datos

Todo proyecto de ML necesita tres particiones:

  • Entrenamiento: El modelo aprende de esto (normalmente 80%)
  • Validación: Verificas el progreso durante el entrenamiento (normalmente 10%)
  • Prueba: Evaluación final después de completar el entrenamiento (normalmente 10%)

Algunos conjuntos de datos vienen ya divididos. Cuando no es así, divídelos tú mismo:

dataset = load_dataset("imdb", split="train")

split = dataset.train_test_split(test_size=0.2, seed=42)
train_val = split["train"].train_test_split(test_size=0.125, seed=42)

train_ds = train_val["train"]
val_ds = train_val["test"]
test_ds = split["test"]

print(f"Train: {len(train_ds)}, Val: {len(val_ds)}, Test: {len(test_ds)}")

Siempre establece una semilla para la reproducibilidad. La misma semilla produce la misma partición cada vez.

Paso 6: Descargar y almacenar en caché modelos

Los modelos son archivos grandes. La biblioteca huggingface_hub maneja la descarga y el almacenamiento en caché.

from huggingface_hub import hf_hub_download, snapshot_download

model_path = hf_hub_download(
    repo_id="sentence-transformers/all-MiniLM-L6-v2",
    filename="config.json"
)
print(f"Cached at: {model_path}")

model_dir = snapshot_download("sentence-transformers/all-MiniLM-L6-v2")
print(f"Full model at: {model_dir}")

Los modelos se almacenan en caché en ~/.cache/huggingface/hub/. Una vez descargados, se cargan al instante en ejecuciones posteriores.

Paso 7: Manejar archivos grandes

Los pesos de los modelos y los conjuntos de datos grandes no deberían ir a git. Tres opciones:

Opción A: .gitignore (la más simple)

*.bin
*.safetensors
*.pt
*.onnx
data/*.parquet
data/*.csv
models/

Opción B: Git LFS (versionar archivos grandes en git)

git lfs install
git lfs track "*.bin"
git lfs track "*.safetensors"
git add .gitattributes

Git LFS almacena punteros en tu repositorio y los archivos reales en un servidor separado. GitHub te da 1 GB gratis.

Opción C: DVC (control de versiones de datos)

pip install dvc
dvc init
dvc add data/training_set.parquet
git add data/training_set.parquet.dvc data/.gitignore
git commit -m "Track training data with DVC"

DVC crea pequeños archivos .dvc que apuntan a tus datos. Los datos en sí residen en S3, GCS u otro backend de almacenamiento remoto.

Enfoque Complejidad Mejor Para
.gitignore Baja Proyectos personales, datos descargados que puedes volver a obtener
Git LFS Media Equipos que comparten pesos de modelos vía git
DVC Alta Experimentos reproducibles, conjuntos de datos grandes, equipos

Para este curso, .gitignore es suficiente. Usa DVC cuando necesites reproducir experimentos exactos entre máquinas.

Paso 8: Patrones de almacenamiento

El almacenamiento local funciona para conjuntos de datos de menos de ~10 GB. La caché de HF maneja esto automáticamente.

El almacenamiento en la nube es para cualquier cosa más grande o compartida entre máquinas:

import os

local_path = os.path.expanduser("~/.cache/huggingface/datasets/")

# s3_path = "s3://my-bucket/datasets/"
# gcs_path = "gs://my-bucket/datasets/"

DVC se integra directamente con S3 y GCS:

dvc remote add -d myremote s3://my-bucket/dvc-store
dvc push

Para este curso, el almacenamiento local es suficiente. El almacenamiento en la nube se vuelve relevante cuando haces fine-tuning en instancias GPU remotas.

Conjuntos de Datos Usados en Este Curso

Conjunto de Datos Lecciones Tamaño Lo Que Enseña
IMDB Tokenización, clasificación 84 MB Fundamentos de clasificación de texto
WikiText Modelado de lenguaje 181 MB Predicción del siguiente token
SQuAD Sistemas de QA 35 MB Preguntas y respuestas, spans
Common Crawl (subconjunto) Embeddings Varía Procesamiento de texto a gran escala
MNIST Fundamentos de visión 21 MB Fundamentos de clasificación de imágenes
COCO (subconjunto) Multimodal Varía Pares imagen-texto

No necesitas descargar todos estos ahora. Cada lección especifica lo que necesita.

Úsalo

Ejecuta el script de utilidad para verificar que todo funciona:

python code/data_utils.py

Esto descarga un conjunto de datos pequeño, lo convierte, lo divide e imprime un resumen.

Entrégalo (Ship It)

Esta lección produce:

  • code/data_utils.py - utilidad reutilizable de carga y almacenamiento en caché de datos
  • outputs/prompt-data-helper.md - prompt para encontrar el conjunto de datos correcto para una tarea

Ejercicios

  1. Carga el conjunto de datos glue con la config mrpc e inspecciona los primeros 5 ejemplos
  2. Transmite el conjunto de datos c4 y cuenta cuántos ejemplos puedes procesar en 10 segundos
  3. Convierte un conjunto de datos a Parquet y compara el tamaño del archivo con CSV
  4. Crea una partición de entrenamiento/validación/prueba 70/15/15 con una semilla fija y verifica los tamaños

Términos Clave

Término Lo que dice la gente Lo que realmente significa
Partición de conjunto de datos "Datos de entrenamiento" Un subconjunto nombrado (train/val/test) usado en diferentes etapas del ciclo de vida del ML
Streaming "Cargarlo de forma diferida" Procesar datos fila por fila desde una fuente remota sin descargar el conjunto de datos completo
Parquet "CSV comprimido" Un formato de archivo columnar optimizado para consultas analíticas y eficiencia de almacenamiento
Arrow "Dataframe rápido" Un formato columnar en memoria usado internamente por la biblioteca datasets para lecturas zero-copy
Git LFS "Git para archivos grandes" Una extensión que almacena archivos grandes fuera del repositorio git mientras mantiene punteros en el control de versiones
DVC "Git para datos" Un sistema de control de versiones para conjuntos de datos y modelos que se integra con el almacenamiento en la nube
Caché "Ya descargado" Una copia local de datos obtenidos previamente, almacenada en ~/.cache/huggingface/ por defecto
0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).