• 正文
  • 相关推荐
申请入驻 产业图谱

具身智能 | AGILE工作流深度解析:从仿真训练到真实部署的人形机器人强化学习工程化范式

10/20 09:32
81
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

转载自公众号:敢敢AUTOHUB

1. 为什么需要 AGILE:从仿真到真机的鸿沟

人形机器人强化学习的难点,从来不只是动作空间大或仿真算力贵,而是系统误差会在整条链路上层层放大。一个关节方向写反、一个观测项顺序不一致、一个奖励项权重尺度漂移、一次启动随机化配置不当,在仿真里都可能被策略“学会适应”;但到了真实硬件上,这种适应往往并不等于可用,而是表现为抖动、打脚、起步失败、姿态漂移、关节冲击,甚至直接威胁执行器安全。人形机器人还叠加了接触、平衡、延迟、摩擦、结构耦合和高维观测历史等问题,因此它比单臂操作或轮式移动更依赖整个流程的一致性。

这也是 AGILE 切入问题的方式。它没有把重点放在“继续提高某个 benchmark 分数”上,而是把问题重新表述为:为什么很多在仿真中看起来流畅的策略,一进入真机就失败;为什么很多实验结果难以复现;为什么训练、评估和部署使用的是三套彼此割裂的数据接口与检查标准。AGILE 给出的回答不是增加一个神奇的损失函数,而是把环境校验、训练、评估、部署变成一个连续的工程生命周期。换句话说,它真正试图修复的,是强化学习在人形机器人场景中的“流程断裂”。

从公开资料看,截至 2026 年 4 月 17 日,AGILE 论文已经发布在 arXiv,WBC-AGILE 官方仓库和文档也已经公开。官方 README 对 AGILE 的描述是一个“comprehensive reinforcement learning framework”,核心目标是训练具有已验证 sim-to-real 迁移能力的 whole-body control policy 。这个表述很重要,因为它说明 AGILE 不是概念验证性质的 demo 集合,而是明确面向训练、评估、跨仿真器验证和部署的框架化项目。

论文地址:https://arxiv.org/abs/2603.20147
项目主页:https://github.com/nvidia-isaac/WBC-AGILE?tab=readme-ov-file

它的下层基础是 Isaac Lab。Isaac Lab 官方文档把自己定位为统一而模块化的机器人学习框架,覆盖强化学习、模仿学习和多模态机器人学习,强调对 GPU 并行仿真、Hydra 配置系统、可复现实验、多 GPU 训练和 Sim2Real 工作流的支持。AGILE 正是建立在这种“通用仿真与任务构建平台”之上。再往上,AGILE 对接的是 RSL-RL。RSL-RL 官方仓库的定位是面向机器人研究的轻量级 GPU 强化学习库,核心提供 PPO、蒸馏、多 GPU 训练和快速原型能力。AGILE 的策略并不是另起炉灶,而是把 Isaac Lab 的环境建模能力和 RSL-RL 的训练能力,装配进一个更完整的工程壳层。

因此,更准确的说法是:AGILE 是位于仿真平台与训练算法之间的一层工作流系统。它没有替代 Isaac Lab,也没有替代 RSL-RL;它的任务是让“任务定义、训练执行、评估诊断、导出部署”围绕同一套配置、同一套约束、同一套输出格式协同工作。理解了这一点,就能理解为什么 AGILE 的创新点主要体现在工作流设计、评估框架和描述符导出,而不是某个单独的网络结构。

如果只想先抓住主线,可以把 AGILE 理解成下面四句话。第一,它把人形机器人 RL 从“试错式脚本堆叠”改造成“分阶段工程流程”。第二,它的重点不在提出新算法,而在统一任务配置、训练入口、评估口径与部署契约。第三,它把最容易出问题的环节前移到了训练前和部署前,而不是等真机失败后再回头排查。第四,它的最终目标不是让仿真视频更好看,而是让策略更容易被带到 MuJoCo 和真实硬件上。

图 1:AGILE 的核心不是单一训练脚本,而是把准备、训练、评估、部署串成闭环。

2. 五层架构:从资产到部署的完整链路

