《VLA 系列》UniLab 机器人 RL 异构架构 | 强化训练 | 复现指导

核心定位: UniLab 机器人 RL 异构架构 | 代码复现 | G1、Go2、灵巧手等

开源地址:https://github.com/unilabsim/UniLab/blob/main/README_zh.md

论文地址:UniLab: A Heterogeneous Architecture for Robot RL Beyond GPU-Dominant Paradigms

项目地址:https://unilabsim.github.io/

✨ UniLab简介与亮点

  • 异构 RL 运行时: CPU 并行仿真通过共享内存流式传输 transition,而策略学习运行在 GPU 加速器上。
  • 两套物理后端: MuJoCoUni 和 MotrixSim 通过后端专用适配器和任务 owner 配置接入。
  • 统一训练 CLI: uv run trainuv run eval 覆盖 PPO、MLX PPO、APPO、SAC、TD3 和 FlashSAC;额外的 HORA 与 HIM-PPO 路径以脚本级工作流文档化。
  • 配置拥有的任务: Hydra owner YAML 会同时选择 task、reward、backend 和 algorithm;后端切换通过 task=<task>/<backend> 表达。
  • 跨平台安装路径: 仓库覆盖Linux CUDA、Linux ROCm、Linux XPU,以及 Apple Silicon / macOS的安装流程。

代表性机器人RL训练系统对比 ,如下图所示:

  • 注:GPU-C/M/R: 基于 CUDA/Metal/ROCm 的 GPU 批量物理。

  • GPU-sync: 同步 GPU 仿真-学习;

  • H-async/sync: CPU 仿真 + GPU 学习。

使用UniLab的训练时间 ,如下表所示:

整体速度还是很快的,不错不错~

一、环境搭建

主要参考下面几条指令,进行环境搭建:

bash 复制代码
# 0. 如果还没有安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 1. 克隆仓库
git clone https://github.com/unilabsim/UniLab.git
cd UniLab

# 2. 安装依赖
# 选择合适的平台,对应的安装命令

# Linux CUDA 或 macOS
make setup-motrix
# 不使用 shell completion 设置时:uv sync --extra motrix
# 如果没有安装 `make`:uv sync --extra motrix && uv run --no-sync unilab-complete install

# Linux AMD / ROCm
# make sync-rocm

# Linux Intel Arc / iGPU
# make sync-xpu

# 3. 安装Play viser 可视化 依赖
uv sync --extra viser

运行过程:

然后设置 Hugging Face 为国内源

动作、场景、机器人数据 和 demo checkpoint首次运行时会从 Hugging Face 拉取。

bash 复制代码
export HF_ENDPOINT=https://hf-mirror.com

二、效果演示

演示回放(首次运行会从 Hugging Face 拉取预训练检查点):

示例1:G1机器人跳舞

bash 复制代码
# G1机器人跳舞的示例
uv run demo dance

其中,可用的 demo 名称:teaser、dance、wallflip、boxtracking、locomani、inhandgrasp

运行效果

示例2:G1机器人搬箱子

bash 复制代码
# G1机器人搬箱子
uv run demo dance

运行效果

示例3:Go2机器狗 移动+操作

bash 复制代码
# Go2机器狗 移动+操作
uv run demo locomani

运行效果

三、机器人训练 与 评估

支持多种机器人、不同任务,参考链接:https://unilabsim.github.io/UniLab-doc/en/2-user_guide/4-tasks/0-index.html

训练和评估在UniLab中共享相同的算法实现基础,但通过配置参数和执行标志实现了功能分离

uv run train 命令

  • 入口函数cli.py 中的 train_main() 函数
  • 路由逻辑 :根据 --algo 参数选择不同的训练脚本
  • 具体脚本对应关系
    • --algo apposcripts/train_appo.py
    • --algo pposcripts/train_rsl_rl.py
    • --algo sac/td3/flashsacscripts/train_offpolicy.py
    • --algo mlx_pposcripts/train_mlx_ppo.py

详细参考第四章节的算法说明

uv run eval 命令

  • 入口函数cli.py 中的 eval_main() 函数
  • 路由逻辑:与 train 相同,但会添加评估专用参数
  • 具体脚本对应关系 :与 train 命令相同,但会设置 training. play_only=true
  • 其中,algo.load_run=-1 (加载最新训练结果)

