Руководство по преобразованию данных роботов
Обзор
Это руководство показывает, как преобразовать данные роботов в формат LeRobot Dataset V2.0, который мы называем GR00T LeRobot. Мы добавили дополнительную структуру, но наша схема полностью совместима с исходным LeRobot 2.0. Эти дополнительные метаданные и структура позволяют точнее описывать данные роботов и добавлять языковую разметку.
Требования
Основные требования
Папка должна иметь структуру, похожую на приведённую ниже, и содержать эти основные папки и файлы:
.
├─meta
│ ├─episodes.jsonl
│ ├─modality.json # -> специфично для GR00T LeRobot
│ ├─info.json
│ └─tasks.jsonl
├─videos
│ └─chunk-000
│ └─observation.images.ego_view
│ └─episode_000001.mp4
│ └─episode_000000.mp4
└─data
└─chunk-000
├─episode_000001.parquet
└─episode_000000.parquet
Видеонаблюдения (video/chunk-*)
Папка видео содержит mp4-файлы, относящиеся к каждому эпизоду; их имена имеют вид episode_00000X.mp4, где X — номер эпизода. Требования:
- Файлы должны храниться в формате MP4.
- Имена должны следовать формату
observation.images.<video_name>.
Данные (data/chunk-*)
Папка данных содержит все parquet-файлы, относящиеся к каждому эпизоду; их имена имеют вид episode_00000X.parquet, где X — номер эпизода. Каждый parquet-файл содержит:
- состояние: хранится в столбце
observation.state; это одномерный массив, объединяющий все модальности состояния; - действия: хранятся в столбце
action; это одномерный массив, объединяющий все модальности действий; - временную метку: хранится в столбце
timestamp; это число с плавающей точкой, задающее время начала; - аннотации: хранятся в столбце
annotation.<annotation_source>.<annotation_type>(.<annotation_name>)(примеры именования см. в полях аннотаций в примерной конфигурации). Прочие столбцы не должны использовать префикс annotation; если нужно добавить несколько аннотаций, см. раздел (multiple-annotation-support).
Пример parquet-файла
Ниже пример набора robot_sim.PickNPlace, который находится в каталоге [demo_data (demo_data/robot_sim.PickNPlace/).
{
"observation.state":[-0.01147082911843003,...,0], // массив объединённых состояний по файлу modality.json
"action":[-0.010770668025204974,...0], // массив объединённых действий по файлу modality.json
"timestamp":0.04999995231628418, // временная метка наблюдения
"annotation.human.action.task_description":0, // индекс описания задачи в файле meta/tasks.jsonl
"task_index":0, // индекс задачи в файле meta/tasks.jsonl
"annotation.human.validity":1, // индекс задачи в файле meta/tasks.jsonl
"episode_index":0, // индекс эпизода
"index":0, // индекс наблюдения. Это глобальный индекс всех наблюдений во всём наборе данных.
"next.reward":0, // награда за следующее наблюдение
"next.done":false // завершён ли эпизод
}
Метаданные
episodes.jsonlсодержит список всех эпизодов набора данных. Для каждого эпизода указаны последовательность задач и длина эпизода.tasks.jsonlсодержит список всех задач набора данных.modality.jsonсодержит конфигурацию модальностей.info.jsonсодержит сведения о наборе данных.
meta/tasks.jsonl
Ниже пример файла meta/tasks.jsonl с описаниями задач.
{"task_index": 0, "task": "pick the squash from the counter and place it in the plate"}
{"task_index": 1, "task": "valid"}
Индекс задачи в parquet-файле можно использовать, чтобы получить описание задачи. Так, для первого наблюдения в этом примере annotation.human.action.task_description — это «pick the squash from the counter and place it in the plate», а annotation.human.validity — «valid».
Файл tasks.json содержит список всех задач набора данных.
meta/episodes.jsonl
Ниже пример файла meta/episodes.jsonl с информацией об эпизодах.
{"episode_index": 0, "tasks": [...], "length": 416}
{"episode_index": 1, "tasks": [...], "length": 470}
episodes.json содержит список всех эпизодов набора данных. Для каждого эпизода указаны последовательность задач и длина эпизода.
Конфигурация meta/modality.json
Этот файл содержит подробные метаданные о модальностях состояния и действий, что позволяет:
- Разделять хранение и интерпретацию данных:
- Состояние и действия хранятся как объединённые массивы float32. Файл
modality.jsonсодержит метаданные, которые нужны, чтобы разбить эти массивы на различные мелкие поля с дополнительной информацией для обучения. - Видео хранятся в отдельных файлах; конфигурация позволяет переименовать их в стандартный формат.
- Аннотации: отслеживаются все поля аннотаций. Если аннотаций нет, не включайте поле
annotationв конфигурационный файл.
- Состояние и действия хранятся как объединённые массивы float32. Файл
- Детальное разбиение: массивы состояний и действий делятся на более осмысленные по смыслу поля.
- Явное соответствие: однозначное соответствие размерностей данных.
- Сложные преобразования данных: во время обучения поддерживаются нормализация и поворот для отдельных полей.
Схема
{
"state": {
"<state_key>": {
"start": <int>, // начальный индекс в массиве состояния
"end": <int>, // конечный индекс в массиве состояния
"rotation_type": <str>, // необязательно: формат поворота
"dtype": <str>, // необязательно: тип данных
"range": <tuple[float, float]>, // необязательно: диапазон модальности
}
},
"action": {
"<action_key>": {
"start": <int>, // начальный индекс в массиве действий
"end": <int>, // конечный индекс в массиве действий
"absolute": <bool>, // необязательно: true — абсолютное значение, false — относительное / приращение
"rotation_type": <str>, // необязательно: формат поворота
"dtype": <str>, // необязательно: тип данных
"range": <tuple[float, float]>, // необязательно: диапазон модальности
}
},
"video": {
"<new_key>": {
"original_key": "<original_video_key>"
}
},
"annotation": {
"<annotation_key>": {} // пустой словарь для единообразия с другими модальностями
}
}
Поддерживаемые типы поворота:
axis_anglequaternionrotation_6dmatrixeuler_angles_rpyeuler_angles_rypeuler_angles_pryeuler_angles_pyreuler_angles_yrpeuler_angles_ypr
Пример конфигурации
{
"state": {
"left_arm": { // первые 7 элементов массива observation.state в parquet-файле — левая рука
"start": 0,
"end": 7
},
"left_hand": { // следующие 6 элементов — левая кисть
"start": 7,
"end": 13
},
"left_leg": {
"start": 13,
"end": 19
},
"neck": {
"start": 19,
"end": 22
},
"right_arm": {
"start": 22,
"end": 29
},
"right_hand": {
"start": 29,
"end": 35
},
"right_leg": {
"start": 35,
"end": 41
},
"waist": {
"start": 41,
"end": 44
}
},
"action": {
"left_arm": {
"start": 0,
"end": 7
},
"left_hand": {
"start": 7,
"end": 13
},
"left_leg": {
"start": 13,
"end": 19
},
"neck": {
"start": 19,
"end": 22
},
"right_arm": {
"start": 22,
"end": 29
},
"right_hand": {
"start": 29,
"end": 35
},
"right_leg": {
"start": 35,
"end": 41
},
"waist": {
"start": 41,
"end": 44
}
},
"video": {
"ego_view": { // видео хранится в videos/chunk-*/observation.images.ego_view/episode_00000X.mp4
"original_key": "observation.images.ego_view"
}
},
"annotation": {
"human.action.task_description": {}, // описание задачи хранится в файле meta/tasks.jsonl
"human.validity": {}
}
}
Поддержка нескольких аннотаций
Чтобы в одном parquet-файле было несколько аннотаций, пользователь добавляет дополнительные столбцы. Эти столбцы нужно обрабатывать так же, как столбец task_index в исходном наборе LeRobot V2:
В LeRobot V2 фактические языковые описания хранятся по строкам в файле meta/tasks.jsonl, а parquet-файл содержит только соответствующие индексы в столбце task_index. Мы следуем тому же соглашению: для каждой аннотации в столбце annotation.<annotation_source>.<annotation_type> хранится соответствующий индекс. Столбец task_index по-прежнему можно использовать для аннотации по умолчанию, однако для загрузки нашим собственным загрузчиком данных нужен отдельный столбец annotation.<annotation_source>.<annotation_type>.
Расширения GR00T LeRobot относительно стандартного LeRobot
GR00T LeRobot — вариант стандартного формата LeRobot с дополнительными фиксированными требованиями:
- Стандартный формат LeRobot использует meta/stats.json, но наш загрузчик данных его не требует. Если его вычисление слишком долгое, этот файл можно безопасно пропустить.
- В ключе
observation.stateвсегда должно присутствовать проприоцептивное состояние. - Мы поддерживаем многоуровневый формат аннотаций (например, грубый и тонкий), что позволяет добавлять любое число каналов аннотаций через ключи
annotation.<annotation_source>.<annotation_type>. - Нам нужен дополнительный файл метаданных
meta/modality.json, которого нет в стандартном формате LeRobot.
Примечания
- Указывайте необязательные поля только тогда, когда их значение отличается от значения по умолчанию.
- Сопоставление ключей видео стандартизирует имена камер во всём наборе данных.
- Все индексы начинаются с нуля и следуют соглашению Python для срезов массивов (
[start:end]).
Пример
Полный пример см. в [примерном наборе данных (demo_data/robot_sim.PickNPlace/).