从仓库结构看,AGILE 的整体架构非常清晰。agile/rl_env/tasks/ 存放任务定义,重点是每个任务的环境配置、观测、动作、奖励、终止和课程学习;scripts/train.py 与 scripts/eval.py 是训练与评估入口;agile/algorithms/evaluation/ 存放评估器、指标分析、轨迹记录和 HTML 报告生成器;scripts/export_IODescriptors.py 负责导出部署契约;scripts/sim2mujoco_eval.py 和 agile/sim2mujoco/ 负责跨模拟器运行与验证;scripts/wandb_sweep/ 则负责超参数搜索和训练封装。整个工程没有把所有逻辑压进一个大脚本,而是通过配置类和入口脚本把职责切开。

如果进一步抽象,可以把 AGILE 看成五层。第一层是机器人资产和场景层,定义机器人模型、传感器、地形和物体。第二层是任务层,定义观测、动作、奖励、终止和事件。第三层是训练层,负责 PPO、对称增强、奖励归一化、L2C2、蒸馏等算法模块。第四层是评估层,统一随机 rollout 与确定性脚本测试,并生成轨迹与报告。第五层是部署层,通过导出 I/O 描述符,把训练时的输入输出契约带到 MuJoCo 和硬件侧。AGILE 最有价值的地方,是让这五层之间用一致的配置接口连接,而不是让每一层各自发明一套数据格式。

这套分层在代码里并不是抽象口号,而是通过任务注册机制直接落地。以 Velocity-T1-v0 为例,AGILE 不是在训练脚本里写一堆 if task == ... 的分支,而是把环境配置和训练配置都挂到任务 ID 上:

gym.register(
    id="Velocity-T1-v0",
    entry_point="isaaclab.envs:ManagerBasedRLEnv",
    disable_env_checker=True,
    kwargs={
        "env_cfg_entry_point": "...velocity_env_cfg:T1LowerVelocityEnvCfg",
        "rsl_rl_cfg_entry_point": "...rsl_rl_ppo_cfg:T1VelocityPpoRunnerCfg",
    },
)

这段代码的作用可以直接概括为“用一个任务名绑定两份配置”。env_cfg_entry_point 决定场景、观测、奖励和终止条件,rsl_rl_cfg_entry_point 决定网络结构和训练超参。这样做的结果是,训练入口、评估入口和部署入口都只需要知道任务 ID,不需要在主脚本里知道每个任务的细节。对工程维护来说,这比把逻辑写死在脚本内部更稳定,因为它天然支持任务版本化、配置继承和实验并行。

下表可以帮助快速把握它的工程结构:

层次 作用 代表目录或脚本
场景层 定义机器人、地形、传感器、接触与物体 agile/rl_env/assets/、任务配置文件
任务层 定义观测、动作、奖励、终止、课程学习 agile/rl_env/tasks/
训练层 训练策略、保存配置、记录 Git 状态、执行 sweep scripts/train.py、scripts/wandb_sweep/
评估层 确定性评估、随机评估、轨迹记录、HTML 报告 scripts/eval.py、agile/algorithms/evaluation/
部署层 导出描述符、跨模拟器验证、推理接口统一 scripts/export_IODescriptors.py、scripts/sim2mujoco_eval.py

3. 训练前的验证:把问题扼杀在摇篮里

AGILE 的第一阶段是训练准备。它的核心思想不是"先训练再找问题",而是 "先验证环境,再投入算力" 。这一步对人形机器人尤其关键,因为关节符号、观测维度、奖励触发条件、物体交互逻辑和接触传感器配置,都会直接决定训练有没有意义。如果这些基础设置是错的,那么你得到的并不是一个次优策略,而是一个在错误环境里被正确优化出来的错误策略。对这类问题,单靠训练日志通常很难快速定位。

官方材料里提到的三个 GUI 插件,对应三种前置检查。关节控制 GUI 用来验证单关节驱动方向、对称映射和力矩读数。物体操作 GUI 用来检查 6 自由度物体放置、接触关系和操作类奖励项。奖励可视化插件则直接把奖励项的贡献展示出来,让开发者在训练前就知道策略会被什么行为驱动。这种做法的关键不是"方便演示",而是把环境正确性验证从训练后期拉到训练前期,减少无意义的 GPU 消耗。

在工程实践中,这一步的一个常见入口是先用 play.py 或调试任务配置做快速检查。例如,官方快速开始文档里就给出:

python scripts/play.py --task Velocity-T1-v0 --num_envs 2

这个命令的价值并不在于它能展示一个完整策略,而在于它能快速暴露环境层的问题。开发者可以在这个阶段确认机器人站姿是否合理、命令是否生效、观测是否能够被正确计算、事件随机化是否影响了初始状态。AGILE 的经验非常明确:对于高维接触系统,训练前 10 分钟的交互式检查,往往比训练后 10 小时的日志分析更有价值。

