论文概述

Ψ₀(Psi-Zero)是由南加州大学物理超智能实验室(USC PSI Lab)、NVIDIA 和 WorldEngine 联合开发的通用人形机器人视觉-语言-动作(VLA)基础模型,发表于 RSS 2026。该模型旨在解决人形机器人的 loco-manipulation(运动-操作联合控制)难题,即机器人在移动过程中同时完成精细操作任务(如开冰箱、搬运物品、操作门把手等)。1

现有方法往往试图同时解决人形机器人的运动规划和操作控制问题,导致训练复杂度高、数据需求大。Ψ₀ 的核心发现是:正确扩展正确类型的数据。通过解耦分阶段训练策略,Ψ₀ 实现了超过 40% 的任务成功率提升,同时仅使用 1/10 的机器人数据量。1

核心创新:解耦分阶段训练

问题背景

人形 loco-manipulation 需要同时处理以下挑战:

  1. 全身协调:下肢行走与上肢操作的协同配合
  2. 长时域规划:复杂任务需要多步骤序列规划
  3. 数据稀缺:高质量机器人操作数据获取成本高昂

传统端到端方法(如 VLA 模型)需要大量机器人数据来同时学习视觉理解、任务规划和动作执行,导致数据效率低下。

解耦策略

Ψ₀ 采用两阶段解耦训练策略:

阶段数据来源目标
预训练阶段人类第一人称视频(800小时)学习通用视觉-动作表征
后训练阶段机器人遥操作数据(30小时)适配具体机器人形态

这种设计背后的洞察是:人类视频包含丰富的视觉运动知识和任务语义理解,可以泛化到多种操作场景;而机器人数据的价值在于精确的关节控制映射。通过先从人类视频学习可迁移的表征,再在少量机器人数据上微调,可以实现数据效率的大幅提升。12

架构设计

Ψ₀ 采用三层系统架构,模拟人类认知的双系统理论:

System-2:视觉-语言骨干网络

  • 基础模型:Qwen3-VL-2B-Instruct(约 2.5B 参数)
  • 功能:从观测图像和语言指令中提取视觉-语言特征
  • 作用:负责高层语义理解、任务解析和环境推理

System-1:多模态扩散 transformer 动作专家

  • 架构:基于 Stable Diffusion 3 的流匹配(Flow Matching)扩散 transformer
  • 参数量:约 500M 参数
  • 功能:基于 System-2 的条件特征,预测未来全身动作序列
  • 输出:动作块(Action Chunk),包含全身关节目标

System-0:强化学习跟踪控制器

  • 功能:执行 System-1 预测的下肢动作命令
  • 方法:基于强化学习的低层跟踪控制器
  • 作用:确保稳定、精确的物理控制
┌─────────────────────────────────────────────────────────┐
│                     用户指令                             │
│                   "打开冰箱门"                            │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│              System-2: Qwen3-VL-2B                       │
│              视觉-语言理解与任务规划                      │
└─────────────────────┬───────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────┐
│         System-1: 多模态扩散 Transformer                  │
│         动作序列预测 (≈500M 参数)                         │
└─────────────────────┬───────────────────────────────────┘
                      │
        ┌─────────────┴─────────────┐
        ▼                           ▼
┌───────────────┐          ┌───────────────┐
│    上肢动作    │          │    下肢动作    │
│  (直接执行)   │          │ System-0 控制器 │
└───────────────┘          └───────────────┘

训练流程

第一阶段:人类视频预训练

数据来源

  • Ego4D、EpicKitchens 等大规模第一人称视频数据集
  • 总计约 800 小时的人类活动视频

训练目标

  • 学习通用的视觉-运动对应关系
  • 理解任务语义和物体交互规律
  • 建立可迁移的视觉-动作表征

关键设计:此阶段不直接预测机器人关节角度,而是学习从视觉观察到动作意图的映射关系,这使得学到的表征具有跨形态迁移能力。

第二阶段:机器人数据后训练

