LeRobot documentation

Портинг больших датасетов в LeRobot Dataset v3.0

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Портинг больших датасетов в LeRobot Dataset v3.0

В этом руководстве объясняется, как перенести крупные робототехнические датасеты в формат LeRobot Dataset v3.0. В качестве основного примера мы будем использовать датасет DROID 1.0.1, который демонстрирует работу с наборами данных объёмом в несколько терабайт, содержащими тысячи шардов на кластерах SLURM.

Организация файлов: v2.1 и v3.0

Dataset v3.0 принципиально меняет способ организации и хранения данных:

Структура v2.1 (на основе эпизодов):

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

Структура v3.0 (на основе файлов):

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

Такой переход от отдельных файлов эпизодов к файловым чанкам значительно повышает производительность и снижает накладные расходы на хранение.

Что нового в Dataset v3.0

Dataset v3.0 вносит значительные улучшения для работы с большими наборами данных:

🏗️ Улучшенная организация файлов

  • Файловая структура: эпизоды теперь сгруппированы в файлы с чанками, а не в отдельные файлы эпизодов
  • Настраиваемые размеры файлов: для файлов данных и видео
  • Повышенная эффективность хранения: лучшее сжатие и снижение накладных расходов

📊 Современное управление метаданными

  • Метаданные на основе Parquet: JSON Lines заменён на эффективный формат parquet
  • Структурированный доступ к эпизодам: прямой доступ к pandas DataFrame через dataset.meta.episodes
  • Статистика по эпизодам: улучшенный учёт статистики на уровне эпизода

🚀 Улучшения производительности

  • Доступ с отображением в память: улучшенное использование ОЗУ за счёт отображения памяти PyArrow
  • Более быстрая загрузка: значительное сокращение времени инициализации набора данных
  • Повышенная масштабируемость: Разработано для наборов данных с миллионами эпизодов

Предварительные требования

Перед переносом больших наборов данных убедитесь, что у вас есть:

  • LeRobot установлен с поддержкой v3.0. Следуйте нашему Руководству по установке.
  • Достаточный объём хранилища: исходные наборы данных могут быть очень большими (например, DROID требует 2 ТБ)
  • Доступ к кластеру (рекомендуется для больших наборов данных): SLURM или аналогичный планировщик заданий
  • Зависимости, специфичные для набора данных: для DROID вам понадобятся утилиты TensorFlow Dataset

Понимание набора данных DROID

DROID 1.0.1 — отличный пример крупномасштабного набора данных для робототехники:

  • Размер: 1,7 ТБ (формат RLDS), 8,7 ТБ (исходные данные)
  • Структура: 2048 заранее определённых фрагментов набора данных TensorFlow
  • Содержание: более 76 000 траекторий манипуляций роботов Franka Emika Panda
  • Область применения: задачи манипуляции в реальных условиях в нескольких средах и с различными объектами
  • Формат: изначально в формате TensorFlow Records/RLDS, требуется конвертация в формат LeRobot
  • Хостинг: Google Cloud Storage с публичным доступом через gsutil

Набор данных содержит разнообразные демонстрации манипуляций с:

  • Несколько видов с камер (камера на запястье, внешние камеры)
  • Описания задач обработки естественного языка
  • Собственная чувствительность и действия робота
  • Аннотации об успехе/неудаче

Схема функций 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
}

Подход 1: Перенос на один компьютер

Шаг 1: Установка зависимостей

В частности, для DROID:

pip install tensorflow
pip install tensorflow_datasets

Для других наборов данных установите соответствующие модули чтения для вашего исходного формата.

Шаг 2: Загрузка исходных данных

Скачайте DROID из Google Cloud Storage с помощью 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/

Большие наборы данных требуют значительного времени и места для хранения:

  • Полный DROID (1,7 ТБ): несколько дней на загрузку в зависимости от пропускной способности
  • Время обработки: более 7 дней для локального переноса полного набора данных
  • Время загрузки: более 3 дней для отправки в Hugging Face Hub
  • Локальное хранилище: ~400 ГБ для обработанного формата LeRobot

Шаг 3: Перенос набора данных

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

Разработка и тестирование

Для разработки можно перенести один шард:

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

Этот подход подходит для небольших наборов данных или тестирования, но для больших наборов данных требуется кластерное вычисление.

Подход 2: перенос на кластер SLURM (рекомендуется)

Для больших наборов данных, таких как DROID, параллельная обработка на нескольких узлах значительно сокращает время обработки.

Шаг 1: Установка зависимостей кластера

pip install datatrove  # Hugging Face's distributed processing library

Шаг 2: Настройка окружения SLURM

Найдите информацию о вашем разделе:

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

Выберите CPU partition — для переноса набора данных GPU не требуется.

Шаг 3: Запуск параллельных задач переноса

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

Рекомендации по параметрам

  • --workers: количество параллельных задач (максимум 2048 для количества шардов DROID)
  • --cpus-per-task: рекомендуется 8 ЦП для параллельного кодирования кадров
  • --mem-per-cpu: ~16 ГБ общей оперативной памяти (8×1950M) для загрузки необработанных кадров

Начните с меньшего количества воркеров (например, 100), чтобы протестировать конфигурацию кластера перед запуском тысяч задач.

Шаг 4: Отслеживание прогресса

Проверка запущенных задач:

squeue -u $USER

Контроль общего прогресса:

jobs_status /your/logs

Просмотреть логи отдельных заданий:

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

Отладка неудачных заданий:

failed_logs /your/logs/port_droid

Шаг 5: Агрегация шардов

После завершения всех задач по переносу:

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

Шаг 6: Загрузка в 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

Загрузка использует меньше рабочих процессов (50), так как она ограничена сетью, а не вычислительными мощностями.

Структура файлов Dataset v3.0

Ваш готовый набор данных будет иметь следующую современную структуру:

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

Это заменяет старую структуру «один эпизод на файл» эффективными блоками оптимального размера.

Переход с Dataset v2.1

Если у вас есть существующие наборы данных в формате v2.1, используйте инструмент миграции:

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

Это автоматически:

  • Преобразует структуру файлов в формат v3.0
  • Перенос метаданных из JSON Lines в parquet
  • Собирает статистику и создаёт статистику по эпизодам
  • Обновление информации о версии

Преимущества производительности

Dataset v3.0 обеспечивает значительные улучшения для больших наборов данных:

  • Более быстрая загрузка: сокращение времени инициализации в 3–5 раз
  • Эффективность использования памяти: лучшее использование ОЗУ за счёт отображения памяти
  • Масштабируемая обработка: Эффективно обрабатывает миллионы эпизодов
  • Оптимизация хранилища: уменьшено количество файлов и улучшено сжатие
Update on GitHub