NVIDIA Isaac GR00T N1:世界首个开源通用人形机器人基础模型
NVIDIA Isaac GR00T N1:世界首个开源通用人形机器人基础模型
NVIDIA最近发布了一个重磅开源项目——Isaac GR00T N1,这是世界上第一个开源的通用人形机器人推理和技能基础模型。本文将详细介绍这个革命性项目的背景、架构、部署方法以及使用流程,帮助研究人员和开发者快速上手这一强大工具。
项目概述
NVIDIA Isaac GR00T N1是一个跨实施模型,可以接收多模态输入(包括语言和图像),用于在各种环境中执行操作任务。该模型基于广泛的人形数据集进行训练,这些数据集包括真实捕获的数据、使用NVIDIA Isaac GR00T Blueprint组件生成的合成数据以及互联网规模的视频数据。
GR00T N1的特点在于它可以通过后期训练适应特定的实施方式、任务和环境。这意味着研究人员可以将这个基础模型应用到各种不同的机器人平台上,并针对特定任务进行微调,大大降低了开发复杂机器人应用的门槛。
技术架构
GR00T N1的神经网络架构是视觉-语言基础模型和扩散变换器头的组合,用于去噪连续动作。下图展示了该架构的示意图:
从上图可以看出,整个系统分为几个关键部分:
- 输入处理:包括图像观察、语言指令和机器人状态的编码
- 视觉-语言模型:处理多模态输入并生成统一表示
- 扩散变换器:将表示转换为连续的机器人动作
这种架构设计使GR00T N1能够理解复杂的视觉场景和语言指令,并将其转化为精确的机器人动作序列。
目标用户
GR00T N1主要面向人形机器人领域的研究人员和专业人士。该项目提供了一系列工具,使用户能够:
- 利用预训练的基础模型进行机器人控制
- 在小型、自定义数据集上进行微调
- 使用最少的数据将模型适应特定的机器人任务
- 部署模型进行推理
项目的重点是通过微调实现机器人行为的定制化,这使得即使是资源有限的研究团队也能快速开发出复杂的机器人应用。
环境要求
在开始使用GR00T N1之前,请确保您的系统满足以下要求:
- 操作系统:Ubuntu 20.04或22.04
- 微调硬件:H100、L40、A4090或A6000 GPU
- 推理硬件:4090、A6000 GPU
- Python版本:3.10
- CUDA版本:12.4
- 系统依赖:ffmpeg、libsm6、libxext6
请注意,CUDA版本必须是12.4,否则在配置flash-attn模块时可能会遇到困难。
安装指南
1. 克隆代码库
首先,克隆GitHub代码库并进入项目目录:
git clone https://github.com/NVIDIA/Isaac-GR00T
cd Isaac-GR00T
2. 创建Conda环境并安装依赖
创建一个新的Conda环境并安装所需的依赖项:
conda create -n gr00t python=3.10
conda activate gr00t
pip install --upgrade setuptools
pip install -e .
pip install --no-build-isolation flash-attn==2.7.1.post4
使用流程
使用GR00T N1的一般流程如下:
- 收集机器人演示数据,形式为(视频、状态、动作)三元组
- 将演示数据转换为LeRobot兼容的数据模式
- 使用提供的配置为不同的机器人实施进行训练
- 使用提供的脚本在用户数据上微调预训练的GR00T N1模型,并运行推理
- 将
Gr00tPolicy
连接到机器人控制器,在目标硬件上执行动作
数据加载指南
在使用GR00T N1之前,您需要了解如何加载和处理数据。以下内容基于0_load_dataset.ipynb
教程。
LeRobot格式
GR00T N1使用LeRobot格式加载数据。本教程将展示如何使用数据加载器加载LeRobot格式的数据。
- 我们将使用
robot_sim.PickNPlace
数据集作为示例,该数据集已经转换为LeRobot格式。 - 要了解如何转换您自己的数据集,请参考下面的数据格式部分。
加载数据集的三个关键要素
要加载数据集,我们需要定义三个关键要素:
- 数据集路径:指向数据集的路径
- 模态配置:定义要使用的数据模态(如视频、状态、动作等)
- 转换配置:定义在数据加载过程中应用的转换
from gr00t.data.dataset import LeRobotSingleDataset
from gr00t.data.embodiment_tags import EmbodimentTag
from gr00t.data.dataset import ModalityConfig
from gr00t.experiment.data_config import DATA_CONFIG_MAP
# 获取数据配置
data_config = DATA_CONFIG_MAP["gr1_arms_only"]
# 获取模态配置和转换
modality_config = data_config.modality_config()
transforms = data_config.transform()
# 这是一个LeRobotSingleDataset对象,从给定的数据集路径加载数据
dataset = LeRobotSingleDataset(
dataset_path="demo_data/robot_sim.PickNPlace",
modality_configs=modality_config,
transforms=transforms,
embodiment_tag=EmbodimentTag.GR1, # 要使用的实施
)
# 这是访问数据的示例
dataset[5]
加载数据集后,您可以访问其中的样本,每个样本包含视频、状态和动作等信息。
数据格式详解
GR00T N1使用LeRobot兼容数据格式,但添加了更详细的元数据和注释模式。以下内容基于LeRobot_compatible_data_schema.md
文档。
数据目录结构
数据集应遵循以下目录结构:
.
├─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
核心文件说明
- videos目录:包含每个场景的MP4视频文件,命名格式为
episode_00000X.mp4
,其中X表示场景编号。 - data目录:包含每个场景的parquet文件,存储状态信息、动作和时间戳等。
- meta/episodes.jsonl:包含整个数据集中所有场景的列表,每个场景包含任务列表和场景长度。
- meta/tasks.jsonl:包含整个数据集中所有任务的列表。
- meta/modality.json:包含模态配置,定义了状态和动作数组的结构。
- meta/info.json:包含数据集信息。
modality.json配置详解
这个文件提供了关于状态和动作模态的详细元数据,使得:
- 数据存储与解释分离:状态和动作存储为连接的float32数组,modality.json提供了将这些数组解释为不同字段的元数据。
- 细粒度拆分:将状态和动作数组分解为更有语义意义的字段。
- 明确映射:数据维度的显式映射。
- 复杂数据转换:支持训练期间的字段特定归一化和旋转转换。
配置文件格式示例:
{
"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>": {} // 空字典,与其他模态保持一致
}
}
模型推理
一旦您的数据准备就绪,您可以使用GR00T N1模型进行推理。以下内容基于1_gr00t_inference.ipynb
教程。
加载预训练模型
GR00T N1模型托管在Huggingface上,您可以使用以下代码加载预训练模型:
from gr00t.model.policy import Gr00tPolicy
from gr00t.data.embodiment_tags import EmbodimentTag
# 1. 加载模态配置和转换,或使用上面的配置
modality_config = ComposedModalityConfig(...)
transforms = ComposedModalityTransform(...)
# 2. 加载数据集
dataset = LeRobotSingleDataset(.....<与上面的加载部分类似>....)
# 3. 加载预训练模型
policy = Gr00tPolicy(
model_path="nvidia/GR00T-N1-2B",
modality_config=modality_config,
modality_transform=transforms,
embodiment_tag=EmbodimentTag.GR1,
device="cuda"
)
# 4. 运行推理
action_chunk = policy.get_action(dataset[0])
推理服务
您还可以使用提供的脚本运行推理服务,该服务可以在服务器模式或客户端模式下运行:
# 服务器模式
python scripts/inference_service.py --model_path nvidia/GR00T-N1-2B --server
# 在不同的终端中,运行客户端模式向服务器发送请求
python scripts/inference_service.py --client
模型微调
GR00T N1支持在自定义数据集上进行微调,以适应特定的机器人和任务。以下内容基于2_finetuning.ipynb
和3_new_embodiment_finetuning.ipynb
教程。
基本微调
您可以使用以下脚本在示例数据集上微调模型:
# 首先运行--help查看可用参数
python scripts/gr00t_finetune.py --help
# 然后运行脚本
python scripts/gr00t_finetune.py --dataset-path ./demo_data/robot_sim.PickNPlace --num-gpus 1
下载示例数据集
您可以从Huggingface下载示例数据集:
huggingface-cli download nvidia/PhysicalAI-Robotics-GR00T-X-Embodiment-Sim \
--repo-type dataset \
--include "gr1_arms_only.CanSort/**" \
--local-dir $HOME/gr00t_dataset
新实施微调
如果您有一个新的机器人实施,您可以使用3_new_embodiment_finetuning.ipynb
中的方法进行微调。这涉及到:
- 准备您的数据集,确保它遵循LeRobot兼容格式
- 使用
EmbodimentTag.NEW_EMBODIMENT
标签加载数据集 - 配置微调参数,特别是针对新实施的参数
- 运行微调脚本,指定适当的参数
硬件性能考虑
- 微调性能:最佳微调使用1个H100节点或L40节点。其他硬件配置(如A6000、RTX4090)也可以工作,但可能需要更长时间才能收敛。确切的批量大小取决于硬件和模型的哪个组件正在调整。
- 推理性能:对于实时推理,大多数现代GPU在处理单个样本时性能相似。基准测试显示L40和RTX 4090之间的推理速度差异很小。
推荐的微调配置是将批量大小提升到最大,并训练20k步。
高级理解
以下内容基于4_deeper_understanding.md
文档,提供了关于GR00T N1更深入的技术细节。
实施动作头微调
GR00T设计为通过专门的动作头与不同类型的机器人(实施)一起工作。在微调时,您需要根据数据集指定要训练的实施头:
-
实施标签
- 每个数据集在实例化
LeRobotSingleDataset
类时必须标记特定的EmbodimentTag
(例如,EmbodimentTag.GR1_UNIFIED) - 实施标签的详尽列表可以在
gr00t/data/embodiment_tags.py
中找到 - 此标签确定将微调哪个动作头
- 如果您有新的实施,可以使用
EmbodimentTag.NEW_EMBODIMENT
标签(例如,new_embodiment.your_custom_dataset
)
- 每个数据集在实例化
-
工作原理
- 当您使用特定的实施标签(例如,
EmbodimentTag.GR1_UNIFIED
)加载数据集时 - 模型有多个可以配置用于微调的组件(视觉编码器、语言模型、DiT等)
- 对于动作头,只有与指定实施标签对应的动作头会被微调。其他特定于实施的动作头保持冻结
- 当您使用特定的实施标签(例如,
高级调整参数
模型有几个可以独立微调的组件。您可以在GR00T_N1.from_pretrained
函数中配置这些参数:
-
视觉编码器(
tune_visual
)- 如果您的数据在视觉上与预训练数据有不同的特征,则设置为
true
- 注意:这在计算上很昂贵
- 默认值:false
- 如果您的数据在视觉上与预训练数据有不同的特征,则设置为
-
语言模型(
tune_llm
)- 仅当您有与标准指令非常不同的特定领域语言时,才设置为
true
- 在大多数情况下,这应该是
false
- 默认值:false
- 仅当您有与标准指令非常不同的特定领域语言时,才设置为
-
投影器(
tune_projector
)- 默认情况下,投影器会被调整
- 这有助于对齐特定于实施的动作和状态空间
-
扩散模型(
tune_diffusion_model
)- 默认情况下,扩散模型不会被调整
- 这是所有实施投影器共享的动作头
数据转换理解
数据处理管道中使用了四种主要类型的转换:
-
视频转换:应用于视频数据,准备用于模型训练。包括:
- VideoToTensor:将视频数据从原始格式转换为PyTorch张量
- VideoCrop:裁剪视频帧,使用随机模式下的0.95比例因子引入轻微变化
- VideoResize:使用线性插值将视频帧调整为标准大小(224x224像素)
- VideoColorJitter:通过随机调整亮度(±0.3)、对比度(±0.4)、饱和度(±0.5)和色调(±0.08)应用颜色增强
- VideoToNumpy:将处理后的张量转换回NumPy数组以进行进一步处理
-
状态转换:处理机器人状态信息:
- StateActionToTensor:将状态数据(如手臂位置、手部配置)转换为PyTorch张量
- StateActionTransform:对状态数据应用归一化
-
动作转换:处理机器人动作数据:
- StateActionToTensor:与状态转换类似,将动作数据转换为PyTorch张量
- StateActionTransform:对动作数据应用归一化
-
连接转换:将处理后的数据组合成统一数组:
- 根据指定的视频模态键顺序连接视频数据
- 根据指定的状态模态键顺序连接状态数据
- 根据指定的动作模态键顺序连接动作数据
策略部署
以下内容基于5_policy_deployment.md
文档,提供了关于如何部署训练好的策略的指南。
注意:本教程要求用户拥有训练好的模型检查点和物理So100 Lerobot机器人来运行策略。
启动策略服务器
运行以下命令启动策略服务器:
python scripts/inference_service.py --server \
--model_path <PATH_TO_YOUR_CHECKPOINT> \
--embodiment_tag new_embodiment \
--data_config so100 \
--denoising_steps 4
- model_path:策略使用的检查点路径,用户应提供微调后的检查点路径
- denoising_steps:策略使用的去噪步骤数,我们注意到使用4个去噪步骤与16个相当
- embodiment_tag:策略使用的实施标签,在对新机器人进行微调时,用户应使用new_embodiment
- data_config:策略使用的数据配置。用户应使用
so100
。如果要使用不同的机器人,请实现自己的ModalityConfig
和TransformConfig
客户端实现
客户端节点可以使用from gr00t.eval.service import ExternalRobotInferenceClient
类实现。这个类是一个独立的客户端-服务器类,可用于与策略服务器通信,get_action()
端点是唯一的接口:
from gr00t.eval.service import ExternalRobotInferenceClient
from typing import Dict, Any
raw_obs_dict: Dict[str, Any] = {} # 填写空白
policy = ExternalRobotInferenceClient(host="localhost", port=5555)
raw_action_chunk: Dict[str, Any] = policy.get_action(raw_obs_dict)
用户可以复制该类并在单独的隔离环境中实现自己的客户端节点。
So100 Lerobot手臂示例
我们为So100 Lerobot手臂提供了一个示例客户端节点实现。有关更多详细信息,请参考示例脚本scripts/eval_gr00t_so100.py
。
用户可以运行以下命令启动客户端节点:
python examples/eval_gr00t_so100.py \
--use_policy --host <YOUR_POLICY_SERVER_HOST> \
--port <YOUR_POLICY_SERVER_PORT> \
--camera_index <YOUR_CAMERA_INDEX>
这将激活机器人,并调用策略服务器的action = get_action(obs)
端点获取动作,然后在机器人上执行动作。
模型评估
要对模型进行离线评估,项目提供了一个脚本,该脚本评估模型在数据集上的表现并绘制结果:
# 运行新训练的模型
python scripts/inference_service.py --server \
--model_path <MODEL_PATH> \
--embodiment_tag new_embodiment
# 运行离线评估脚本
python scripts/eval_policy.py --plot \
--dataset_path <DATASET_PATH> \
--embodiment_tag new_embodiment
您将看到真实值与预测动作的对比图,以及动作的未归一化MSE。这将让您了解策略在数据集上的表现如何。
常见问题解答
我有自己的数据,下一步应该做什么来进行微调?
本项目假设您的数据已经按照LeRobot格式组织。请参考getting_started/LeRobot_compatible_data_schema.md
了解如何组织数据。
什么是模态配置、实施标签和转换配置?
- 实施标签:定义使用的机器人实施,非预训练的实施标签被视为新的实施标签。
- 模态配置:定义数据集中使用的模态(例如视频、状态、动作)。
- 转换配置:定义在数据加载期间应用于数据的数据转换。
更多详细信息,请参阅getting_started/4_deeper_understanding.md
。
Gr00tPolicy的推理速度如何?
根据硬件的不同,推理速度会有所变化,但在现代GPU上,单个样本的推理速度通常足够快,可以满足实时控制需求。
总结
NVIDIA Isaac GR00T N1是一个突破性的开源项目,为人形机器人研究和开发提供了强大的基础模型。通过提供预训练模型和简化的微调流程,它使研究人员能够快速开发复杂的机器人应用,而无需从头开始训练模型。
该项目的开源性质和详细文档使其成为人形机器人研究社区的宝贵资源。无论您是经验丰富的机器人研究人员还是刚刚进入该领域的新手,GR00T N1都提供了工具和资源,帮助您将先进的AI能力应用到机器人平台上。
要开始使用,只需克隆GitHub仓库,设置环境,并按照提供的教程进行操作。随着更多研究人员采用和贡献这个项目,我们可以期待看到人形机器人领域的快速进步和创新。
参考资源
- GitHub仓库:https://github.com/NVIDIA/Isaac-GR00T
- 预训练模型:Huggingface - nvidia/GR00T-N1-2B
- 示例数据集:Huggingface - nvidia/PhysicalAI-Robotics-GR00T-X-Embodiment-Sim