[IT/数码] 全球首个 | 英伟达开源人形机器人基座模型GR00T N1,成功率提升17%!代码+模型解析

[复制链接]
查看20 | 回复0 | 前天 22:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×

2230106975b828.png
2.2B 参数的双系统架构 × 异质混合的多源数据 × 超 17% 的基准测试领先优势
——人形机器的“数据流水线”
3月份黄仁勋在GTC大会上,甩出了世界首个专用于人形机器人的开源基础模型 Isaac GR00T N1。众所周知,一直以来,尽管互联网规模的训练数据能够赋予机器人常识与推理能力,但并不会教给机器人具体的运动和控制,而且始终需要更多、更好的数据。而受限于每日操作时长,人类演示数据的获取也极为有限。Isaac GR00T N1 的出现,则打破了这一困境。它能将少量真实捕获数据,拓展为庞大且多样化的训练数据集。从而轻松地实现各种常见任务 ,例如抓取、用一只或两只手臂移动物体以及将物品从一只手臂转移到另一只手臂等等。本文将围绕该基座模型两个系统架构——VLM模型和DiT模型,从模型结构、输出和输出三个方向,匹配对应的核心代码块进行梳理。我们开设此账号,想要向各位对【具身智能】感兴趣的人传递最前沿最权威的知识讯息外,也想和大家一起见证它到底是泡沫还是又一场热浪?欢迎关注【深蓝具身智能】👇
[backcolor=var(--APPMSGCARD-BG)] 223011cc09295a.png
深蓝具身智能
[color=var(--weui-FG-1)]深蓝学院旗下专注于具身智能与大模型的资讯与干货分享

[color=var(--weui-FG-1)]62篇原创内容




[color=var(--weui-FG-2)]公众号




2230123676bb15.png
模型结构
模型设计
GR00T N1 模型通过创新的双系统架构的VLA模型设计和数据金字塔策略,在复杂操作任务中实现17%的成功率提升,并支持跨硬件平台快速适配,帮助机器人高效地完成桌面操作任务。
223012d8c7f62d.png ▲图1|GR00T N1系统架构总览
其中,系统1是一个扩散Transformer模块,以120Hz的高频率生成动作;系统2则是一个基于预训练的VLM模型,以10Hz的频率运行,负责感知环境和任务目标。
两个模块紧密耦合,通过端到端联合训练实现协同工作。如下图所示:
223012d8176cd0.png ▲图2|GR00T N1系统架构
(1) VLM模块(系统2)
  • 主干网络:

Eagle-2(由SmolLM2语言大模型和SigLIP-2图像编码器微调而来)
  • 模型输入:

1、分辨率为224×224的图像,通过SigLIP-2视觉编码器进行编码,产生64个视觉tokens;
2、 将输入的提示文本通过tokenizer分词器进行编码,得到文本tokens,将视觉tokens和文本tokens进行嵌入,输入到SmolLM2语言大模型。

class Eagle2ChatModel(PreTrainedModel):    def __init__(self, config: Eagle2ChatConfig, vision_model=None, language_model=None):        # 产生64个视觉tokens        self.num_image_token = int((image_size // patch_size) ** 2 * (config.downsample_ratio**2))        # SigLIP-2图像编码器        self.vision_model = SiglipVisionModel(config.vision_config)▲代码1|VLM模块的部分代码1(呼应模型输入的内容)
  • 模型输出:

提取SmolLM2语言大模型的第12层做为输出,其形状为批量大小 × 序列长度 × 隐藏维度的视觉-语言特征,使用第12层做为输出的优势是可以加快推理速度并提高任务成功率。

class EagleBackbone(nn.Module):    def __init__(self,...)        # 移除大于12的层        while len(self.model.language_model.model.layers) > select_layer:            self.model.language_model.model.layers.pop(-1)        # 输入数据融合处理        processor = EagleProcessor(            model_path=processor_cfg["model_path"],            max_input_tiles=processor_cfg["max_input_tiles"],model_spec=ModelSpecificValues(**processor_cfg["model_spec"]),        )    def forward(self, vl_input: BatchFeature) -> BatchFeature:        embeddings = get_embeddings(            self.model,            self.reproject_vision,            pixel_values=vl_input["pixel_values"],            input_ids=vl_input["input_ids"],            attention_mask=vl_input["attention_mask"],        )        embeddings = self.linear(embeddings)        attention_mask = vl_input["attention_mask"]        # [B, T2, hidden_size], 模型输出, (批量大小 × 序列长度 × 隐藏维度)的视觉-语言特征        return BatchFeature(            data={                "backbone_features": embeddings,                "backbone_attention_mask": attention_mask,            }        )  # [B, T2, hidden_size]▲代码2|VLM模块的部分代码2(VLM模块的部分代码1(呼应模型输出的内容)
(2) 扩散 Transformer 模块(系统 1)
  • 模型结构:

采用DiT的变体结构,一种通过自适应归一化进行去噪调节的Transformer,它是由交替的交叉注意力和自注意力模块组成。
自注意力模块对带噪声的动作标记嵌入和状态嵌入进行操作;交叉注意力模块则依据VLM输出的视觉-语言标记嵌入进行调节。

class DiT(ModelMixin, ConfigMixin):    @register_to_config    def __init__(        self,        num_attention_heads: int = 8,        attention_head_dim: int = 64,        output_dim: int = 26,        num_layers: int = 12,        ...):        self.attention_head_dim = attention_head_dim        self.inner_dim = num_attention_heads * attention_head_dim        # 交替的交叉注意力和自注意力        self.transformer_blocks = nn.ModuleList(            [                BasicTransformerBlock(                    self.inner_dim,                    num_attention_heads,                    attention_head_dim,                    ...                )                for _ in range(num_layers)            ]        )▲代码3|DIT模块的部分代码1(呼应模型结构的内容)
  • 模型输入:

视觉-语言特征和状态、动作的编码数据(推理过程中会通过迭代来减少噪声,每次迭代的输出作为下一次迭代的输入)。
  • 模型输出:

经过DiT处理后,利用动作解码器生成动作。

class FlowmatchingActionHead(nn.Module):    def __init__(        self,        config: FlowmatchingActionHeadConfig,    ):        # 状态编码器        self.state_encoder = CategorySpecificMLP(            num_categories=config.max_num_embodiments,            input_dim=config.max_state_dim,            hidden_dim=self.hidden_size,            output_dim=self.input_embedding_dim,        )        # 动作编码器        self.action_encoder = MultiEmbodimentActionEncoder(            action_dim=config.action_dim,            hidden_size=self.input_embedding_dim,            num_embodiments=config.max_num_embodiments,        )        # 动作解码器        self.action_decoder = CategorySpecificMLP(            num_categories=config.max_num_embodiments,            input_dim=self.hidden_size,            hidden_dim=self.hidden_size,            output_dim=self.action_dim,        )    @torch.no_grad()    def get_action(self, backbone_output: BatchFeature, action_input: BatchFeature) -> BatchFeature:        ...        # 迭代去动作噪声        for t in range(num_steps):            t_cont = t / float(num_steps)  # e.g. goes 0, 1/N, 2/N, ...            t_discretized = int(t_cont * self.num_timestep_buckets)             # Embed noised action trajectory.            timesteps_tensor = torch.full(                size=(batch_size,), fill_value=t_discretized, device=device            )            # 动作编码            action_features = self.action_encoder(actions, timesteps_tensor, embodiment_id)            # Maybe add position embedding.            if self.config.add_pos_embed:                pos_ids = torch.arange(action_features.shape[1], dtype=torch.long, device=device)                pos_embs = self.position_embedding(pos_ids).unsqueeze(0)                action_features = action_features + pos_embs             vl_embs = vl_embeds             # Join vision, language, state and action embedding along sequence dimension.            # 动作编码和状态编码合并嵌入            sa_embs = torch.cat((state_features, action_features), dim=1)             # Run model forward.            model_output = self.model(                hidden_states=sa_embs,                # 视觉-文本特征                encoder_hidden_states=vl_embs,                timestep=timesteps_tensor,            )            # 动作解码            pred = self.action_decoder(model_output, embodiment_id)             pred_velocity = pred[:, -self.action_horizon :]             # Update actions using euler integration.            actions = actions + dt * pred_velocity        return BatchFeature(data={"action_pred": actions})
▲代码4|DIT模块的部分代码2(呼应模型输入和输出的内容)
训练细节
  • 预训练数据集

22301212b009e1.png
▲图3|预训练数据集统计
  • 训练超参数

223012448a70c0.png
▲图4|训练超参数。除非指定,否则训练前和训练后使用相同的超参数。
  • 微调内容:

冻结VLM主干网络的语言模型,微调其余部分。

# first run --help to see the available argumentspython scripts/GR00t_finetune.py --help # then run the scriptpython scripts/GR00t_finetune.py --dataset-path ./demo_data/robot_sim.PickNPlace --num-gpus 1 # run using Lora Parameter Eifficient Fine-Tuningpython scripts/GR00t_finetune.py  --dataset-path ./demo_data/robot_sim.PickNPlace --num-gpus 1 --lora_rank 64  --lora_alpha 128  --batch-size 32▲代码5|训练指令
数据集采集
GR00T N1模型的预训练数据集分为:真实机器人数据集、合成数据集和人类视频数据集:
1. 真实机器人数据集
  • GR00T N1人形机器人预训练数据集(通过遥控傅里叶GR1机器人采集的数据集)

  • OpenX-Embodiment

  • AgiBot-Alpha

