GR00T 系列 1 - 机器人数据准备指南
机器人数据准备指南
概览
本指南展示如何将自己的机器人数据转换为 GR00T 版本的 LeRobot 数据集 V2 格式(LeRobot 文档)- GR00T LeRobot。虽然 GR00T 引入额外结构,但 Schema 仍与上游 LeRobot V2 保持完全兼容。额外的元数据及结构允许对机器人数据进行更详细的规格说明和语言标注。
简而言之:向 LeRobot V2 数据集中添加 meta/modality.json 文件,并且遵循下面的 Schema。LeRobot V2 要求
如果已有 LeRobot V2 格式的数据集,可以跳过本节。
如果数据集采用 LeRobot V3.0 格式,请使用该脚本将其转换为 LeRobot V2 格式。
为什么使用 LeRobot V2?GR00T 目前使用 LeRobot V2 数据格式,因为许多上游数据集(DROID、LIBERO、Bridge 等)都是以 V2 格式发布的。GR00T 计划在未来版本中原生支持 V2 和 V3 两种格式。目前,请使用上面的脚本将 V3 数据集转换为 V2。
如果数据集采用其他格式,请将其转换为满足以下要求的 LeRobot V2 格式。
结构要求
文件夹应遵循类似下面的结构,并且包含以下核心文件夹和文件:
.
├─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-*)
videos 文件夹将包含与每个 Episode 关联的 MP4 文件,遵循 episode_00000X.mp4 命名格式,其中 X 表示 Episode 编号。
要求:
- 必须存储为 MP4 文件。
- 应使用以下格式命名:
observation.images.<video_name>
数据(data/chunk-*)
data 文件夹将包含与每个 Episode 关联的所有 Parquet 文件,遵循 episode_00000X.parquet 命名格式,其中 X 表示 Episode 编号。
每个 Parquet 文件将包含:
- 状态信息:存储为
observation.state,它是所有状态模态的一维拼接数组。
- 动作:存储为
action,它是所有动作模态的一维拼接数组。
- 时间戳:存储为
timestamp,它是起始时间的浮点数。
- 标注:存储为
annotation.<annotation_source>.<annotation_type>(.<annotation_name>)(示例命名请参见示例配置中的annotation字段)。其他列不应带有annotation前缀;如果想添加多个标注,请参见(multiple-annotation-support)。
Parquet 文件示例
下面是 demo_data/cube_to_bowl_5/ 目录下的 cube_to_bowl 数据集的示例。
{
"observation.state":[-0.01,...,0], // 一维数组:所有状态模态按 modality.json 顺序拼接
"action":[-0.010,...,0], // 一维数组:所有动作模态按 modality.json 顺序拼接
"timestamp":0.049, // 浮点数:本观测的挂钟时间(秒)
"annotation.human.action.task_description":0, // 整数:meta/tasks.jsonl 中语言指令的索引
"task_index":0, // 整数:任务标识符(对于单任务,与标注索引相同)
"annotation.human.validity":1, // 整数:meta/tasks.jsonl 中有效性标签的索引
"episode_index":0, // 整数:本帧属于哪个 Episode
"index":0, // 整数:跨数据集中所有 Episode 的全局帧索引
"next.reward":0, // 浮点数:下一时间步的奖励(如果未使用则为 0)
"next.done":false // 布尔值:如果这是 Episode 的最后一帧则为真
}元数据
episodes.jsonl包含整个数据集中所有 Episode 的列表。每个 Episode 包含任务列表和 Episode 长度。
tasks.jsonl包含整个数据集中所有任务的列表。
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.jsonl 包含整个数据集中所有任务的列表。
meta/episodes.jsonl
下面是包含 Episode 信息的 meta/episodes.jsonl 文件示例。
{"episode_index": 0, "tasks": [...], "length": 416}
{"episode_index": 1, "tasks": [...], "length": 470}episodes.jsonl 包含整个数据集中所有 Episode 的列表。每个 Episode 包含任务列表和 Episode 长度。
GR00T LeRobot 特定要求
meta/modality.json 配置
GR00T 需要标准 LeRobot 格式中不存在的额外元数据文件 meta/modality.json。该文件提供关于状态和动作模态的详细元数据,从而支持:
- 分离的数据存储与解释:
- 状态和动作: 存储为拼接的 Float32 数组。
modality.json文件提供将上述数组解释为不同的细粒度字段所必需的元数据。
- 视频: 存储为单独文件,配置文件允许将它们重命名为标准化格式。
- 标注: 跟踪所有标注字段。如果没有标注,请不要在配置文件中包含
annotation字段。
- 状态和动作: 存储为拼接的 Float32 数组。
- 细粒度拆分: 将状态和动作数组划分为语义上更有意义的字段。
- 清晰映射: 数据维度的显式映射。
- 复杂的数据变换: 支持在训练期间进行字段级别的归一化及旋转变换。
Schema
{
"state": {
"<state_key>": {
"start": <int>, // 状态数组中的起始索引
"end": <int> // 状态数组中的结束索引
}
},
"action": {
"<action_key>": {
"start": <int>, // 动作数组中的起始索引
"end": <int> // 动作数组中的结束索引
}
},
"video": {
"<new_key>": {
"original_key": "<original_video_key>"
}
},
"annotation": {
"<annotation_key>": {} // 空字典,用于与其他模态保持一致
}
}示例
关于 modality.json 和完整数据集结构的具体示例,请参见 HuggingFace 上公开可用的数据集:
也可以在随附 Demo 数据中找到可用示例。
备注
- 所有索引都从零开始,并且遵循 Python 的数组切片约定(
[start:end])。
GR00T LeRobot 对标准 LeRobot 的扩展
GR00T LeRobot 是标准 LeRobot 格式的变体,带有更多明确要求:
- GR00T 将为每个数据集计算
meta/stats.json和meta/relative_stats.json,并且将它们存储在meta文件夹中。
- 本体感受状态必须始终包含在
observation.state键中。
- GR00T 支持多通道标注格式(比如 coarsegrained、finetuned),允许通过
annotation.<annotation_source>.<annotation_type>键按需添加任意数量的标注通道。
- GR00T 需要标准 LeRobot 格式中不存在的额外元数据文件
meta/modality.json。
多标注支持
为在单个 Parquet 文件中支持多个标注,用户可向 Parquet 文件添加额外列。用户应像处理原始 LeRobot V2 数据集中的 task_index 列一样处理这些列:
在 LeRobot V2 中,实际的语言描述存储在 meta/tasks.jsonl 文件的行中,而 Parquet 文件只在 task_index 列中存储对应的索引。GR00T 遵循相同约定,在 annotation.<annotation_source>.<annotation_type> 列中为每个标注存储对应的索引。虽然 task_index 列仍可用于默认标注,但仍需要专用列 annotation.<annotation_source>.<annotation_type>,以确保 GR00T 自定义数据加载器可以加载它。