代码执行路径差异

训练路径
python 复制代码
# 入口:src/unilab/cli.py → train_main()
# 根据 --algo 参数路由到不同训练脚本:
# - appo → scripts/train_appo.py
# - ppo → scripts/train_rsl_rl.py  
# - sac/td3/flashsac → scripts/train_offpolicy.py
# - mlx_ppo → scripts/train_mlx_ppo.py
评估路径
python 复制代码
# 入口:src/unilab/cli.py → eval_main()
# 实际仍调用相同的训练脚本,但设置特殊标志:
# training.play_only = True
# algo.load_run = -1 (加载最新训练结果)
# render_mode = "interactive" 或 "record"
关键配置参数差异
参数 训练模式 评估模式 作用
training.play_only False True 禁用策略更新,仅执行策略
algo.load_run 通常为 None -1 (最新) 或指定run ID 指定要加载的模型
render_mode 通常为 none interactive/record 控制可视化行为
num_envs 多环境并行 (最大化吞吐量) 通常为1 (便于观察) 环境数量设置
headless 通常为 True (无GUI) 根据需求设置 是否显示GUI

1、G1机器人 平地行走

对于G1机器人,进行训练与评估:

bash 复制代码
# G1机器人在平面行走--训练
uv run train --algo sac --task g1_walk_flat --sim mujoco

# G1机器人在平面行走--验证,保存可视化结果
uv run eval --algo sac --task g1_walk_flat --sim mujoco --load-run -1

训练结果:

训练好后,会保留模型权重(model_5000.pt)、可视化视频的

G1机器人在平面行走的效果:

如果 开着代理访问国内镜像站 hf-mirror.com 出现链路异常,可以参考下面进行修复:

bash 复制代码
# 1. 彻底清空所有代理环境变量,排除代理干扰
unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY no_proxy NO_PROXY

# 2. 重新设置 Hugging Face 国内镜像
export HF_ENDPOINT=https://hf-mirror.com

# 3. (可选)验证镜像站是否可通,正常会返回 200/302
curl -I https://hf-mirror.com

# 4. 重新执行训练
uv run train --algo sac --task g1_walk_flat --sim mujoco

2、G1机器人 空翻

使用PPO的算法进行强化训练,默认训练2万轮,最终的效果比较稳定

bash 复制代码
# G1机器人空翻--训练
uv run train --algo ppo --task g1_wall_flip_tracking --sim mujoco


# G1机器人空翻--验证,保存可视化结果
uv run eval --algo ppo --task g1_wall_flip_tracking --sim mujoco --load-run -1

训练结果:

G1机器人空翻效果:

3、G1机器人 动作跟踪(舞蹈)

使用sac的算法进行强化训练,默认训练2.5万轮,最终的效果比较稳定

bash 复制代码
# G1机器人动作跟踪--训练
uv run train --algo sac --task g1_motion_tracking --sim motrix

# G1机器人动作跟踪--验证,保存可视化结果
uv run eval --algo sac --task g1_motion_tracking --sim motrix  --load-run -1

训练结果:

bash 复制代码
╭─────────────────────────────────  🚀 UniLab Off-Policy Training  ─────────────────────────────────╮
│  FastSAC | G1MotionTrackingSAC | iter 0/25000 | ⏱ 0s | Warming up...                              │
│                                                                                                   │
╭─────────────────────────────────  🚀 UniLab Off-Policy Training  ─────────────────────────────────╮
│  FastSAC | G1MotionTrackingSAC | iter 25000/25000 | ⏱ 1h01m33s | ETA 0s | Ep Len 264.0 | Steps/s... │
│                                                                                                   │
│ Losses & Metrics                           Value  Rewards                                   Value │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ Actor Loss                                -9.425  Reward ━              Mean 27.937 / Peak 32.162 │
│ Alpha Loss                              5.73e-05    action rate                           -0.2227 │
│ Qf Loss                                    3.907  l2                                              │
│   Action Std                              0.1768    joint limit                           +0.0000 │
│   Actor Grad Norm                         0.0094    motion body                           +0.3483 │
│   Alpha                                 7.84e-04  ang vel                                         │
│   Critic Grad Norm                        0.0338    motion body                           +0.8121 │
│   Policy Entropy                         -14.482  lin vel                                         │
│   Target Q Max                             9.818    motion body                           +0.8480 │
│   Target Q Min                             5.634  ori                                             │
│                                                     motion body                           +1.9748 │
│                                                   pos                                             │
│                                                     motion global                         +0.4823 │
│                                                   root ori                                        │
│                                                     motion global                         +0.9764 │
│                                                   root pos                                        │
│                                                     undesired                             +0.0000 │
│                                                   contacts                                        │
│                                                                                                   │
│ Learner                    Value   Collector               Value   System                   Value │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
│ Wait                       0.1ms   Weight Sync            12.4ms   Buffer               1,048,576 │
│ H2D                        0.1ms   Action Select          32.1ms   Timeout Rate            100.0% │
│ Train                     22.2ms   Env Step               32.5ms   Terminated Rate           0.0% │
│ Weight Sync                0.4ms   Replay                 27.1ms   Envs                     2,048 │
│                                    Sync Coordination      49.2ms   Sync Collect             ✓ (1) │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯

G1机器人舞蹈效果:

四、算法说明 与 模型推理

4.1、算法说明

bash 复制代码
主要包含8种算法:
1-ppo
2-appo
3-sac
4-td3
5-flash_sac
6-him_ppo
7-hora
8-mlx_ppo

这里描述每个算法:具体算法的内容入口配置文件所在位置

算法 类型 入口 配置
PPO 同步 on-policy scripts/train_rsl_rl.py conf/ppo/config.yaml
APPO 异步 on-policy scripts/train_appo.py conf/appo/config.yaml
SAC off-policy scripts/train_offpolicy.py conf/offpolicy/algo/sac.yaml
TD3 off-policy scripts/train_offpolicy.py conf/offpolicy/algo/td3.yaml
FlashSAC off-policy scripts/train_offpolicy.py conf/offpolicy/algo/flashsac.yaml
HIM-PPO 高度估计器 PPO 路径 scripts/train_him_ppo.py conf/ppo_him/config.yaml
HORA teacher/student 蒸馏路径 scripts/train_hora_distill.py conf/hora_distill/config.yaml
MLX PPO 面向 Apple Silicon 的同步 on-policy scripts/train_mlx_ppo.py conf/ppo/config_mlx.yaml

不同算法使用示例:

bash 复制代码
uv run train --algo ppo --task go2_joystick_flat --sim mujoco
uv run train --algo ppo --task go2_joystick_flat --sim motrix
uv run train --algo sac --task g1_walk_flat --sim mujoco
  • 常规用法下,使用 --task 和 --sim 选择 task 和 backend;
  • 通过--algo 选择那一种算法,比如上面示例的ppo、sac。

4.2、模型推理、可视化验证

1、🎮 主要推理入口

scripts/play_interactive.py 是核心的实际推理代码,专为真实机器人部署设计:

核心功能:
  • 多模式推理:

    python 复制代码
    # action_mode参数控制推理模式
    action_mode = "policy"    # 使用训练好的策略
    action_mode = "zero"      # 零动作(安全模式)
    action_mode = "keyboard"  # 键盘控制(调试/演示模式)
  • 键盘控制接口:

    python 复制代码
    # 支持键盘速度命令(vx, vyaw)
    if keycode == _KEY_UP:    commander.nudge(commander.AXIS_VX, +1.0)  # 前进
    if keycode == _KEY_DOWN:  commander.nudge(commander.AXIS_VX, -1.0)  # 后退
    if keycode == _KEY_LEFT:  commander.nudge(commander.AXIS_VYAW, +1.0) # 左转
    if keycode == _KEY_RIGHT: commander.nudge(commander.AXIS_VYAW, -1.0) # 右转
  • 真实机器人适配:

    python 复制代码
    # 检测是否为速度命令型locomotion任务
    def _is_velocity_command_locomotion_task(env: Any) -> bool:
        # 验证任务名称是否包含"Joystick"、"Walk"等关键字
        return any(marker in candidate for candidate in candidate_names 
                   for marker in ["Joystick", "Walk"])

play_interactive.py 是 UniLab 框架下专属 MuJoCo 物理后端的交互式策略回放调试工具,核心作用是加载训练完成的机器人强化学习策略,通过 MuJoCo 原生可视化窗口实现实时回放、交互控制与调试可视化。