从任务配置文件也能看出这种“先把定义写清楚”的思路。下面这类代码通常直接出现在任务配置里,而不是散落在多个脚本中:

class HistoryPolicyCfg(ObsGroup):
    base_ang_vel = ObsTerm(func=mdp.base_ang_vel, scale=0.2)
    projected_gravity = ObsTerm(func=mdp.projected_gravity)
    velocity_commands = ObsTerm(func=mdp.generated_commands, params={"command_name": "base_velocity"})
    controlled_joint_pos = ObsTerm(func=mdp.joint_pos_rel)
    controlled_joint_vel = ObsTerm(func=mdp.joint_vel_rel, scale=0.05)
    actions = ObsTerm(func=mdp.last_action)

    def __post_init__(self):
        self.history_length = 5
        self.enable_corruption = True

这段配置同时说明了三件事。第一,策略输入不是匿名数组,而是有语义的观测项组合,包括机体角速度、投影重力、速度命令、关节状态和前一时刻动作。第二,history_length = 5 表明策略使用了历史观测,而不是单帧观测。第三,enable_corruption = True 表明在训练阶段会注入观测扰动,以提升策略对噪声的鲁棒性。把这些信息都放在同一个任务配置里,最大的好处就是:开发者在训练前就能明确知道策略到底“看见了什么”,这也是后续评估和部署能够对齐的基础。

图 2:AGILE 把环境验证放在训练前,而不是训练失败后。

4. 可复现的训练:不只是跑出结果

训练阶段是 AGILE 工作流的核心执行部分,但它强调的并不是“如何把 PPO 调到最高分”,而是“如何把训练做成可复现、可消融、可迁移的过程”。官方文档中训练入口非常直接,仍然沿用 Isaac Lab 风格的命令接口,例如:

python scripts/train.py 
    --task Velocity-T1-v0 
    --num_envs 4096 
    --headless 
    --logger wandb

这条命令背后有三个工程上的关键点。第一,任务 ID 会自动映射到环境配置和训练配置。第二,Hydra 风格参数允许从命令行覆盖奖励权重、学习率、场景参数等配置。第三,日志系统会把当前实验的代码状态、环境参数和训练参数一起持久化下来。也就是说,AGILE 不是只记录"最后这个 checkpoint 长什么样",而是记录**"这个 checkpoint 是在什么代码、什么环境、什么超参数下得到的"**。这对后续回归测试和消融实验非常重要。

训练主脚本最关键的一段其实并不长,但几乎把 AGILE 的训练哲学都写出来了:

@hydra_task_config(args_cli.task, "rsl_rl_cfg_entry_point")
def main(env_cfg, agent_cfg):
    agent_cfg = cli_args.update_rsl_rl_cfg(agent_cfg, args_cli)
    env = gym.make(args_cli.task, cfg=env_cfg)
    env = RslRlVecEnvWrapper(env, clip_actions=agent_cfg.clip_actions)

    runner = OnPolicyRunner(
        env,
        agent_cfg.to_dict(),
        log_dir=log_dir,
        device=agent_cfg.device,
    )
    runner.add_git_repo_to_log(__file__)
    dump_yaml(os.path.join(log_dir, "params", "env.yaml"), env_cfg)
    dump_yaml(os.path.join(log_dir, "params", "agent.yaml"), agent_cfg)
    runner.learn(num_learning_iterations=agent_cfg.max_iterations, init_at_random_ep_len=True)

这段代码里最重要的不是 runner.learn(...),而是前后那几步。hydra_task_config(...) 根据任务 ID 自动拿到环境配置和训练配置,说明训练入口与任务定义天然联动。RslRlVecEnvWrapper(...) 负责把 Isaac Lab 环境转换成 RSL-RL 可以直接消费的向量环境接口。add_git_repo_to_log(...)、dump_yaml(...) 则把代码版本和最终生效的配置落到日志目录里。也就是说,AGILE 把"可复现"做成了训练主路径的一部分,而不是论文写完后再补实验说明。

