LeRobot documentation

Portar conjuntos de datos grandes al formato LeRobot Dataset v3.0

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Portar conjuntos de datos grandes al formato LeRobot Dataset v3.0

Este tutorial explica cómo portar conjuntos de datos robóticos a gran escala al formato LeRobot Dataset v3.0. Utilizaremos el conjunto de datos DROID 1.0.1 como ejemplo principal, que demuestra el manejo de conjuntos de datos de varios terabytes con miles de fragmentos en clústeres SLURM.

Organización de archivos: v2.1 frente a v3.0

El Dataset v3.0 cambia fundamentalmente cómo se organiza y almacena los datos:

Estructura v2.1 (basada en episodios):

dataset/
├── data/chunk-000/episode_000000.parquet
├── data/chunk-000/episode_000001.parquet
├── videos/chunk-000/camera/episode_000000.mp4
└── meta/episodes.jsonl

Estructura de v3.0 (basada en archivos):

dataset/
├── data/chunk-000/file-000.parquet        # Multiple episodes per file
├── videos/camera/chunk-000/file-000.mp4   # Consolidated video chunks
└── meta/episodes/chunk-000/file-000.parquet  # Structured metadata

Esta transición de archivos de episodios individuales a fragmentos basados en archivos mejora drásticamente el rendimiento y reduce la sobrecarga de almacenamiento.

Novedades en Dataset v3.0

Dataset v3.0 introduce mejoras significativas para el manejo de conjuntos de datos grandes:

🏗️ Organización de archivos mejorada

  • Estructura basada en archivos: Los episodios ahora se agrupan en archivos segmentados en lugar de archivos individuales por episodio
  • Tamaños de archivo configurables: para archivos de datos y de video
  • Mejor eficiencia de almacenamiento: Mejor compresión y menor sobrecarga

📊 Gestión moderna de metadatos

  • Metadatos basados en Parquet: Se reemplazó JSON Lines por el formato parquet eficiente
  • Acceso estructurado a episodios: Acceso directo a un DataFrame de pandas a través de dataset.meta.episodes
  • Estadísticas por episodio: Seguimiento de estadísticas mejorado a nivel de episodio

🚀 Mejoras de rendimiento

  • Acceso con mapeo de memoria: Mejora del uso de RAM mediante el mapeo de memoria de PyArrow
  • Carga más rápida: tiempo de inicialización del conjunto de datos reducido significativamente
  • Mejor escalabilidad: Diseñado para conjuntos de datos con millones de episodios

Prerrequisitos

Antes de portar conjuntos de datos grandes, asegúrate de tener:

  • LeRobot instalado con soporte para v3.0. Sigue nuestra Guía de instalación.
  • Almacenamiento suficiente: Los conjuntos de datos crudos pueden ser muy grandes (p. ej., DROID requiere 2 TB)
  • Acceso al clúster (recomendado para conjuntos de datos grandes): SLURM o un programador de trabajos similar
  • Dependencias específicas del conjunto de datos: Para DROID, necesitarás las utilidades de TensorFlow Dataset

Comprensión del conjunto de datos DROID

DROID 1.0.1 es un excelente ejemplo de un conjunto de datos robótico a gran escala:

  • Tamaño: 1,7 TB (formato RLDS), 8,7 TB (datos sin procesar)
  • Estructura: 2048 fragmentos predefinidos de conjuntos de datos de TensorFlow
  • Contenido: más de 76.000 trayectorias de manipulación robótica de robots Franka Emika Panda
  • Alcance: Tareas de manipulación en el mundo real en múltiples entornos y objetos
  • Formato: Originalmente en formato TensorFlow Records/RLDS, lo que requiere su conversión al formato LeRobot
  • Alojamiento: Google Cloud Storage con acceso público a través de gsutil

El conjunto de datos contiene demostraciones de manipulación diversas con:

  • Vistas de múltiples cámaras (cámara de muñeca, cámaras externas)
  • Descripciones de tareas de lenguaje natural
  • Estado propioceptivo y acciones del robot
  • Anotaciones de éxito/fallo