具体核心功能如下:

  1. 多算法策略回放
    支持 PPO、APPO、SAC、FlashSAC、HORA 多种算法的训练 checkpoint 加载与回放,兼容 rsl_rl 等训练框架的模型格式,自动解析模型输入维度与配置。
  2. 播放与交互控制
    • 基础播放:空格暂停/继续、N 键单步执行、+/- 调节回放倍速、退格键重置环境
    • 键盘遥操作:针对带速度指令的运动类任务,支持方向键下发线速度/角速度指令,回车键归零,直接控制机器人运动
  3. 多层级调试可视化
    • 运动目标叠加:显示参考运动的目标刚体位置、姿态坐标轴
    • 奖励调试叠加:同步渲染参考位姿、机器人力学位姿、运动目标位姿,支持速度向量、位姿误差连线、全局锚点的可视化
    • 速度指令箭头:运动任务中区分显示目标速度(绿色)与当前实际速度(蓝色),直观对比指令跟随效果
  4. 视角与渲染适配
    • 自动跟随机器人基座,支持自定义相机距离、俯仰角、方位角、高度偏移
    • 自动适配可视化模型,优先加载高画质渲染模型,失败时自动降级为回放模型
  5. 跨场景兼容
    覆盖足式机器人运动、人形机器人运动跟踪、灵巧手操作等多类任务,自动匹配任务对应的环境、观测与奖励逻辑。

补充说明

play_interactive.py仅支持 MuJoCo 后端的交互式策略回放脚本,用于加载训练好的策略模型,在 MuJoCo 可视化窗口中实时推理、调试机器人行为。

即使你的模型是通过 Motrix 后端训练的,该脚本也可以读取对应后端的任务配置,但最终物理步进与渲染均使用 MuJoCo 完成。

模型推理------实践示例1

比如,上面用G1机器人进行了,运行跟踪,学习舞蹈,现在进行推理

训练指令:

bash 复制代码
uv run train --algo sac --task g1_motion_tracking --sim motrix
方式1:加载最新一次训练的模型(最常用)

使用 algo.load_run=-1 自动匹配最近一次完成的训练运行,加载其最新的 checkpoint:

bash 复制代码
uv run scripts/play_interactive.py \
  --algo sac \
  --task g1_motion_tracking \
  --sim motrix \
  algo.load_run=-1 \
  interactive.action_mode=policy

运行效果:

方式2:显示关节坐标系/奖励调试叠加层

显示关节坐标系/奖励调试叠加层

bash 复制代码
uv run scripts/play_interactive.py \
    --algo sac \
    --task g1_motion_tracking \
    --sim motrix \
    algo.load_run=-1 \
    interactive.action_mode=policy \
    interactive.show_target_bodies=true \
    interactive.target_show_axes=true \
    interactive.show_reward_debug=true

运行效果:

核心参数详解
参数分类 参数 说明
基础标识 --algo 必须与训练时的算法完全一致,支持 ppo/appo/sac/flashsac/hora_distill
基础标识 --task 任务名,与训练命令保持一致
基础标识 --sim 训练时使用的物理后端(mujoco/motrix),用于读取对应任务配置
模型指定 algo.load_run 训练运行的编号:-1 表示最新一次运行,填数字则对应第N次训练
推理控制 interactive.action_mode 必须设为 policy 才会执行策略推理输出动作;否则为零动作回放,机器人不会运动
模型推理------实践示例2

比如,上面用G1机器人进行了空翻,现在进行推理

训练指令:

bash 复制代码
uv run train --algo ppo --task g1_wall_flip_tracking --sim mujoco

推理指令

bash 复制代码
uv run scripts/play_interactive.py \
  --algo ppo \
  --task g1_wall_flip_tracking \
  --sim motrix \
  algo.load_run=-1 \
  interactive.action_mode=policy

运行效果:

2、🌐 备选:Web可视化推理

scripts/play_viser.py 提供Web-based交互式推理,适合远程监控和调试:

bash 复制代码
uv run scripts/play_viser.py task=go2_joystick_flat/mujoco \
    interactive.action_mode=policy \
    viser.port=8080
  • 通过浏览器访问 http://localhost:8080
  • 支持多环境同时显示
  • 无需本地图形界面,适合服务器部署