从能力层面看,AGILE 训练阶段还整合了几类稳定化模块。对称增强用于利用左右对称的身体结构,让策略学习更自然的步态;奖励归一化用于减轻不同阶段奖励尺度变化带来的训练不稳定;L2C2 用于惩罚局部观测扰动下过于剧烈的动作和价值变化,提升控制平滑性;蒸馏模块用于把带特权观测的教师策略压缩成可部署学生策略;虚拟安全带则在早期训练中提供外部辅助力,减少刚开始学习时的频繁崩溃。AGILE 的优势不是“这些模块单独都从未出现过”,而是它把这些模块做成了统一配置接口,可以在同一训练框架里有组织地启用、关闭和比较。

例如,对称增强和奖励归一化在配置里就是显式对象,而不是隐含在算法内部的魔法行为:

algorithm = RslRlPpoAlgorithmCfg(
    symmetry_cfg=RslRlSymmetryCfg(
        use_data_augmentation=True,
        use_mirror_loss=False,
        data_augmentation_func=lr_mirror_T1,
    ),
    reward_normalization_cfg=RslRlRewardNormalizationCfg(
        decay=0.999,
        epsilon=1e-2,
    ),
)

这段配置可以直接读成一句工程化语言:训练时开启对称数据增强,同时开启奖励归一化。对称增强的作用,是利用机器人左右身体结构的镜像关系,减少样本浪费并改善步态自然性。奖励归一化的作用,是在课程学习和奖励权重变化时保持回报尺度更稳定,避免 PPO 更新因奖励方差飘移而变得不稳定。仓库里的 RslRlRewardNormalizationCfg 甚至明确写出了它是基于 EMA 跟踪奖励尺度,并考虑时间相关性的返回尺度修正,而不是简单做一次标准化。

蒸馏配置同样是透明的:

class G1VelocityHeightDistillationRecurrentRunnerCfg(...):
    algorithm = RslRlDistillationAlgorithmCfg(
        num_learning_epochs=5,
        gradient_length=15,
        learning_rate=1e-3,
        max_grad_norm=1.0,
        loss_type="mse",
    )
    policy = RslRlStudentTrainedTeacherCfg(
        class_name="StudentTrainedTeacherRecurrent",
        teacher_path="agile/data/policy/velocity_height_g1/unitree_g1_velocity_height_teacher.pt",
        student_hidden_dims=[256, 256, 128],
    )

这段代码告诉我们,AGILE 并没有把“教师策略如何变成学生策略”处理成一段一次性的实验脚本,而是把教师模型路径、学生网络结构、蒸馏损失和优化参数全部显式配置出来。对工程团队来说,这意味着蒸馏本身也是可复现、可替换、可比较的正式训练流程。

训练阶段还有一个很容易被忽略、但对人形机器人很重要的模块,就是虚拟安全带。论文里把它描述为早期训练时的外部支撑,而在仓库里,它被直接实现成一个动作项:

class HarnessAction(ActionTerm):
    def scale_forces(self, scale: float) -> None:
        self.stiffness_torques = self.cfg.stiffness_torques * scale
        self.damping_torques = self.cfg.damping_torques * scale
        self.stiffness_forces = self.cfg.stiffness_forces * scale
        self.damping_forces = self.cfg.damping_forces * scale
        self._force_limit = self.cfg.force_limit * scale
        self._torque_limit = self.cfg.torque_limit * scale
        self._is_disabled = scale <= 0

    def apply_actions(self) -> None:
        torque_stabilization = self._compute_orientation_torque()
        force_height = self._compute_height_force()
        self._asset.set_external_force_and_torque(
            forces=force_height, torques=torque_stabilization, body_ids=self._root_id
        )

这段代码说明,所谓“安全带”并不是抽象说法,而是对机器人根部施加一个可衰减的外力和力矩,用来在训练初期帮助机器人维持姿态和高度。scale_forces(...) 表示这个辅助强度是课程化退场的,训练越往后,支撑越弱,直到完全关闭。这样做的工程意义非常明确:不是让机器人永远依赖外力,而是帮助它跨过最容易崩溃的早期探索阶段,把“从不会站到开始会站”的过程做成一个可控、可退场的训练机制。

图 3:AGILE 允许上下体、教师与学生、历史与特权观测在结构上做清晰解耦。

5. 脚本化评估:从随机 Rollout 到能力边界测试