数据来源

  • Unitree G1 人形机器人的遥操作数据
  • 9 个真实世界任务:抓取放置、倾倒、搬运、抽屉操作等
  • 总计约 30 小时(数千条轨迹)

微调策略

  • 冻结 System-2 骨干网络权重
  • 仅训练 System-1 动作专家
  • 使用少量数据即可习得精确的关节控制

效率提升:实验表明,仅需 80 条轨迹(约 80 个成功演示)即可让模型习得新的 loco-manipulation 技能。

实验结果与分析

核心指标

指标Ψ₀基线方法提升
任务成功率显著提升基线水平+40%
数据效率30h 机器人数据300h+10×
泛化能力少样本微调全量训练

基准对比

在 SIMPLE 仿真环境和真实 Unitree G1 机器人上的评估显示:

  • 复杂长时域任务:如”从冰箱取物并放置到柜子”,成功率提升超过 40%
  • 少样本适应:新任务仅需 80 条轨迹即可达到实用水平
  • 跨任务泛化:预训练阶段学到的技能可迁移到未见过的任务类型

基线方法比较

方法架构特点数据需求Ψ₀ 优势
GR00T端到端 Transformer大量机器人数据解耦训练更高效
RT-2VLA 统一模型大规模互联网数据专为人形优化
π0扩散策略中等规模Ψ₀ 在 loco-manipulation 更强
π0.5π0 增强版中等规模Ψ₀ 数据效率更高

代码实现

核心模型定义(PyTorch)

import torch
import torch.nn as nn
from transformers import Qwen2VLForConditionalGeneration, Qwen2VLProcessor
from diffusers import DDPMScheduler, FlowMatchEulerDiscreteScheduler
 
class PsiZeroModel(nn.Module):
    """
    Ψ₀: 通用人形机器人基础模型
    
    三层架构:
    - System-2: Qwen3-VL 视觉-语言骨干
    - System-1: 多模态扩散 transformer 动作专家
    - System-0: RL 跟踪控制器(外部模块)
    """
    
    def __init__(
        self,
        vision_model_name: str = "Qwen/Qwen2-VL-2B-Instruct",
        action_dim: int = 23,  # Unitree G1 自由度
        action_horizon: int = 16,  # 动作预测时域
        diffusion_steps: int = 50,
    ):
        super().__init__()
        
        # System-2: 视觉-语言骨干网络
        self.vision_backbone = Qwen2VLForConditionalGeneration.from_pretrained(
            vision_model_name
        )
        self.vision_hidden_dim = self.vision_backbone.config.hidden_size
        
        # System-1: 多模态扩散 transformer 动作专家
        self.action_expert = MultiModalDiffusionTransformer(
            input_dim=action_dim,
            hidden_dim=512,
            num_layers=12,
            num_heads=8,
            action_horizon=action_horizon,
        )
        
        # 扩散调度器 (Flow Matching)
        self.noise_scheduler = FlowMatchEulerDiscreteScheduler(
            num_train_timesteps=1000,
            shift=1.0,
        )
        
        # 动作投影层
        self.action_projection = nn.Linear(
            self.vision_hidden_dim, 
            self.action_expert.condition_dim
        )
        
    def encode_observations(self, images, text_instructions):
        """
        System-2: 编码观测和指令
        
        Args:
            images: 相机图像 [B, T, C, H, W]
            text_instructions: 自然语言指令 [B]
        
        Returns:
            视觉-语言条件特征
        """
        # 图像编码
        pixel_values = images.reshape(-1, *images.shape[2:])
        outputs = self.vision_backbone(
            pixel_values=pixel_values,
            input_ids=text_instructions["input_ids"],
            attention_mask=text_instructions["attention_mask"],
        )
        
        return outputs.last_hidden_state
    
    def forward_diffusion(self, actions, noisy_actions, timesteps, condition):
        """
        System-1 前向传播:预测噪声以进行去噪
        
        Args:
            actions: 原始动作序列 [B, action_horizon, action_dim]
            noisy_actions: 加噪动作 [B, action_horizon, action_dim]
            timesteps: 时间步 [B]
            condition: 条件特征(来自 System-2)
        
        Returns:
            预测的噪声
        """
        noise_pred = self.action_expert(
            noisy_actions=noisy_actions,
            timesteps=timesteps,
            condition=condition,
        )
        return noise_pred
    
    @torch.no_grad()
    def sample_actions(self, condition, num_inference_steps: int = 50):
        """
        推理:使用 DDIM 或 Flow Matching采样动作
        
        Args:
            condition: 条件特征
            num_inference_steps: 采样步数
        
        Returns:
            预测的动作序列
        """
        batch_size = condition.shape[0]
        device = condition.device
        
        # 初始化随机噪声
        actions = torch.randn(
            batch_size, self.action_horizon, self.action_dim,
            device=device
        )
        
        self.noise_scheduler.set_timesteps(num_inference_steps)
        
        for t in self.noise_scheduler.timesteps:
            # 预测噪声
            noise_pred = self.action_expert(
                noisy_actions=actions,
                timesteps=t.expand(batch_size),
                condition=condition,
            )
            
            # 去噪步骤
            actions = self.noise_scheduler.step(
                model_output=noise_pred,
                timestep=t,
                sample=actions,
            ).prev_sample
        
        return actions
 
 