五、Sim2Real 部署指南

📁 关键部署脚本

项目中的 scripts/deploy 目录包含核心部署工具:

复制代码
scripts/deploy/
├── export_deploy_config.py    # 导出部署配置
├── export_motion_bin.py       # 导出运动二进制文件  
├── append_cooldown.py         # 添加冷却阶段
├── prepend_warmup.py          # 添加预热阶段
└── sim_prototype.py           # 模拟原型测试

5.1 仿真到真机总览

在 UniLab 中,一个可部署的策略是导出的策略加上所选任务 owner 使用的那套精确的观测与动作契约。G1 WBT 辅助路径将其物化为 policy.onnxdeploy_config.yaml 以及一个运动二进制文件;其他机器人需要一个等价的硬件侧运行时,它需要:

  • 读取传感器 → 组装出策略在仿真中看到的同一个观测向量
  • 通过一个支持所导出计算图的运行时来运行 policy.onnx
  • 将动作向量映射到环境 SimBackend 所使用的同一套执行器接口

端到端流程:
#mermaid-svg-NDwMjH0D2AMqF52x{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NDwMjH0D2AMqF52x .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NDwMjH0D2AMqF52x .error-icon{fill:#552222;}#mermaid-svg-NDwMjH0D2AMqF52x .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NDwMjH0D2AMqF52x .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NDwMjH0D2AMqF52x .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NDwMjH0D2AMqF52x .marker.cross{stroke:#333333;}#mermaid-svg-NDwMjH0D2AMqF52x svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NDwMjH0D2AMqF52x p{margin:0;}#mermaid-svg-NDwMjH0D2AMqF52x .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NDwMjH0D2AMqF52x .cluster-label text{fill:#333;}#mermaid-svg-NDwMjH0D2AMqF52x .cluster-label span{color:#333;}#mermaid-svg-NDwMjH0D2AMqF52x .cluster-label span p{background-color:transparent;}#mermaid-svg-NDwMjH0D2AMqF52x .label text,#mermaid-svg-NDwMjH0D2AMqF52x span{fill:#333;color:#333;}#mermaid-svg-NDwMjH0D2AMqF52x .node rect,#mermaid-svg-NDwMjH0D2AMqF52x .node circle,#mermaid-svg-NDwMjH0D2AMqF52x .node ellipse,#mermaid-svg-NDwMjH0D2AMqF52x .node polygon,#mermaid-svg-NDwMjH0D2AMqF52x .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NDwMjH0D2AMqF52x .rough-node .label text,#mermaid-svg-NDwMjH0D2AMqF52x .node .label text,#mermaid-svg-NDwMjH0D2AMqF52x .image-shape .label,#mermaid-svg-NDwMjH0D2AMqF52x .icon-shape .label{text-anchor:middle;}#mermaid-svg-NDwMjH0D2AMqF52x .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NDwMjH0D2AMqF52x .rough-node .label,#mermaid-svg-NDwMjH0D2AMqF52x .node .label,#mermaid-svg-NDwMjH0D2AMqF52x .image-shape .label,#mermaid-svg-NDwMjH0D2AMqF52x .icon-shape .label{text-align:center;}#mermaid-svg-NDwMjH0D2AMqF52x .node.clickable{cursor:pointer;}#mermaid-svg-NDwMjH0D2AMqF52x .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NDwMjH0D2AMqF52x .arrowheadPath{fill:#333333;}#mermaid-svg-NDwMjH0D2AMqF52x .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NDwMjH0D2AMqF52x .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NDwMjH0D2AMqF52x .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NDwMjH0D2AMqF52x .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NDwMjH0D2AMqF52x .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NDwMjH0D2AMqF52x .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NDwMjH0D2AMqF52x .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NDwMjH0D2AMqF52x .cluster text{fill:#333;}#mermaid-svg-NDwMjH0D2AMqF52x .cluster span{color:#333;}#mermaid-svg-NDwMjH0D2AMqF52x div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NDwMjH0D2AMqF52x .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NDwMjH0D2AMqF52x rect.text{fill:none;stroke-width:0;}#mermaid-svg-NDwMjH0D2AMqF52x .icon-shape,#mermaid-svg-NDwMjH0D2AMqF52x .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NDwMjH0D2AMqF52x .icon-shape p,#mermaid-svg-NDwMjH0D2AMqF52x .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NDwMjH0D2AMqF52x .icon-shape .label rect,#mermaid-svg-NDwMjH0D2AMqF52x .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NDwMjH0D2AMqF52x .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NDwMjH0D2AMqF52x .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NDwMjH0D2AMqF52x :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-NDwMjH0D2AMqF52x .step>*{fill:#e6f7ff!important;stroke:#1890ff!important;}#mermaid-svg-NDwMjH0D2AMqF52x .step span{fill:#e6f7ff!important;stroke:#1890ff!important;} 核心验证点
iterate
训练收敛
训练收敛
跨后端验证
导出验证
延迟匹配
安全层
硬件启动
闭环验证
Train in UniLab
Curriculum + DR
Validate in alt backend
Export ONNX
Latency / lag injection
Safety layer
Hardware bringup
Closed-loop run
奖励稳定
成功判据稳定
MuJoCo & Motrix
ONNX校验
训练/部署同步
畸形观测过滤
传感器校准
动作轨迹比对