评估阶段是 AGILE 与很多“只有训练脚本”的项目拉开差距的部分。它没有把评估简化为平均回报或随机 rollout 视频,而是把评估定义成一套可复现、可脚本化、可跨后端共享的诊断体系。官方文档明确区分两条评估路径:一条是 Isaac Lab 路径,支持并行环境、多环境脚本测试、指标统计、轨迹保存和 HTML 报告生成;另一条是 Sim2MuJoCo 路径,用于跨模拟器验证,虽然不直接生成 HTML 报告,但轨迹格式与 Isaac Lab 路径一致,因此仍然可以复用同一套分析工具。

更重要的是,AGILE 的确定性评估并不是临时加的一层脚本,而是有完整的 YAML 配置系统。EvalConfig 支持显式时间调度,也支持 sweep 形式的周期命令变化,还支持按环境 ID 分配不同测试场景。例如可以把一个环境专门用于前进速度扫描,把另一个环境用于横向速度扫描,再把第三个环境用于偏航率扫描。这样做的价值,是让“能力边界测试”成为常规流程,而不是人工录视频时顺手测一下。

这种思想在 eval.py 入口里非常清楚。评估时,脚本并不是简单加载 checkpoint 后开始播放,而是先检查是否存在 YAML 场景配置:

if args_cli.eval_config:
    from agile.algorithms.evaluation.eval_config import EvalConfig
    eval_config = EvalConfig.from_yaml(args_cli.eval_config)
    _apply_env_overrides(env_cfg, eval_config)

agent_cfg = cli_args.parse_rsl_rl_cfg(args_cli.task, args_cli)
env = gym.make(args_cli.task, cfg=env_cfg)
env = RslRlVecEnvWrapper(env, clip_actions=agent_cfg.clip_actions)

这里有两个关键动作。一个是 EvalConfig.from_yaml(...),说明评估场景是配置驱动的,而不是硬编码脚本。另一个是 _apply_env_overrides(...),说明评估配置不仅能改变命令输入,还能覆盖 episode 长度、环境数量甚至事件开关。这样做的价值是:训练和评估仍然围绕同一套任务环境工作,但评估可以用更可控的方式去测试策略边界。

EvalConfig 的设计本身也很工程化:

@dataclass
class SweepConfig:
    interval: float
    commands: dict | None = None

    def to_schedule(self, max_time: float) -> list[ScheduleStep]:
        ...

@dataclass
class EvalConfig:
    task_name: str
    num_envs: int
    episode_length_s: float
    num_episodes: int = 1
    joint_groups: dict | None = None
    environments: list[EnvConfig] = field(default_factory=list)

这段配置结构可以直接读成:评估既支持按时间显式调度,也支持按固定间隔自动 sweep;而 joint_groups 会进一步影响后续指标如何按身体部位统计。这意味着 AGILE 的评估配置不是为了“方便录视频”,而是为了让不同评估后端共享同一套场景语言。

评估指标本身也不是简单的任务成功率。MotionMetricsAnalyzer 默认注册的指标包括关节平均加速度、最大加速度、平均加速度变化率、最大加速度变化率、平均关节速度和最大关节速度;同时它还支持按关节组统计,例如把上半身和下半身分开分析。对于真机部署而言,这类指标比单纯的任务回报更接近硬件健康状态,因为它们直接反映出控制是否过于剧烈、关节是否存在高频震荡,以及不同部位的动态负载是否合理。

相关实现也非常直接:

base_joint_metrics = {
    "mean_joint_acc": self._compute_mean_joint_acc,
    "max_joint_acc": self._compute_max_joint_acc,
    "mean_acc_rate": self._compute_mean_acc_rate,
    "max_acc_rate": self._compute_max_acc_rate,
    "mean_joint_vel": self._compute_mean_joint_vel,
    "max_joint_vel": self._compute_max_joint_vel,
}

这段代码意味着AGILE 从一开始就把"平滑性"纳入默认评估指标,而不是把它留给真机工程师凭经验判断。特别是 mean_acc_rate 和 max_acc_rate 这类量,实际上对应的就是关节加速度变化有多剧烈。对人形机器人真机部署而言,这往往比回报曲线更能直接反映硬件风险。

图 4:AGILE 的评估不是简单的 rollout,而是围绕脚本化测试、统一指标和报告生成展开。

6. 契约式部署:用描述符消除接口不一致

部署阶段的核心不是“把权重导出成一个 .pt 文件”,而是把训练时的输入输出契约完整带到部署端。AGILE 用于完成这件事的关键组件是 I/O 描述符导出脚本。scripts/export_IODescriptors.py 会读取环境的观测项、动作项、关节信息、场景信息,还会额外把观测噪声配置、运动跟踪配置和软关节速度上限等信息一起写进 YAML。随后,无论是 MuJoCo 验证端还是真实硬件端,都可以围绕这份描述符重建推理所需的观测组合、动作映射和历史缓冲区。

