# UniLab + MotrixSim 异构机器人 RL 训练复现 本章带大家在一台 6GB 显存的 Windows 笔记本上,跑通 UniLab 的 MotrixSim 后端和 PPO 训练流程。这个实验的主线是机器人 state-based RL:策略网络读取机器人状态、速度指令和历史观测,在 CPU 侧仿真里采样,再由 GPU learner 更新参数。渲染不是本章的核心方法,只作为 checkpoint 检查、结果展示和 MotrixSim PBR teaser 体验的辅助环节。 本次实测机器为 RTX 3060 Laptop 6GB、AMD Ryzen 7 5800H、64GB 内存。最终跑通了 `go2_joystick_flat + motrix + ppo`,最大实测配置为 `512` 个并行环境、`100` 个 training iteration,累计 `1,228,800` 个环境步。 ## 1. UniLab 在解决什么问题 UniLab 的核心思路是把机器人 RL 训练拆成两部分:CPU 侧负责大规模物理仿真和数据采集,GPU 侧负责策略网络学习。这样做的意义在于,大家不一定非要依赖 GPU 物理仿真器才能开始做大批量机器人 RL;只要 CPU 能并行推进足够多的环境,GPU 只需要承担 learner 的工作。  图 1 UniLab 官方系统架构图。大家需要重点看中间的 Runtime Flow Spine:CPU Workers 负责 MuJoCo/MotrixSim 仿真,Host IPC 负责共享内存、rollout 和 replay buffer,Device Learner 才是 CUDA / Apple / AMD / Intel 设备侧的学习模块。来源:[UniLab 官方项目页](https://unilabsim.github.io)。  图 2 UniLab 官方 pipeline timeline。它展示了仿真采样、Host-to-Device 数据移动和 learner 更新如何在异构流水线中排布。来源:[UniLab 官方项目页](https://unilabsim.github.io)。  图 3 UniLab 官方训练效率对比图。这里的完整性能结论需要严格按论文硬件和任务矩阵复现;本章只做 6GB 显卡上的轻量 smoke test 和资源占用记录。来源:[UniLab 官方项目页](https://unilabsim.github.io)。  图 4 UniLab 官方项目页中的 Go2 平地速度跟踪任务截图。本章选择同一个 `go2_joystick_flat` 任务,是因为它比人形舞蹈、灵巧手操作更适合作为第一轮训练 smoke test。来源:[UniLab 官方项目页](https://unilabsim.github.io)。 ## 2. 本章能复现到什么程度 这台 6GB 显卡可以跑小规模训练,但不建议把它当作完整论文复现平台。原因有两个:第一,论文中的 3-10x 端到端效率提升需要多任务、多算法、多硬件条件对比;第二,官方当前主要支持 Linux CUDA、Linux ROCm、Linux XPU 和 macOS,Windows 不在官方主路径内。 本章实测得到的结论更适合大家做入门判断: | 项目 | 本章状态 | | --- | --- | | UniLab 官方仓库克隆 | 已完成 | | MotrixSim 后端导入 | 已完成 | | CUDA 版 PyTorch | 已完成,`torch 2.7.0+cu128` | | `go2_joystick_flat` 训练 | 已完成 | | checkpoint 保存 | 已完成 | | 无渲染 eval | 已完成 | | MotrixSim record 视频 | 已完成 | | MuJoCo 后端 | Windows 下未跑通,卡在 `mujoco-uni` 构建 | | 完整论文 benchmark | 未复现,需要 Linux/云服务器和更系统的实验矩阵 | ## 3. 环境准备 官方推荐使用 `uv` 管理环境。本机已有 `micromamba` 的 `py310` 环境,所以这里没有新建 micromamba 环境,而是让 UniLab 在项目目录下创建自己的 `.venv`。这样做的好处是隔离 UniLab 依赖,不污染已有环境。 先把工作目录和仓库路径写成变量: ```powershell $WORKSPACE = "C:\path\to\workspace" $UNILAB_ROOT = "$WORKSPACE\UniLab" git clone https://github.com/unilabsim/UniLab.git $UNILAB_ROOT cd $UNILAB_ROOT ``` 如果大家在 Linux 上复现,优先走官方命令: ```bash make setup-motrix ``` 本机 Windows 实测时,`mujoco-uni==3.8.0` 没有可用的 Windows wheel,源码构建会要求 `MUJOCO_PATH`。为了先跑通 MotrixSim 路线,这里使用如下折中命令跳过 `mujoco-uni`: ```powershell uv sync --extra motrix --no-install-package mujoco-uni ` --python C:\path\to\micromamba\envs\py310\python.exe ``` 随后把项目 `.venv` 里的 PyTorch 换成 Windows CUDA 12.8 wheel: ```powershell uv pip install --python .\.venv\Scripts\python.exe --reinstall ` torch==2.7.0 --index-url https://download.pytorch.org/whl/cu128 ``` 检查 CUDA 是否可用: ```powershell $env:PYTHONPATH = "src" uv run --no-sync python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available()); print(torch.cuda.get_device_name(0))" ``` 本机输出为: ```text 2.7.0+cu128 12.8 True NVIDIA GeForce RTX 3060 Laptop GPU ``` ## 4. Checkpoint 1:先跑 256 环境的小规模训练 第一次建议大家不要直接使用官方默认的 `1024` 个环境。6GB 显存机器上先从 `256` 个环境开始,确认训练循环、日志和 checkpoint 都能正常工作。 ```powershell $env:PYTHONPATH = "src" $env:WANDB_MODE = "disabled" uv run --no-sync train --algo ppo --task go2_joystick_flat --sim motrix ` training.no_play=true training.device=cuda:0 ` algo.num_envs=256 algo.max_iterations=50 algo.save_interval=50 ``` 这个命令会做三件事:用 MotrixSim 在 CPU 侧推进 Go2 平地速度跟踪任务;用 CUDA 上的 PPO learner 更新策略;每 50 个 iteration 保存一次 checkpoint。`training.no_play=true` 会关闭训练后的交互回放,避免窗口渲染影响训练验证。 本机一次成功训练的摘要如下: | 指标 | 数值 | | --- | ---: | | 并行环境数 | 256 | | iteration | 50 | | `num_steps_per_env` | 24 | | 累计环境步 | 307,200 | | 训练 wall time | 51.30 s | | 最终 mean reward | 22.48 | | 最佳 mean reward | 25.52 | | 最终 checkpoint | `model_49.pt` | 这个 smoke test 证明了数据采集、GPU learner、日志写入、checkpoint 保存都能走通;它不能证明策略已经达到论文或官方 benchmark 水平。 ## 5. Checkpoint 2:512 环境、100 iteration 的资源占用 确认 256 环境能跑后,本机继续跑了 `512` 个环境、`100` 个 iteration,并用 `nvidia-smi`、Windows 计数器和进程 RSS 做了粗粒度监控。 ```powershell $env:PYTHONPATH = "src" $env:WANDB_MODE = "disabled" uv run --no-sync train --algo ppo --task go2_joystick_flat --sim motrix ` training.no_play=true training.device=cuda:0 ` algo.num_envs=512 algo.max_iterations=100 algo.save_interval=50 ``` 训练摘要: | 指标 | 数值 | | --- | ---: | | 并行环境数 | 512 | | iteration | 100 | | 累计环境步 | 1,228,800 | | 训练 wall time | 132.90 s | | 外层监控记录时长 | 141.94 s | | 最终 mean reward | 34.97 | | 最佳 mean reward | 37.40 | | 平均 episode length | 1000.0 | 资源占用记录: | 资源项 | 平均值 | 峰值 | 说明 | | --- | ---: | ---: | --- | | GPU 显存 | 233 MiB | 263 MiB | 只包含 `nvidia-smi` 采样值,说明策略网络本身很轻 | | GPU 利用率 | 13.54% | 60% | learner 间歇更新,利用率不会长期打满 | | 系统 CPU 使用率 | 62.80% | 81.05% | MotrixSim/CPU 并行仿真是主要负载 | | 系统内存已用 | 31.22 GiB | 32.24 GiB | 包含系统和后台程序,不是 UniLab 独占 | | UniLab 相关 Python RSS | 1397 MiB | 1538 MiB | 由相关 Python/uv 进程工作集估算 | 监控文件保存在: - `assets/local_runs/20260531-210237/resource_monitor.csv` - `assets/local_runs/20260531-210237/resource_summary_512x100.json` - `assets/local_runs/20260531-210237/train_summary_512x100.json` 从这组数据可以看出,6GB 显卡不是这个轻量任务的瓶颈,CPU 才是更明显的压力来源。这也符合 UniLab 的设计:CPU 侧承担物理仿真,GPU 侧只处理策略学习。 ## 6. Checkpoint 3:导出 MotrixSim 训练回放 Windows 下如果仓库路径包含中文,`eval --render-mode record` 在导出 TorchScript 策略时可能报错: ```text RuntimeError: Parent directory ... does not exist. ``` 本机的原因是原始路径里含有中文,TorchScript 保存时没有正确处理这个路径。解决办法是把训练日志根目录放到 ASCII 路径,例如 `C:/unilab_logs`。 ```powershell $env:PYTHONPATH = "src" $env:WANDB_MODE = "disabled" uv run --no-sync train --algo ppo --task go2_joystick_flat --sim motrix ` training.no_play=true training.device=cuda:0 training.log_root=C:/unilab_logs ` algo.num_envs=256 algo.max_iterations=50 algo.save_interval=50 ``` 这里导出的是训练后 checkpoint 的策略回放,不是 PBR teaser。它的作用是验证 state-based policy 能被加载,并能在 MotrixSim 里稳定推进若干步。 多环境回放: ```powershell uv run --no-sync eval --algo ppo --task go2_joystick_flat --sim motrix ` --load-run -1 --render-mode record ` training.log_root=C:/unilab_logs ` training.play_steps=300 training.play_env_num=4 training.render_spacing=1.4 ``` 单环境跟随视角回放: ```powershell uv run --no-sync eval --algo ppo --task go2_joystick_flat --sim motrix ` --load-run -1 --render-mode record ` training.log_root=C:/unilab_logs ` training.play_steps=300 training.play_env_num=1 ` training.cam_tracking=true training.cam_distance=4.0 training.cam_elevation=-15.0 ``` 图 5 本机导出的 4 环境 MotrixSim 回放视频。它验证了 checkpoint 可以被加载,并能驱动 MotrixSim 录制 300 step 的策略回放。 图 6 本机导出的单环境跟随视角视频。这个视频更适合检查机器人姿态和动作是否连续。 如果网页构建器不直接显示视频,可以先看两张视频抽帧:  图 7 4 环境回放抽帧。  图 8 单环境回放抽帧。 ## 7. 扩展体验:MotrixSim PBR teaser 渲染器 UniLab 这条工作线重点不是做渲染 benchmark,但 MotrixSim 的渲染器已经支持 PBR。官方仓库里提供了一个独立的 teaser 入口,大家可以把它当作视觉体验教程来跑:它加载论文 teaser 场景,打开 MotrixSim renderer,并保持静态场景显示;它不训练策略,也不推进 RL rollout。 在 UniLab 仓库根目录运行: ```powershell $env:PYTHONPATH = "src" uv run --no-sync demo teaser ``` 第一次运行会自动下载 teaser scene 资产。下载完成后,程序会进入 `src/unilab/tools/render_teaser.py`,调用 `RenderSettings.quality()`,并启用 shadow、SSGI 和完整 render mesh。窗口打开后可以通过 renderer 交互查看场景;关闭窗口即可退出。 本机为了稳定截取多视角图片,使用了 MotrixSim 的 headless system camera capture,而不是录制聊天视频或截屏幕前台窗口。核心思路是加载同一个 teaser MJCF 场景,然后多次调整: ```python render.system_camera.set_view(lookat, distance, elevation, azimuth) ``` 在场景资产已经下载完成后,本机导出 3 张 `1280x720` PNG 截图约用 `24 s`。首次运行会额外下载 `scenes/teaser` 资产;如果日志里出现 `convex hull partial success`、`Duplicate AssetLoader` 或 `wgpu_core::validation` 这类 warning,只要截图正常生成,一般可以先当作渲染器初始化提示处理。 下面三张图都来自本机实际运行的 MotrixSim PBR renderer。
![]() |
![]() |
| 图 9 PBR teaser 主视角。这里可以看到反光地面、强光入口、机器人和纸箱等展示资产。 | 图 10 PBR teaser 左侧高位视角。这个角度更容易观察场景整体布置和阴影层次。 |