class MultiModalDiffusionTransformer(nn.Module):
    """
    多模态扩散 Transformer(System-1 动作专家)
    
    基于 Stable Diffusion 3 的 MMDiT 架构,
    融合视觉-语言条件和动作序列
    """
    
    def __init__(
        self,
        input_dim: int,
        hidden_dim: int,
        num_layers: int,
        num_heads: int,
        action_horizon: int,
    ):
        super().__init__()
        
        self.input_dim = input_dim
        self.hidden_dim = hidden_dim
        self.action_horizon = action_horizon
        
        # 动作序列编码
        self.action_embedding = nn.Linear(input_dim, hidden_dim)
        
        # 时间步嵌入
        self.time_embedding = TimestepEmbedding(hidden_dim)
        
        # 条件投影(来自 System-2)
        self.condition_projection = nn.Linear(hidden_dim, hidden_dim * 2)
        
        # 多模态注意力块
        self.transformer_blocks = nn.ModuleList([
            MultiModalAttentionBlock(hidden_dim, num_heads)
            for _ in range(num_layers)
        ])
        
        # 输出层
        self.output_projection = nn.Linear(hidden_dim, input_dim)
        
    def forward(self, noisy_actions, timesteps, condition):
        # 动作序列编码
        h = self.action_embedding(noisy_actions)
        
        # 时间步嵌入
        t_emb = self.time_embedding(timesteps)
        h = h + t_emb.unsqueeze(1)
        
        # 条件融合
        cond_proj = self.condition_projection(condition)
        # 条件作为 LayerNorm 的 scale 和 shift
        scale, shift = cond_proj.chunk(2, dim=-1)
        h = h * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
        
        # Transformer 层
        for block in self.transformer_blocks:
            h = block(h)
        
        # 输出预测
        return self.output_projection(h)
 
 
class MultiModalAttentionBlock(nn.Module):
    """多模态注意力块"""
    
    def __init__(self, hidden_dim, num_heads):
        super().__init__()
        self.norm1 = nn.LayerNorm(hidden_dim)
        self.attn = nn.MultiheadAttention(hidden_dim, num_heads, batch_first=True)
        self.norm2 = nn.LayerNorm(hidden_dim)
        self.mlp = MLPBlock(hidden_dim)
        
    def forward(self, x):
        x = x + self.attn(self.norm1(x), self.norm1(x), self.norm1(x))[0]
        x = x + self.mlp(self.norm2(x))
        return x

训练循环示例