这一步的意义非常大。许多 sim-to-real 失败案例并不是"模型学得不行",而是训练端和部署端在默认姿态、观测顺序、动作缩放、历史长度或噪声处理上存在不一致。AGILE 把这些隐式假设显式写进 YAML,就是在减少这种"接口层失败"。从官方文档看,Sim2MuJoCo 模块是 task-agnostic 的,也就是说只要 I/O 描述符正确,它就能自动完成不同任务的观测和动作对接,而不需要为每个任务单独改一套代码。对于中长期维护而言,这种设计非常关键。

描述符导出的核心代码可以直接看出这种设计:

outs = env.unwrapped.get_IO_descriptors

motion_tracking = export_motion_tracking_data(env.unwrapped)
if motion_tracking is not None:
    outs["motion_tracking"] = motion_tracking

_inject_noise_config(env.unwrapped, outs)

for name, art in env.unwrapped.scene.articulations.items():
    vel_limits = art.data.soft_joint_vel_limits
    if vel_limits is not None and name in outs["articulations"]:
        outs["articulations"][name]["soft_joint_vel_limits"] = vel_limits[0].detach().cpu().tolist()

这里可以把导出逻辑理解成“把训练时默认存在的隐式信息全部摊开写进 YAML”。get_IO_descriptors 提供基础观测和动作结构,export_motion_tracking_data(...) 写入动作模仿所需的附加信息,_inject_noise_config(...) 补齐观测噪声配置,soft_joint_vel_limits 则把对安全很重要的软速度限制写进去。导出的不只是说明文档,而是部署侧恢复策略接口的唯一依据。

AGILE 的跨模拟器运行器同样体现了这一思想。scripts/sim2mujoco_eval.py 的主循环如下:

policy = PolicyWrapper.from_config(args.checkpoint, config, device)
sim = MuJocoSimulation(config, device, enable_viewer=not args.no_viewer, mjcf_path=args.mjcf)
obs_processor = ObservationProcessor(config, sim.joint_names, device)
command_provider = create_command_provider(config, device, motion_tracker=obs_processor.motion_tracker)
act_processor = ActionProcessor(config, sim.joint_names, device)

for step in range(num_steps):
    if command_scheduler is not None:
        command_scheduler.update(control_dt)

    sim_state = sim.get_state()
    obs = obs_processor.compute(sim_state, noise_scale=args.noise_scale)

    with torch.no_grad():
        actions = policy(obs)

    obs_processor.set_last_action(actions)
    joint_cmd = act_processor.process(actions)

    for _ in range(sim.decimation):
        sim.step(joint_cmd)

这段代码其实把部署链路拆成了五个可检查的模块。PolicyWrapper 负责统一加载策略;MuJoCoSimulation 负责物理仿真;ObservationProcessor 负责把仿真状态恢复成训练时的观测格式;create_command_provider(...) 负责命令来源;ActionProcessor 负责把策略输出还原为关节命令。主循环顺序是“更新命令 -> 计算观测 -> 策略推理 -> 处理动作 -> 推进仿真”,它尽量复现训练时的执行语义。这样做的最大好处是,当策略在 MuJoCo 或真机侧出现异常时,开发者能判断问题到底出在观测、动作、PD、命令还是物理后端,而不是面对一个黑盒部署函数束手无策。

7. 真机验证:从仿真到硬件的完整闭环

从论文和官方材料看,AGILE 在 Unitree G1 和 Booster T1 两个平台上验证了速度跟踪、速度加高度控制、摔倒复位、动作模仿和移动操作等多类任务。最值得注意的不是“任务种类多”,而是这些任务并非只停留在仿真中,而是完成了仿真到真实硬件的迁移验证。对人形机器人来说,这意味着 AGILE 至少在两个典型平台上证明了它的工作流设计不是纸面上的工程理想,而是真正可以用于训练、评估和落地策略的工具链。

从结果解读上,我认为需要抓住两个层面。第一个层面是能力展示,例如速度跟踪更准了、复位能成功了、动作模仿能落地了、VLA 驱动的抓取放置成功率达到了较高水平。第二个层面更关键,是它展示出了一种更可靠的实验组织方式:任务定义、训练配置、评估脚本、导出部署都围绕同一套系统展开。对研究型读者来说,前者更直观;对工程型读者来说,后者才是更难复制、也更有长期价值的部分。