流程图说明:

  1. 纵向结构:从上到下展示完整流程,符合阅读习惯
  2. 关键验证点:每个环节标注核心验证要求(灰色子图)
  3. 迭代路径:闭环验证(H)后自动返回训练阶段(B),形成持续优化循环
  4. 视觉优化
    • 蓝色节点突出核心步骤
    • 箭头标注具体验证要求
    • 闭环迭代路径用虚线明确标识

上机前检查清单:

  • 一次收敛的训练运行,奖励稳定,且成功判据也稳定(运动跟踪误差、跌落次数等)
  • 当 MuJoCo 与 Motrix 都支持该任务时,同一策略在两者中都能通过评估
  • 域随机化范围足够大,使得在扫动 DR 强度时奖励平滑变化
  • 环境中没有后端功能泄漏
  • 一份你能在硬件上实现的观测规格

最常见的失败模式:

  • 观测漂移:仿真与部署运行时之间的传感器预处理不同(单位、坐标系、滤波截止频率)
  • 动作延迟:测量部署回路,并在硬件运行前让训练 owner 匹配该契约
  • 摩擦/阻尼不匹配:尤其对于手内操作。在 DR 中扫动摩擦
  • 复位瞬态:安全层必须在畸形观测与不安全动作到达电机驱动器之前将其拒绝

5.2 ONNX 运行时部署

UniLab 从既有的训练回放路径导出 ONNX 策略。使用产出该检查点的同一算法家族与任务 owner;回放代码加载检查点、导出 policy.onnx,并在该路径实现了 ONNX Runtime 检查时校验所导出的计算图。

导出路径:

算法路径 入口脚本 仓库中的导出行为
PPO(torch) scripts/train_rsl_rl.py 脚本入口处 EXPORT_POLICY=True;回放调用 runner.export_policy_to_onnx(...) 与 runner.export_policy_to_jit(...)
HIM-PPO scripts/train_him_ppo.py 与 PPO 相同的脚本级导出模式
APPO scripts/train_appo.py 回放写出 policy.onnx 并将 ONNX Runtime 输出与 PyTorch 比对校验
SAC / TD3 / FlashSAC scripts/train_offpolicy.py 回放写出 policy.onnx;SAC 与 FlashSAC 在导出前使用 actor.as_export_module()
MLX PPO scripts/train_mlx_ppo.py 回放将 MLX actor 权重转换为 PyTorch 模块,写出 policy.onnx,并校验 ONNX Runtime 输出

导出命令:

bash 复制代码
# PPO算法示例
uv run eval --algo ppo --task go2_joystick_flat --sim mujoco --load-run -1

# APPO算法示例
uv run eval --algo appo --task g1_motion_tracking --sim motrix --load-run -1

# SAC算法示例
uv run eval --algo sac --task g1_walk_flat --sim mujoco --load-run -1

5.3 G1 全身运动跟踪部署

硬件目标: Unitree G1 人形机器人(29 自由度变体)。假定关节顺序与 scripts/deploy/export_deploy_config.pysrc/unilab/assets/robots/g1/scene_flat.xml 导出的顺序一致。