def train_psi_zero(
    model: PsiZeroModel,
    train_loader: DataLoader,
    optimizer: torch.optim.Optimizer,
    device: str = "cuda",
):
    """Ψ₀ 训练循环(第二阶段:机器人数据微调)"""
    
    model.train()
    total_loss = 0.0
    
    for batch in train_loader:
        images = batch["images"].to(device)  # [B, T, C, H, W]
        actions = batch["actions"].to(device)  # [B, T, action_dim]
        instructions = batch["instructions"]
        
        # System-2: 提取视觉-语言特征
        with torch.no_grad():  # 冻结骨干网络
            vision_features = model.encode_observations(images, instructions)
        
        # System-1: Flow Matching 训练
        batch_size = actions.shape[0]
        
        # 采样随机时间步
        timesteps = torch.randint(
            0, model.noise_scheduler.config.num_train_timesteps,
            (batch_size,), device=device
        )
        
        # 生成噪声
        noise = torch.randn_like(actions)
        
        # 加噪过程(Flow Matching)
        t_norm = timesteps.float() / model.noise_scheduler.config.num_train_timesteps
        noisy_actions = (1 - t_norm.view(-1, 1, 1)) * actions + t_norm.view(-1, 1, 1) * noise
        
        # 预测噪声
        condition = model.action_projection(vision_features)
        noise_pred = model.forward_diffusion(
            actions=actions,
            noisy_actions=noisy_actions,
            timesteps=timesteps,
            condition=condition,
        )
        
        # 计算损失
        loss = nn.functional.mse_loss(noise_pred, noise)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
        optimizer.step()
        
        total_loss += loss.item()
    
    return total_loss / len(train_loader)

推理使用示例

@torch.no_grad()
def inference_with_psi_zero(
    model: PsiZeroModel,
    images: torch.Tensor,
    instruction: str,
    device: str = "cuda",
):
    """
    使用 Ψ₀ 进行推理
    
    Args:
        model: Ψ₀ 模型
        images: 当前观测图像
        instruction: 任务指令,如 "拿起红色杯子并放到蓝色托盘上"
    
    Returns:
        预测的全身动作序列
    """
    model.eval()
    
    # System-2: 编码观测和指令
    vision_features = model.encode_observations(
        images.unsqueeze(0).to(device),
        {"input_ids": instruction, "attention_mask": [1]}
    )
    
    # System-1: 采样动作序列
    actions = model.sample_actions(
        condition=model.action_projection(vision_features),
        num_inference_steps=50,
    )
    
    return actions.cpu().numpy()

与现有方法对比

架构范式对比

方法核心思想训练策略优势局限
Ψ₀解耦分阶段训练人类视频→机器人微调数据效率高、泛化强需要多阶段训练流程
GR00T统一 VLA端到端架构简洁数据需求大
RT-2VLA 泛化互联网+机器人泛化能力强非人形专用
π0扩散策略统一扩散动作平滑loco 能力弱
π0.5π0 改进增强扩散更好的泛化仍需大量数据

关键差异分析

1. 训练数据策略

  • GR00T、RT-2:依赖大量机器人数据或互联网视觉-语言数据
  • π0、π0.5:使用中等规模机器人数据集
  • Ψ₀:利用 800 小时人类视频 + 30 小时机器人数据,突破数据瓶颈

2. 系统架构

  • 传统 VLA:单一端到端模型
  • Ψ₀:三层解耦架构(System-2 → System-1 → System-0),各司其职

3. 人形 loco-manipulation 专优化

  • RT-2:通用 VLA,非人形专用
  • GR00T:NVIDIA 人形项目,但端到端训练
  • Ψ₀:专门针对人形 loco-manipulation 优化,上下身在系统层面解耦

参考资源

相关阅读

Footnotes

  1. Wei, S., Jing, H., Li, B., et al. Ψ₀: An Open Foundation Model Towards Universal Humanoid Loco-Manipulation. RSS 2026. arXiv:2603.12263 2 3

  2. Physical Superintelligence Lab. Ψ₀ Project Page. https://psi-lab.ai/Psi0