2. 合成数据集
仿真合成:结合RoboCasa和DexMimicGen,通过遥操进行采集,机器人动作通过重定向生成,并在真实环境和模拟环境中的机器人上执行。
2230135a5ec017.png
▲图5|模型合成:使用图像-视频的模型生成视频,共生成约827小时的合成视频
3. 人类视频数据集
这些数据集涵盖了广泛的真实世界人类行为,包括抓取、工具使用、烹饪、组装以及在自然环境中执行的其他以任务为导向的活动,包含以下7类数据集:Ego4D、Ego-Exo4D、Assembly-101、EPIC-KITCHENS、HOI4D、HoloAssist 、RH20T-Human。
223013523ef3e8.png ▲图6|人类视频数据集样本。七个人类视频数据集进行预训练。上面的图像显示了七个数据集中的每个数据集的示例及其相应的语言注释。

from GR00t.data.dataset import LeRobotSingleDatasetfrom GR00t.data.embodiment_tags import EmbodimentTagfrom GR00t.data.dataset import ModalityConfigfrom GR00t.experiment.data_config import DATA_CONFIG_MAP # get the data configdata_config = DATA_CONFIG_MAP["gr1_arms_only"] # get the modality configs and transformsmodality_config = data_config.modality_config()transforms = data_config.transform() # This is a LeRobotSingleDataset object that loads the data from the given dataset path.dataset = LeRobotSingleDataset(    dataset_path="demo_data/robot_sim.PickNPlace",    modality_configs=modality_config,    transforms=None,  # we can choose to not apply any transforms    embodiment_tag=EmbodimentTag.GR1, # the embodiment to use) # This is an example of how to access the data.dataset[5]▲代码6|加载数据集 2230134342e5bb.png 实验
  • 基线模型:BC-Transformer、Diffusion Policy

  • 评估数据:

(1)仿真:
  • RoboCasa厨房数据:包含24个任务,涉及基础感测运动技能,如拾取和放置、开门和关门、按按钮、转动水龙头等。对于每个任务,使用公开可用的3000个演示数据集,这些数据集由FrankaEmikaPanda臂生成。

  • DexMimicGen双臂灵巧手操作数据:包括一系列9项双手灵巧操作任务,需要精确的双协调。这些任务共同涵盖了三种双手机器人实现方式

  • GR-1机器人桌面操作数据:包含24个任务,使用配备傅里叶灵巧手的GR-1类人型机器人进行灵巧的手部控制,涉及将物体放入关节式物体(即柜、抽屉和微波炉)中并关闭它们。观察空间包括从机器人头部的自主相机捕获的RGB图像。状态/动作空间包括双臂和双手的关节位置和旋转,以及腰部和颈部。
    2230139f7e26c9.png
    ▲图7|在仿真环境中的测试结果
(2)真实世界:
  • Pick-and-Place:5个任务,用于评估模型抓取物体并将其放置到指定容器中的能力,这是机器人操作的基本能力。
  • Articulated Object Manipulation:3个任务,评估模型对关节式存储隔层的操作能力。模型需要抓取物体,将其放入诸如木箱、深色橱柜或白色抽屉等存储单元中,然后关闭隔层。
  • Industrial Object Manipulation:3个任务,针对工业场景设计,包含三个结构化工作流程和基于工具的交互任务。
  • Multi-Agent Coordination:2个任务,协作任务需要多个智能体之间的同步,强调角色协调和自适应决策。

22301420272173.png
▲图8|在真实世界中的测试结果
  • 实验结论:

1、 GR00T N1 优于BC-Transformer和Diffusion Policy基线模型;
2、 GR00T N1 相较于Diffusion Policy具有更强的语义理解能力;
3、 GR00T N1 相较于Diffusion Policy,运动更平滑、抓取更准确。
223014a4b655d8.png 总结
在英伟达官网视频的结尾中,他们写到:
在基于英伟达 Isaac GR00T N1 的开发者的推动下,通用机器人时代已经到来。
而 GR00T N1 采用双系统架构,融合异构数据,的确可以支持多种机器人形态,在模拟和真实环境测试中,且它泛化性强,能有效帮助机器人高效完成桌面操作任务。
目前 GR00T N1 也已开源模型检查点、训练数据集、模拟环境和代码。
但是,GR00T N1 主要用于短视距桌面操作任务,在长视距移动的操作任务上尚无进展。
并且 GR00T N1 在构建的机器人训练的合成数据上,仍缺乏多样性,且在物理特性上仍存在反事实现象,因此严重影响了合成数据集的质量。
在未来,GR00T N1 希望能从以下几个方向继续发力:
1. 拓展应用:提升模型处理长视距移动操作任务的能力
2. 强化模块:增强视觉-语言主干,提升模型空间推理、语言理解和环境适应能力
3. 优化数据:改进合成数据生成技术,丰富数据金字塔,为模型训练提供更好的数据
4. 创新技术:探索新模型架构和预训练策略,提高机器人模型的鲁棒性和泛化性
Ref论文题目:GR00T N1: An Open Foundation Model for Generalist Humanoid Robots项目主页:https://developer.nvidia.com/isaac/GR00t

论文地址:https://arxiv.org/pdf/2503.14734



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

hdy

259

主题

318

回帖

685

积分

二级逆天

积分
685