0. 验证你的仿真侧检查点
bash 复制代码
uv run eval --algo ppo --task g1_motion_tracking --sim motrix --load-run -1 --render-mode record

在视频中要关注:

  • 被跟踪的各 body 跟随参考运动,没有大的不连续
  • 关节速度与动作保持有限且在预期范围内
  • 接触时序看起来与参考运动一致
1. 导出部署文件
bash 复制代码
# 导出ONNX策略
uv run eval --algo ppo --task g1_motion_tracking --sim motrix --load-run -1

# 导出部署配置
uv run scripts/deploy/export_deploy_config.py --output logs/deploy/deploy_config.yaml

# 导出运动二进制
uv run scripts/deploy/export_motion_bin.py --output logs/deploy/dance1.bin

部署侧原型消费如下文件:

复制代码
runs/<run>/
└── policy.onnx
logs/deploy/
├── deploy_config.yaml
└── dance1.bin
2. 观测契约

对于已提交的 G1 WBT 部署辅助工具,观测布局会作为 obs_layout 导出到 deploy_config.yaml

分组 维度 硬件上的来源
command_joint_pos 29 运动参考帧的关节位置
command_joint_vel 29 运动参考帧的关节速度
motion_anchor_ori_b 6 来自参考帧与机器人躯干帧的锚点朝向项
gyro 每个历史步 3 IMU 陀螺仪项
joint_pos_rel 每个历史步 29 测量到的关节位置减去 default_angles
dof_vel 每个历史步 29 关节速度项
last_actions 29 上一步的原始 actor 输出
3. 执行器接口

G1 部署原型将 actor 输出严格映射为:

复制代码
action * action_scale + default_angles

然后钳制到 joint_lower / joint_upper,并应用来自 ema_alpha 的 EMA 平滑。

4. 参考运动同步

相位变量让策略能够跟踪一个外部提供的运动片段。在硬件上你需要一个墙钟 → 相位的映射,它必须:

  • 单调 ------ 不向后跳跃
  • 可重启 ------ 在通信抖动后仍能存活,不会在 (sinφ,cosφ) 中产生阶跃式不连续
  • 速率有界 ------ 将 dφ/dt 钳制到策略训练时所用的值
5. 安全层

硬件侧安全层要求:

  • 在应用 action_scale 之前拒绝非有限动作与形状不匹配
  • deploy_config.yaml 中的 joint_lower / joint_upper 钳制生成的目标
  • 把看门狗、姿态监控以及操作员停止阈值保留在部署控制器中
6. 闭环上机序列
  1. 支架上站立:机器人由龙门架吊挂。策略运行,但执行器关闭力矩。确认观测管线。
  2. 使能力矩、手扶:操作员护着机器人。策略指挥执行器。确认动作映射。
  3. 龙门架支撑步态:以半时间速率跟踪运动(dφ/dt 减半)。
  4. 自由站立:全速率,然后移除龙门架。
7. 验证与记录

为每一步记录完整的观测向量、完整的动作向量与墙钟。在硬件上机前,通过 MuJoCo 部署原型验证:

bash 复制代码
uv run scripts/deploy/sim_prototype.py \
  --onnx runs/<run>/policy.onnx \
  --config logs/deploy/deploy_config.yaml \
  --motion logs/deploy/dance1.bin

ONNX 输入宽度与 deploy_config.yamlobs_dim 之间的不匹配是部署契约 bug,而不是硬件调参问题。

5.4 部署验证与调试

关键验证点:

  • ONNX 输入维度必须与部署配置中的 obs_dim 完全匹配
  • 动作映射必须与仿真中的执行器接口一致
  • 传感器预处理必须在仿真和硬件之间保持一致
  • 时序特性(延迟、采样率)必须在训练和部署之间匹配

调试建议:

  • 从简单的开环测试开始,逐步过渡到闭环
  • 记录完整的观测-动作轨迹,用于离线分析
  • 使用仿真原型验证部署配置,避免硬件损坏
  • 实现详细的日志记录,包括安全层触发事件

新增算法、新增不同地形,新增机器人任务,可以参考:https://unilabsim.github.io/UniLab-doc/zh_CN/4-developer_guide/0-index.html

分享完成~