Esquema de características de DROID

DROID_FEATURES = {
    # Episode markers
    "is_first": {"dtype": "bool", "shape": (1,)},
    "is_last": {"dtype": "bool", "shape": (1,)},
    "is_terminal": {"dtype": "bool", "shape": (1,)},

    # Language instructions
    "language_instruction": {"dtype": "string", "shape": (1,)},
    "language_instruction_2": {"dtype": "string", "shape": (1,)},
    "language_instruction_3": {"dtype": "string", "shape": (1,)},

    # Robot state
    "observation.state.gripper_position": {"dtype": "float32", "shape": (1,)},
    "observation.state.cartesian_position": {"dtype": "float32", "shape": (6,)},
    "observation.state.joint_position": {"dtype": "float32", "shape": (7,)},

    # Camera observations
    "observation.images.wrist_left": {"dtype": "video", "shape": (180, 320, 3), "names": ["height", "width", "channels"]},
    "observation.images.exterior_1_left": {"dtype": "video", "shape": (180, 320, 3), "names": ["height", "width", "channels"]},
    "observation.images.exterior_2_left": {"dtype": "video", "shape": (180, 320, 3), "names": ["height", "width", "channels"]},

    # Actions
    "action.gripper_position": {"dtype": "float32", "shape": (1,)},
    "action.cartesian_position": {"dtype": "float32", "shape": (6,)},
    "action.joint_position": {"dtype": "float32", "shape": (7,)},

    # Standard LeRobot format
    "observation.state": {"dtype": "float32", "shape": (8,)},  # joints + gripper
    "action": {"dtype": "float32", "shape": (8,)},  # joints + gripper
}

Enfoque 1: Porting a un solo equipo

Paso 1: Instalar dependencias

Específicamente para DROID:

pip install tensorflow
pip install tensorflow_datasets

Para otros conjuntos de datos, instale los lectores adecuados para su formato de origen.

Paso 2: Descargar datos en bruto

Descarga DROID de Google Cloud Storage usando gsutil:

# Install Google Cloud SDK if not already installed
# https://cloud.google.com/sdk/docs/install

# Download the full RLDS dataset (1.7TB)
gsutil -m cp -r gs://gresearch/robotics/droid/1.0.1 /your/data/

# Or download just the 100-episode sample (2GB) for testing
gsutil -m cp -r gs://gresearch/robotics/droid_100 /your/data/

Los conjuntos de datos grandes requieren tiempo y almacenamiento considerables:

  • DROID completo (1,7 TB): varios días para descargarlo, dependiendo del ancho de banda
  • Tiempo de procesamiento: más de 7 días para el porteo local del conjunto de datos completo
  • Tiempo de carga: más de 3 días para enviar a Hugging Face Hub
  • Almacenamiento local: ~400GB para el formato LeRobot procesado

Paso 3: Portar el Dataset

python examples/port_datasets/port_droid.py \
    --raw-dir /your/data/droid/1.0.1 \
    --repo-id your_id/droid_1.0.1 \
    --push-to-hub

Desarrollo y pruebas

Para el desarrollo, puedes portar un solo fragmento:

python examples/port_datasets/port_droid.py \
    --raw-dir /your/data/droid/1.0.1 \
    --repo-id your_id/droid_1.0.1_test \
    --num-shards 2048 \
    --shard-index 0

Este enfoque funciona para conjuntos de datos más pequeños o para pruebas, pero los conjuntos de datos grandes requieren computación en clúster.

Enfoque 2: Porting a un clúster SLURM (Recomendado)

Para conjuntos de datos grandes como DROID, el procesamiento paralelo en varios nodos reduce drásticamente el tiempo de procesamiento.

Paso 1: Instalar las dependencias del clúster

pip install datatrove  # Hugging Face's distributed processing library

Paso 2: Configure su entorno de SLURM

Encuentra la información de tu partición:

sinfo --format="%R"  # List available partitions
sinfo -N -p your_partition -h -o "%N cpus=%c mem=%m"  # Check resources

Elija una partición de CPU: no se necesita GPU para portar el conjunto de datos.

Paso 3: Iniciar trabajos de porting en paralelo

python examples/port_datasets/slurm_port_shards.py \
    --raw-dir /your/data/droid/1.0.1 \
    --repo-id your_id/droid_1.0.1 \
    --logs-dir /your/logs \
    --job-name port_droid \
    --partition your_partition \
    --workers 2048 \
    --cpus-per-task 8 \
    --mem-per-cpu 1950M

Directrices de parámetros

  • --workers: Número de trabajos en paralelo (máximo 2048 para el número de fragmentos de DROID)
  • --cpus-per-task: se recomiendan 8 CPUs para la paralelización de la codificación de fotogramas
  • --mem-per-cpu: ~16GB de RAM total (8×1950M) para cargar los fotogramas en bruto

Comience con menos workers (por ejemplo, 100) para probar la configuración de su clúster antes de lanzar miles de trabajos.

Paso 4: Monitorear el progreso

Comprobar los trabajos en ejecución:

squeue -u $USER

Monitorear el progreso general:

jobs_status /your/logs

Inspeccionar los registros de un trabajo individual:

less /your/logs/port_droid/slurm_jobs/JOB_ID_WORKER_ID.out

Depurar trabajos fallidos:

failed_logs /your/logs/port_droid

Paso 5: Agregar fragmentos

Una vez que todos los trabajos de porting se completan:

python examples/port_datasets/slurm_aggregate_shards.py \
    --repo-id your_id/droid_1.0.1 \
    --logs-dir /your/logs \
    --job-name aggr_droid \
    --partition your_partition \
    --workers 2048 \
    --cpus-per-task 8 \
    --mem-per-cpu 1950M

Paso 6: Subir al Hub

python examples/port_datasets/slurm_upload.py \
    --repo-id your_id/droid_1.0.1 \
    --logs-dir /your/logs \
    --job-name upload_droid \
    --partition your_partition \
    --workers 50 \
    --cpus-per-task 4 \
    --mem-per-cpu 1950M

Upload utiliza menos workers (50) ya que está limitado por la red y no por la capacidad de cálculo.

Estructura de archivos del Dataset v3.0

Tu conjunto de datos completado tendrá esta estructura moderna:

dataset/
├── meta/
│   ├── episodes/
│   │   └── chunk-000/
│   │       └── file-000.parquet    # Episode metadata
│   ├── tasks.parquet               # Task definitions
│   ├── stats.json                  # Aggregated statistics
│   └── info.json                   # Dataset information
├── data/
│   └── chunk-000/
│       └── file-000.parquet        # Consolidated episode data
└── videos/
    └── camera_key/
        └── chunk-000/
            └── file-000.mp4        # Consolidated video files

Esto reemplaza la antigua estructura de un episodio por archivo con bloques de tamaño óptimo y eficiente.

Migrar desde Dataset v2.1

Si tienes conjuntos de datos existentes en el formato v2.1, usa la herramienta de migración:

python src/lerobot/scripts/convert_dataset_v21_to_v30.py \
    --repo-id your_id/existing_dataset

Esto hace automáticamente:

  • Convierte la estructura de archivos al formato v3.0
  • Migra los metadatos de JSON Lines a parquet
  • Agrega estadísticas y crea estadísticas por episodio
  • Actualiza la información de la versión

Beneficios de rendimiento

Dataset v3.0 ofrece mejoras significativas para conjuntos de datos grandes:

  • Carga más rápida: reducción del 3 al 5 en el tiempo de inicialización
  • Eficiencia de memoria: Mejor uso de la RAM mediante el mapeo de memoria
  • Procesamiento escalable: maneja millones de episodios de manera eficiente
  • Optimización del almacenamiento: Reducción del número de archivos y mejora de la compresión
Update on GitHub