图 5:AGILE 的确定性评估很适合展示速度、偏航率和高度控制能力。图 6:AGILE 的范围不只包括移动,还延伸到了与视觉语言动作闭环结合的移动操作。

8. 六步工作流:从环境验证到真机部署

如果把 AGILE 的实现流程压缩成最清晰的六步,基本可以概括为下面这样。

第一步,先验证任务环境。用 play.py 或 GUI 调试插件检查关节方向、观测项、接触逻辑和奖励触发,先把明显错误排干净。第二步,运行 train.py,让任务 ID 自动关联环境配置和训练配置,并保存环境参数、Agent 参数和 Git 状态。第三步,用 eval.py 做两类评估:随机 rollout 看总体鲁棒性,EvalConfig 驱动的确定性评估看能力边界和硬件相关指标,并在需要时生成轨迹和 HTML 报告。第四步,用 export_IODescriptors.py 导出 I/O 描述符,把部署端所需的观测、动作、噪声和安全约束写进统一 YAML。第五步,用 sim2mujoco_eval.py 在 MuJoCo 中复用同一份策略和描述符,验证跨模拟器一致性。第六步,在真实硬件侧按照同一份描述符重建输入输出契约,只替换状态获取和执行接口,而不改核心推理逻辑。

对应到命令层,一个最典型的端到端流程大致如下:

# 1. 快速检查环境
python scripts/play.py --task Velocity-T1-v0 --num_envs 2

# 2. 训练
python scripts/train.py --task Velocity-T1-v0 --num_envs 4096 --headless --logger wandb

# 3. 评估并生成报告
python scripts/eval.py 
    --task Velocity-T1-v0 
    --checkpoint /path/to/model.pt 
    --num_envs 32 
    --run_evaluation 
    --save_trajectories 
    --generate_report

# 4. 导出描述符
python scripts/export_IODescriptors.py --task Velocity-T1-v0 --output_dir /path/to/output

# 5. 在 MuJoCo 中复用同一策略和描述符
python scripts/sim2mujoco_eval.py 
    --checkpoint /path/to/policy.pt 
    --config /path/to/output/velocity_t1_v0_IO_descriptors.yaml 
    --mjcf /path/to/scene.xml 
    --eval-config agile/sim2mujoco/configs/x_velocity_sweep.yaml 
    --save-data --no-viewer

如果一定要提炼一个最核心的方法论,那就是:不要把训练、评估和部署看成三件事,而要把它们看成同一条契约链路上的三个阶段。 AGILE 的强点正是在这里。它把任务定义写清楚,把训练过程记清楚,把评估指标拉齐,把部署接口导出来。这样一来,读者不仅能理解这篇工作“做成了什么”,也能知道它“为什么更容易被复用”。

9. 总结

AGILE 的真正意义,不是它证明了人形机器人也能用强化学习完成移动和操作,而是它把“人形机器人强化学习如何进入工程阶段”这件事写成了一套可以照着执行的流程。它提醒我们,在人形机器人这个高度复杂的系统里,算法性能固然重要,但流程标准化、接口一致性、评估可回归和部署可诊断同样重要。很多研究工作强调更强的策略,而 AGILE 更强调更可靠的研发系统;从走向真实硬件这一步来看,后者往往才是更难、更关键、也更有产业价值的部分。

参考

    1. AGILE 论文(https://arxiv.org/abs/2603.20147)2. AGILE 官方仓库(https://github.com/nvidia-isaac/WBC-AGILE)3. AGILE 官方文档(https://nvidia-isaac.github.io/WBC-AGILE)4. AGILE 训练文档(https://github.com/nvidia-isaac/WBC-AGILE/blob/main/docs/source/training.md)5. AGILE 评估文档(https://github.com/nvidia-isaac/WBC-AGILE/blob/main/docs/source/evaluation.md)6. AGILE Sim2MuJoCo 文档(https://github.com/nvidia-isaac/WBC-AGILE/blob/main/docs/source/sim2mujoco.md)7. Isaac Lab 官方文档(https://isaac-sim.github.io/IsaacLab/main/index.html)8. RSL-RL 官方仓库(https://github.com/leggedrobotics/rsl_rl)9. L2C2 论文(https://arxiv.org/abs/2202.07152)

相关推荐