This commit is contained in:
linux5880
2026-08-01 15:02:43 +08:00
parent 269aac5116
commit 6441d9ad35

View File

@@ -2,30 +2,39 @@
> 本教程基于西安交通大学 RoboGauge 团队的研究成果 [Toward Reliable Sim-to-Real Predictability for MoE-based Robust Quadrupedal Locomotion](https://robogauge.github.io/static/files/arxiv.pdf) 及其[项目主页](https://robogauge.github.io/complete/),将原始 Go2 训练任务适配为 Unitree Go1并串联 IsaacLab 训练、RoboGauge 评估、MuJoCo sim2sim、ONNX 导出、RDK X5/S100 BPU 量化和 sim2real。 > 本教程基于西安交通大学 RoboGauge 团队的研究成果 [Toward Reliable Sim-to-Real Predictability for MoE-based Robust Quadrupedal Locomotion](https://robogauge.github.io/static/files/arxiv.pdf) 及其[项目主页](https://robogauge.github.io/complete/),将原始 Go2 训练任务适配为 Unitree Go1并串联 IsaacLab 训练、RoboGauge 评估、MuJoCo sim2sim、ONNX 导出、RDK X5/S100 BPU 量化和 sim2real。
> >
> 本文依据当前本地仓库代码和本次 Go1 训练记录整理。IsaacLab 训练、模型导出以及 RoboGauge 单模型评估命令已在训练机上验证全新环境安装、BPU 量化和实机命令仍需在目标设备上逐条复核。不要整段复制后无人值守运行。 > 本文依据当前本地仓库代码和本次 Go1 训练记录整理。已验证 1 轮 IsaacLab 训练、ONNX 接口与推理、MuJoCo 采样、RoboGauge 单任务评估,以及使用 ONNX 推理采样数据完成 X5/S100 PTQ 编译的链路。板端数值、延迟和硬件命令仍需在对应设备上逐条复核。不要整段复制后无人值守运行。
## 1. 教程范围与版本约定 ## 1. 教程范围与版本约定
### 1.1 仓库 ### 1.1 仓库
| 用途 | 仓库或目录 | | 用途 | 镜像内目录 | 本次验证版本 |
| --- | --- | | --- | --- | --- |
| IsaacLab 训练与自带 MuJoCo 部署 | `go2_rl_robotlab` `go1` 分支 | | IsaacLab 源码 | `/opt/IsaacLab` | `v2.3.2` |
| 自动化 sim2sim 评估 | `RoboGauge``go1` 分支 | | IsaacLab 训练与自带 MuJoCo 部署 | `/opt/go2_rl_robotlab``go1` 分支 | `f40874bc90c72264dbf46989d90e15a9715c1393` |
| 独立 MuJoCo、ONNX、X5/S100 BPU 部署 | `go1_pro_deploy/deploy_45dim_rl_gym` | | 自动化 sim2sim 评估 | `/opt/RoboGauge``go1` 分支 | `66d0eb9010dabc501c52a8b9e5ffb2149dbcb82b` |
| 独立 MuJoCo、ONNX、X5/S100 BPU 部署 | `/opt/go1_pro_deploy/deploy_45dim_rl_gym` | `22a13d6659c59e2793b08c767ab69d8fcc0a406b` |
| 官方公开 SDK | [unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk) | | 官方公开 SDK | [unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk) |
| 私有 Go1 PRO SDK | 仅在内部部署机使用,本文不公开协议、密钥和专有接口 | | 私有 Go1 PRO SDK | 仅在内部部署机使用,本文不公开协议、密钥和专有接口 |
本文有两条使用路径:
- **路径 A直接使用交付镜像**:不要重新 clone 或重新安装,使用 `/opt` 下的固定目录和解释器。
- **路径 B没有镜像**:按 3.4 节拉取仓库并安装,但仓库、虚拟环境、日志和产物仍全部放在 `/opt`
除第 11 至 14 节明确标注的 X5/S100 板端命令外,文中的 `/root/...` 不适用于训练镜像。训练镜像不得把环境或项目放到用户 home 目录。
本次训练在约 33540 轮手动停止,最后一个完整保存的检查点是 `model_33500.pt`。综合当前单 seed RoboGauge 结果,本文仍用 **26000 轮检查点**作为平地与三级楼梯之间较均衡的部署基线33500 是最新候选,而不是无条件替代 26000。示例发布名称如下 本次训练在约 33540 轮手动停止,最后一个完整保存的检查点是 `model_33500.pt`。综合当前单 seed RoboGauge 结果,本文仍用 **26000 轮检查点**作为平地与三级楼梯之间较均衡的部署基线33500 是最新候选,而不是无条件替代 26000。示例发布名称如下
```text ```text
训练检查点: model_26000.pt 训练检查点: model_26000.pt
浮点模型: policy_robotlab_26000.onnx TorchScript: policy_robotlab_26000_post_command_curriculum.pt
浮点模型: policy_robotlab_26000_post_command_curriculum.onnx
X5 模型: policy_robotlab_26000_int16_gemm.bin X5 模型: policy_robotlab_26000_int16_gemm.bin
S100 模型: policy_robotlab_26000_s100_int16_gemm.hbm S100 模型: policy_robotlab_26000_s100_int16_gemm.hbm
``` ```
训练目录中的导出文件会保留课程阶段,例如 `policy_robotlab_26000_post_command_curriculum.onnx`;确定发布版本后可再复制为上面的短名称。26000 只是当前均衡基线,不表示轮数越大一定越好。若任务以上楼梯为主,应同时保留 15000 和 26000若以平地高速或下楼梯为主可继续比较 33500。最终模型仍应根据多 seed RoboGauge、MuJoCo 回放和真机日志共同选择。 训练目录中的导出文件会保留课程阶段。量化脚本使用 `--name policy_robotlab_26000` 时会生成上面的 X5/S100 短名称TorchScript/ONNX 是否另存为不带课程后缀的别名必须在发布记录中明确。26000 只是当前均衡基线,不表示轮数越大一定越好。若任务以上楼梯为主,应同时保留 15000 和 26000若以平地高速或下楼梯为主可继续比较 33500。最终模型仍应根据多 seed RoboGauge、MuJoCo 回放和真机日志共同选择。
### 1.2 全流程 ### 1.2 全流程
@@ -38,7 +47,7 @@ Go1 模型与任务适配
-> RoboGauge 自动评估 -> RoboGauge 自动评估
-> 独立 MuJoCo sim2sim -> 独立 MuJoCo sim2sim
-> ONNX 实机只读和悬空测试 -> ONNX 实机只读和悬空测试
-> 用真实日志制作 BPU 校准集 -> 用 ONNX 推理生成 PTQ 校验基准
-> X5/S100 量化与离线对齐 -> X5/S100 量化与离线对齐
-> BPU 悬空对照 -> BPU 悬空对照
-> 低速地面测试 -> 低速地面测试
@@ -68,58 +77,230 @@ Go1 模型与任务适配
RoboGauge 当前关注的指标包括关节软限位、线/角速度误差、电机功耗、姿态稳定性、力矩平滑度、摩擦裕度和 ZMP 裕度。归一化后均按“越大越好”解释,但任何综合分数都不能替代分项检查。 RoboGauge 当前关注的指标包括关节软限位、线/角速度误差、电机功耗、姿态稳定性、力矩平滑度、摩擦裕度和 ZMP 裕度。归一化后均按“越大越好”解释,但任何综合分数都不能替代分项检查。
## 3. 训练环境 ## 3. 两种环境准备方式
### 3.1 硬件与软件前提 ### 3.1 硬件与软件前提
- NVIDIA GPU 和匹配的驱动。 - NVIDIA GPU 和匹配的驱动。
- Linux 训练环境;图形界面训练不是必须。 - Linux 训练环境;图形界面训练不是必须。
- Python 3.11。 - Python 3.11。
- IsaacLab/Isaac Sim 2.3.2 对应依赖 - IsaacLab `2.3.2.post1` 和 Isaac Sim `5.1.0.0`
- 足够的磁盘空间保存检查点、TensorBoard 日志和导出模型。 - 足够的磁盘空间保存检查点、TensorBoard 日志和导出模型。
### 3.2 RoboGo 镜像 ### 3.2 路径 A直接使用交付镜像
此处由维护者补充平台镜像信息 以下信息在当前工作区无法从文件和 Docker 本地缓存推断,属于交付前必须填写的镜像元数据
```text ```text
TODO(维护者填写) 交付阻断项(维护者填写)
RoboGo 镜像名称: RoboGo 镜像名称:
镜像拉取命令: 镜像拉取命令:
容器启动参数: 容器启动参数:
训练数据持久化目录: 训练数据持久化目录:
``` ```
若镜像已包含 IsaacLab、项目仓库和依赖可跳过下一节的手工安装但仍需核对代码分支和版本。 量化工具链不依赖交付镜像本身的 CUDA 环境,已单独归档到 `/opt`
### 3.3 手工安装 ```text
/opt/envs/go2_rl_robotlab/docker-toolchain/images/openexplorer_ai_toolchain_ubuntu_20_x5_cpu_v1.2.8.tar
/opt/envs/go2_rl_robotlab/docker-toolchain/images/ai_toolchain_ubuntu_22_s100_s600_cpu_v3.7.0.tar
```
归档内只有 Docker CLI 和工具链镜像,不包含也不应在交付镜像内自行启动 `dockerd`。量化时应连接宿主 Docker daemon先执行 `docker load -i <归档>`,再运行第 11 节脚本。本次已实际加载并验证两个归档。
如果交付镜像本身运行在 Docker 中,需要由宿主在创建容器时挂载 Docker socket
```bash ```bash
conda create -n go2_rl_robotlab python=3.11 -y # 以下在宿主执行,放入实际的 docker run 参数中
conda activate go2_rl_robotlab docker run ... \
-v /var/run/docker.sock:/var/run/docker.sock \
<RoboGo镜像>
```
进入容器后验收 CLI 和 daemon
```bash
sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker info
sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker image inspect openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8
sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker image inspect registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0
```
本次验证 daemon 的 `DockerRootDir` 是宿主 `/var/lib/docker`。交付所需的 CLI、配置和可重新加载的镜像归档都在 `/opt/envs/go2_rl_robotlab/docker-toolchain``docker load` 之后的展开层属于宿主 daemon 缓存,不会被保存进 RoboGo 交付镜像。如果专用量化主机要求 Docker 展开层也位于 `/opt`,应由主机管理员在首次 `docker load` 之前设置 daemon不要在共享 Docker 主机上盲目更改:
```json
{
"data-root": "/opt/envs/go2_rl_robotlab/docker-toolchain/docker-data"
}
```
上述内容应合并到宿主 `/etc/docker/daemon.json`,然后由管理员重启 Docker 并用 `docker info --format '{{.DockerRootDir}}'` 验收。修改数据根目录会影响该 daemon 管理的所有镜像和容器,不是普通容器内步骤。
镜像内目录必须固定如下:
```text
/opt/IsaacLab
/opt/go2_rl_robotlab
/opt/RoboGauge
/opt/go1_pro_deploy
/opt/envs/go2_rl_robotlab
/opt/envs/robogauge
```
直接使用镜像时跳过 3.4 节。首次进入容器先执行验收,不要看到 `/opt/IsaacLab` 存在就默认版本正确:
```bash
export OMNI_KIT_ACCEPT_EULA=YES
export MPLCONFIGDIR=/tmp/robogauge-matplotlib
test -d /opt/IsaacLab
test -d /opt/go2_rl_robotlab
test -d /opt/RoboGauge
test -d /opt/go1_pro_deploy
test -x /opt/envs/go2_rl_robotlab/bin/python
test -x /opt/envs/robogauge/bin/python
nvidia-smi
git --git-dir=/opt/IsaacLab/.git --work-tree=/opt/IsaacLab describe --tags --always
/opt/envs/go2_rl_robotlab/bin/python -c "import isaaclab, torch; import importlib.metadata as m; print('isaaclab', m.version('isaaclab')); print('isaacsim', m.version('isaacsim')); print('torch', torch.__version__)"
```
预期为 IsaacLab `v2.3.2`/`2.3.2.post1`、Isaac Sim `5.1.0.0`、PyTorch `2.7.0`。IsaacLab `v2.2.0` 搭配 Isaac Sim `5.0.0` 与当前 `go1` 分支不兼容,不能作为交付镜像发布。本次检查发现原始 `/opt/IsaacLab` 正是该不兼容组合;镜像维护者必须在发布层将 `/opt/IsaacLab` 替换为 `v2.3.2`,不能只在另一个临时目录安装新版后继续交付旧路径。
Pip 版 Isaac Sim 首次启动必须接受 EULA。建议把下面变量写入镜像运行环境而不是只写在某个用户的 shell 历史中:
```bash
export OMNI_KIT_ACCEPT_EULA=YES
```
下列目录会在训练或评估时写入,镜像构建阶段必须由 root 预建并授予实际容器用户写权限:
```text
/opt/go2_rl_robotlab/logs
/opt/go2_rl_robotlab/outputs
/opt/RoboGauge/logs
/opt/RoboGauge/outputs
/opt/go1_pro_deploy/logs
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/cache
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/logs
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data/Kit/Isaac-Sim/5.1/user.config.json
```
Dockerfile 中应使用交付镜像的实际运行 UID/GID下面的 `APP_UID/APP_GID` 只是占位符):
```dockerfile
RUN install -d -m 0775 /opt/go2_rl_robotlab/logs /opt/go2_rl_robotlab/outputs \
/opt/RoboGauge/logs /opt/RoboGauge/outputs \
/opt/go1_pro_deploy/logs \
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/cache \
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data \
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/logs \
&& chown -R ${APP_UID}:${APP_GID} /opt/go2_rl_robotlab/logs /opt/go2_rl_robotlab/outputs \
/opt/RoboGauge/logs /opt/RoboGauge/outputs \
/opt/go1_pro_deploy/logs \
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/cache \
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data \
/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/logs
```
运行用户验收:
```bash
test -w /opt/go2_rl_robotlab/logs
test -w /opt/go2_rl_robotlab/outputs
test -w /opt/RoboGauge/logs
test -w /opt/RoboGauge/outputs
test -w /opt/go1_pro_deploy/logs
test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/cache
test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data
test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/logs
test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data/Kit/Isaac-Sim/5.1/user.config.json
```
`/opt/IsaacSim` 清理后RoboGauge 环境的 `bin/python3` 不得继续指向旧路径;应指向 `/opt/envs/go2_rl_robotlab/python-runtime`,并把 `/opt/RoboGauge` 和 RoboGauge 自己的 `site-packages` 放入 `PYTHONPATH`。否则第 9 节会在导入前直接报 `No such file or directory`
本流程以 `/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim` 中的 pip 版 Isaac Sim `5.1.0.0` 为准。旧的独立 `/opt/IsaacSim` `5.0.0` 已从运行环境移除;不要重新挂载它的 `PYTHONPATH``python.sh`
若仓库由镜像构建用户创建、运行用户不同,普通 `git status` 可能报 `dubious ownership`。镜像应优先统一目录属主;只读检查也可使用 `git --git-dir=/opt/<REPO>/.git --work-tree=/opt/<REPO> ...`,不要为省事把所有系统目录加入 Git safe.directory。
### 3.3 镜像训练链路自检
正式训练前先跑 1 轮。以下命令已在目标镜像运行环境中以 16 个环境验证,完成 384 个 transition用时约 5.23 秒;发布镜像仍必须先通过 3.2 节的版本和写权限验收:
```bash
cd /opt/go2_rl_robotlab
OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py \
--task=RobotLab-Go1-v0 \
--num_envs=16 \
--max_iterations=1 \
--run_name=image_direct_1iter \
--logger=tensorboard \
--headless
```
确认新目录中至少有 `model_0.pt``train.log`、TensorBoard event、`params/env.yaml``params/agent.yaml`
```bash
find /opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts -path '*image_direct_1iter*' -type f -print
```
本次自检 checkpoint 的 SHA-256 为 `14589a131b09680bbbd10427ad6d5f90dd4cf3a0cc57b6f516c4de2ef1b0cbe3`。该文件仅证明训练链路可运行,不是可部署策略。
### 3.4 路径 B没有镜像时从零安装
以下命令假设主机已安装 NVIDIA 驱动、Docker量化时需要和 CondaConda/Miniforge 本身也应安装在 `/opt`。即使没有镜像,也统一把项目与 Conda prefix 放到 `/opt`
```bash
sudo install -d -o "$USER" -g "$(id -gn)" /opt/envs /opt/IsaacLab
sudo install -d -o "$USER" -g "$(id -gn)" /opt/go2_rl_robotlab /opt/RoboGauge /opt/go1_pro_deploy
conda create --prefix /opt/envs/go2_rl_robotlab python=3.11 -y
conda activate /opt/envs/go2_rl_robotlab
python -m pip install --upgrade pip python -m pip install --upgrade pip
python -m pip install "isaaclab[isaacsim,all]==2.3.2.post1" --extra-index-url https://pypi.nvidia.com python -m pip install "isaaclab[isaacsim,all]==2.3.2.post1" --extra-index-url https://pypi.nvidia.com
python -m pip install torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128 python -m pip install torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128
``` ```
拉取 Go1 分支并安装项目内定制包 拉取固定分支。内部 Gitea 地址需要相应读取权限;没有权限时应向交付方获取源码归档及 commit 校验,不能退回公开仓库的不同分支假装等价
```bash ```bash
git clone --branch go1 --single-branch https://github.com/wertyuilife2/go2_rl_robotlab.git git clone --branch v2.3.2 --depth 1 https://github.com/isaac-sim/IsaacLab.git /opt/IsaacLab
cd go2_rl_robotlab git clone --branch go1 --single-branch https://gitea.qingruxu.xyz/cyy/go2_rl_robotlab.git /opt/go2_rl_robotlab
git clone --branch go1 --single-branch https://gitea.qingruxu.xyz/cyy/RoboGauge.git /opt/RoboGauge
git clone --branch main --single-branch https://gitea.qingruxu.xyz/cyy/go1_pro_deploy.git /opt/go1_pro_deploy
cd /opt/go2_rl_robotlab
python -m pip install -e source/robot_lab python -m pip install -e source/robot_lab
python -m pip install -e source/rsl_rl python -m pip install -e source/rsl_rl
python -m pip install mujoco pygame onnx onnxruntime tensorboard python -m pip install tensordict onnx onnxscript onnxruntime mujoco pygame tensorboard
```
RoboGauge 使用独立环境,避免其 `mujoco==3.2.3``dm_control==1.0.23``numpy<2` 约束影响 IsaacLab。必须先固定 PyTorch防止无上限的 `torch` 依赖在未来解析成 CUDA 13 等大体积版本:
```bash
conda create --prefix /opt/envs/robogauge python=3.11 -y
conda activate /opt/envs/robogauge
python -m pip install torch==2.7.0 --index-url https://download.pytorch.org/whl/cpu
cd /opt/RoboGauge
python -m pip install -e /opt/RoboGauge
```
最后由管理员创建运行目录并交给实际运行用户:
```bash
sudo install -d -o "$USER" -g "$(id -gn)" /opt/go2_rl_robotlab/logs /opt/go2_rl_robotlab/outputs
sudo install -d -o "$USER" -g "$(id -gn)" /opt/RoboGauge/logs /opt/RoboGauge/outputs
sudo install -d -o "$USER" -g "$(id -gn)" /opt/go1_pro_deploy/logs
``` ```
记录环境,便于在部署前复现: 记录环境,便于在部署前复现:
```bash ```bash
git rev-parse HEAD git --git-dir=/opt/go2_rl_robotlab/.git --work-tree=/opt/go2_rl_robotlab rev-parse HEAD
python --version /opt/envs/go2_rl_robotlab/bin/python --version
python -m pip freeze > requirements-lock.txt /opt/envs/go2_rl_robotlab/bin/python -m pip freeze > /opt/go2_rl_robotlab/requirements-lock.txt
nvidia-smi nvidia-smi
``` ```
@@ -277,10 +458,12 @@ max_iterations = 300000通常通过命令行覆盖
建议从小到大试探: 建议从小到大试探:
```bash ```bash
python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=512 --max_iterations=20 --headless cd /opt/go2_rl_robotlab
python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=1024 --max_iterations=20 --headless export OMNI_KIT_ACCEPT_EULA=YES
python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=2048 --max_iterations=20 --headless /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=512 --max_iterations=20 --headless
python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=4096 --max_iterations=20 --headless /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=1024 --max_iterations=20 --headless
/opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=2048 --max_iterations=20 --headless
/opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py --task=RobotLab-Go1-v0 --num_envs=4096 --max_iterations=20 --headless
``` ```
另开终端观察: 另开终端观察:
@@ -294,10 +477,10 @@ watch -n 1 nvidia-smi
### 6.2 正式训练并保留候选检查点 ### 6.2 正式训练并保留候选检查点
```bash ```bash
cd go2_rl_robotlab cd /opt/go2_rl_robotlab
conda activate go2_rl_robotlab export OMNI_KIT_ACCEPT_EULA=YES
python scripts/rsl_rl/train.py \ /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py \
--task=RobotLab-Go1-v0 \ --task=RobotLab-Go1-v0 \
--num_envs=4096 \ --num_envs=4096 \
--max_iterations=33500 \ --max_iterations=33500 \
@@ -309,13 +492,13 @@ python scripts/rsl_rl/train.py \
日志默认位于: 日志默认位于:
```text ```text
logs/rsl_rl/go1_moe_cts/<时间戳>_go1_4096x24/ /opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts/<时间戳>_go1_4096x24/
``` ```
检查点每 500 轮保存一次。不要只保留最后一个文件,至少确认课程切换前后和最终候选都存在: 检查点每 500 轮保存一次。不要只保留最后一个文件,至少确认课程切换前后和最终候选都存在:
```bash ```bash
find logs/rsl_rl/go1_moe_cts -name 'model_*.pt' -print | sort -V find /opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts -name 'model_*.pt' -print | sort -V
``` ```
本次实际 run 保留了 `model_15000.pt``model_19500.pt``model_26000.pt``model_33500.pt`。若训练进程被 `Ctrl+C` 中断,以磁盘上最后一个完整 checkpoint 为准;本次停止日志到 33540 左右,但 33540 没有保存,不能把 33500 标成 33540。 本次实际 run 保留了 `model_15000.pt``model_19500.pt``model_26000.pt``model_33500.pt`。若训练进程被 `Ctrl+C` 中断,以磁盘上最后一个完整 checkpoint 为准;本次停止日志到 33540 左右,但 33540 没有保存,不能把 33500 标成 33540。
@@ -323,7 +506,7 @@ find logs/rsl_rl/go1_moe_cts -name 'model_*.pt' -print | sort -V
### 6.3 断点续训 ### 6.3 断点续训
```bash ```bash
python scripts/rsl_rl/train.py \ OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python /opt/go2_rl_robotlab/scripts/rsl_rl/train.py \
--task=RobotLab-Go1-v0 \ --task=RobotLab-Go1-v0 \
--num_envs=4096 \ --num_envs=4096 \
--max_iterations=3000 \ --max_iterations=3000 \
@@ -340,7 +523,7 @@ python scripts/rsl_rl/train.py \
训练机执行: 训练机执行:
```bash ```bash
tensorboard --logdir logs/rsl_rl --port 6006 /opt/envs/go2_rl_robotlab/bin/python -m tensorboard.main --logdir /opt/go2_rl_robotlab/logs/rsl_rl --port 6006
``` ```
从本机通过 SSH 查看远端 TensorBoard 从本机通过 SSH 查看远端 TensorBoard
@@ -373,10 +556,11 @@ ssh -L 6006:127.0.0.1:6006 <USER>@<TRAIN_HOST>
`play.py` 加载 checkpoint 后,会先在同一 run 的 `exported/` 下生成 `policy.pt``policy.onnx`,再进入可视化 rollout `play.py` 加载 checkpoint 后,会先在同一 run 的 `exported/` 下生成 `policy.pt``policy.onnx`,再进入可视化 rollout
```bash ```bash
python scripts/rsl_rl/play.py \ cd /opt/go2_rl_robotlab
OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/play.py \
--task=RobotLab-Go1-v0 \ --task=RobotLab-Go1-v0 \
--num_envs=64 \ --num_envs=64 \
--checkpoint=/absolute/path/to/model_26000.pt --checkpoint=/opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts/<RUN_NAME>/model_26000.pt
``` ```
输出: 输出:
@@ -389,8 +573,9 @@ python scripts/rsl_rl/play.py \
同一 run 下再次导出会覆盖这两个通用文件名。必须在切换到下一个 checkpoint 前复制并带上轮次、课程阶段;导出文件完整写入后才能终止 play 同一 run 下再次导出会覆盖这两个通用文件名。必须在切换到下一个 checkpoint 前复制并带上轮次、课程阶段;导出文件完整写入后才能终止 play
```bash ```bash
cp <RUN_DIR>/exported/policy.onnx /path/to/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx cp <RUN_DIR>/exported/policy.onnx /opt/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx
cp <RUN_DIR>/exported/policy.pt /path/to/RoboGauge/resources/models/go1/policy_robotlab_26000.pt cp <RUN_DIR>/exported/policy.onnx /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.onnx
cp <RUN_DIR>/exported/policy.pt /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt
``` ```
RoboGauge 当前通过 `torch.jit.load()` 使用 TorchScript `.pt`ONNX 用于独立 MuJoCo、量化和实机部署。两者不能只靠改后缀互换。 RoboGauge 当前通过 `torch.jit.load()` 使用 TorchScript `.pt`ONNX 用于独立 MuJoCo、量化和实机部署。两者不能只靠改后缀互换。
@@ -400,10 +585,11 @@ RoboGauge 当前通过 `torch.jit.load()` 使用 TorchScript `.pt`ONNX 用于
训练 runner 保存的是可恢复训练的 checkpoint不会默认在每次保存时生成 ONNX。`play.py` 即使使用 `--headless` 也会启动 Isaac Sim 和一个环境,不是纯模型导出器。要保持主训练进程运行,只应在另一块 GPU、另一台机器或确认剩余显存足够时启动独立 `play.py` 训练 runner 保存的是可恢复训练的 checkpoint不会默认在每次保存时生成 ONNX。`play.py` 即使使用 `--headless` 也会启动 Isaac Sim 和一个环境,不是纯模型导出器。要保持主训练进程运行,只应在另一块 GPU、另一台机器或确认剩余显存足够时启动独立 `play.py`
```bash ```bash
CUDA_VISIBLE_DEVICES=1 python scripts/rsl_rl/play.py \ cd /opt/go2_rl_robotlab
OMNI_KIT_ACCEPT_EULA=YES CUDA_VISIBLE_DEVICES=1 /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/play.py \
--task=RobotLab-Go1-v0 \ --task=RobotLab-Go1-v0 \
--num_envs=1 \ --num_envs=1 \
--checkpoint=/absolute/path/to/model_26000.pt \ --checkpoint=/opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts/<RUN_NAME>/model_26000.pt \
--headless --headless
``` ```
@@ -417,7 +603,7 @@ CUDA_VISIBLE_DEVICES=1 python scripts/rsl_rl/play.py \
### 8.3 检查 ONNX 接口 ### 8.3 检查 ONNX 接口
```bash ```bash
python -c "import onnxruntime as ort; s=ort.InferenceSession('policy_robotlab_26000.onnx'); print([(x.name,x.shape,x.type) for x in s.get_inputs()]); print([(x.name,x.shape,x.type) for x in s.get_outputs()])" /opt/envs/go2_rl_robotlab/bin/python -c "import onnx, onnxruntime as ort; p='/opt/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx'; onnx.checker.check_model(onnx.load(p)); s=ort.InferenceSession(p, providers=['CPUExecutionProvider']); print([(x.name,x.shape,x.type) for x in s.get_inputs()]); print([(x.name,x.shape,x.type) for x in s.get_outputs()])"
``` ```
预期 ONNX 输入为 `obs: [1, 450] float32`,输出为 `actions: [1, 12] float32`。本次导出的 19500、26000 和 33500 ONNX 均已通过 `onnx.checker.check_model()`。输入输出不匹配时不要继续 sim2sim 或量化。 预期 ONNX 输入为 `obs: [1, 450] float32`,输出为 `actions: [1, 12] float32`。本次导出的 19500、26000 和 33500 ONNX 均已通过 `onnx.checker.check_model()`。输入输出不匹配时不要继续 sim2sim 或量化。
@@ -426,18 +612,27 @@ python -c "import onnxruntime as ort; s=ort.InferenceSession('policy_robotlab_26
如果你要做的是“和部署链路一致”的快速检查,直接使用部署仓库里的 ONNX 入口。它读取当前 45 维单帧观测,并在脚本内部维护 10 帧历史,适合在进入完整 RoboGauge 评估前核对观测、动作缩放和地形 XML 如果你要做的是“和部署链路一致”的快速检查,直接使用部署仓库里的 ONNX 入口。它读取当前 45 维单帧观测,并在脚本内部维护 10 帧历史,适合在进入完整 RoboGauge 评估前核对观测、动作缩放和地形 XML
Linux 不需要 `mjpython`;它主要用于 macOS 的 MuJoCo 图形启动。镜像中用绝对 ONNX 路径执行非交互采样。该脚本会在加载模型前切换工作目录,相对 ONNX 路径可能因此失效:
```bash ```bash
cd /path/to/go1_pro_deploy cd /opt/go1_pro_deploy/deploy_45dim_rl_gym
MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \ env -u MUJOCO_GL /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx --onnx /opt/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx \
--sample \
--sample-seconds 1 \
--sample-log-dir /opt/go1_pro_deploy/logs
``` ```
采样目录名固定以 `mujoco_stairs_sample_` 开头,用于保存独立 MuJoCo ONNX 推理检查日志PTQ 使用第 11 节的正式 64 样本校验集。
楼梯测试同样直接切 terrain 楼梯测试同样直接切 terrain
```bash ```bash
MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \ env -u MUJOCO_GL /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx \ --onnx /opt/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx \
--terrain deploy_45dim_rl_gym/terrains/stairs/stairs_3.xml \ --sample-stairs-level 3 \
--sample-seconds 20 \
--sample-log-dir /opt/go1_pro_deploy/logs \
--spawn-x -0.6 \ --spawn-x -0.6 \
--spawn-z 0.34 --spawn-z 0.34
``` ```
@@ -448,40 +643,46 @@ MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \
### 9.1 安装 ### 9.1 安装
建议使用独立环境,因为当前 RoboGauge 固定了 `mujoco==3.2.3``dm_control==1.0.23``numpy<2` 路径 A 的镜像用户不再安装,先检查解释器、任务注册和模型
```bash ```bash
conda create -n robogauge python=3.10 -y test -x /opt/envs/robogauge/bin/python
conda activate robogauge test -f /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt
test -w /opt/RoboGauge/logs
git clone https://github.com/wty-yy/RoboGauge.git cd /opt/RoboGauge
cd RoboGauge /opt/envs/robogauge/bin/python -c "import torch, mujoco, numpy; print('torch', torch.__version__); print('mujoco', mujoco.__version__); print('numpy', numpy.__version__)"
/opt/envs/robogauge/bin/python -c "import robogauge.tasks; from robogauge.utils.task_register import task_register; print(*sorted(task_register.pipeline_classes), sep='\n')" | grep '^go1_lab\.'
```
# go1 分支当前维护在私有派生仓库;有权限时再执行 路径 B 的无镜像用户按 3.4 节 clone 后,单独创建环境。当前 RoboGauge 固定了 `mujoco==3.2.3``dm_control==1.0.23``numpy<2`;先安装固定的 CPU PyTorch再安装仓库避免 `setup.py` 中无上限的 `torch` 自动选中未来的大体积 CUDA 构建:
git remote add go1-private <GO1_ROBOGAUGE_REPOSITORY_URL>
git fetch go1-private go1
git switch -c go1 --track go1-private/go1
```bash
conda create --prefix /opt/envs/robogauge python=3.11 -y
conda activate /opt/envs/robogauge
python -m pip install torch==2.7.0 --index-url https://download.pytorch.org/whl/cpu
cd /opt/RoboGauge
python -m pip install -e . python -m pip install -e .
``` ```
公开仓库作为基线使用。本文所需的 `go1_lab.*` 任务来自本地修改版的 `go1` 分支;在新评估机上还必须同步该分支或应用对应提交。安装后执行下面的命令确认任务注册,输出中必须出现 `go1_lab.flat``go1_lab.stairs_fd` 等任务: 上面的最后一条命令必须在 `/opt/RoboGauge` 中执行。本文需要 Gitea `go1` 分支中的 `go1_lab.*` 任务;公开上游仓库只能作为参考,不能用 `go2_lab.*` 代替。安装后确认当前 commit 与任务注册,输出中必须出现 `go1_lab.flat``go1_lab.stairs_fd` 等任务:
```bash ```bash
git branch --show-current git --git-dir=/opt/RoboGauge/.git --work-tree=/opt/RoboGauge rev-parse HEAD
python -c "import robogauge.tasks; from robogauge.utils.task_register import task_register; print(*sorted(task_register.pipeline_classes), sep='\n')" /opt/envs/robogauge/bin/python -c "import robogauge.tasks; from robogauge.utils.task_register import task_register; print(*sorted(task_register.pipeline_classes), sep='\n')"
``` ```
若不存在 `go1_lab.*` 任务,不要用 `go2_lab.*` 代替,应先同步本地 Go1 适配代码。 若不存在 `go1_lab.*` 任务,不要用 `go2_lab.*` 代替,应先同步本地 Go1 适配代码。
### 9.2 单模型评估 ### 9.2 单模型评估
直接通过 `--model-path` 指定 26000 对应的部署版 TorchScript。不要传入训练 checkpoint `model_26000.pt`,它是包含优化器等状态的字典,不能被 `torch.jit.load()`。平地配置默认没有启用目标,必须显式传入 `--goals`否则不会得到有效的速度评估 直接通过 `--model-path` 指定 26000 对应的部署版 TorchScript。不要传入训练 checkpoint `model_26000.pt`,它是包含优化器等状态的字典,不能被 `torch.jit.load()`当前平地配置默认启用最大速度和对角速度;命令仍显式传入 `--goals`以免配置默认值变化后评测范围静默改变
```bash ```bash
MUJOCO_GL=glfw python robogauge/scripts/run.py \ cd /opt/RoboGauge
MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/python robogauge/scripts/run.py \
--task-name go1_lab.flat \ --task-name go1_lab.flat \
--model-path resources/models/go1/policy_robotlab_26000.pt \ --model-path /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt \
--experiment-name go1_robotlab_26000_flat \ --experiment-name go1_robotlab_26000_flat \
--run-name flat_velocity \ --run-name flat_velocity \
--goals max_velocity diagonal_velocity \ --goals max_velocity diagonal_velocity \
@@ -491,18 +692,18 @@ MUJOCO_GL=glfw python robogauge/scripts/run.py \
三级楼梯使用目标点任务。`--spawn-type level_eval` 固定评估出生点,避免和搜索最高等级时的出生点混淆: 三级楼梯使用目标点任务。`--spawn-type level_eval` 固定评估出生点,避免和搜索最高等级时的出生点混淆:
```bash ```bash
MUJOCO_GL=glfw python robogauge/scripts/run.py \ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/python robogauge/scripts/run.py \
--task-name go1_lab.stairs_fd \ --task-name go1_lab.stairs_fd \
--model-path resources/models/go1/policy_robotlab_26000.pt \ --model-path /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt \
--experiment-name go1_robotlab_26000_stairs_fd \ --experiment-name go1_robotlab_26000_stairs_fd \
--run-name stairs_fd_l3 \ --run-name stairs_fd_l3 \
--level 3 \ --level 3 \
--spawn-type level_eval \ --spawn-type level_eval \
--headless --headless
MUJOCO_GL=glfw python robogauge/scripts/run.py \ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/python robogauge/scripts/run.py \
--task-name go1_lab.stairs_bd \ --task-name go1_lab.stairs_bd \
--model-path resources/models/go1/policy_robotlab_26000.pt \ --model-path /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt \
--experiment-name go1_robotlab_26000_stairs_bd \ --experiment-name go1_robotlab_26000_stairs_bd \
--run-name stairs_bd_l3 \ --run-name stairs_bd_l3 \
--level 3 \ --level 3 \
@@ -512,14 +713,17 @@ MUJOCO_GL=glfw python robogauge/scripts/run.py \
`run.py --headless` 在 Linux 默认选择 EGL。本次评估机的 EGL 驱动不支持 `PLATFORM_DEVICE`,所以命令显式设置 `MUJOCO_GL=glfw`GLFW 可能打印无法打开 X11 的 warning但无窗口仿真仍可完成。如果目标机 EGL 工作正常,可改回 `MUJOCO_GL=egl` `run.py --headless` 在 Linux 默认选择 EGL。本次评估机的 EGL 驱动不支持 `PLATFORM_DEVICE`,所以命令显式设置 `MUJOCO_GL=glfw`GLFW 可能打印无法打开 X11 的 warning但无窗口仿真仍可完成。如果目标机 EGL 工作正常,可改回 `MUJOCO_GL=egl`
本次镜像自检只启用 `--goals max_velocity`6 个速度子任务约 12 秒完成,`quality_score.mean=0.8402`,证明 TorchScript 加载、Go1 XML、MuJoCo 和指标落盘链路可用。该数值不是发布验收阈值,也不能替代下文完整的多目标、多 seed 评估。
单任务的 `--task-name` 必须是注册表里的完整名称,例如 `go1_lab.flat``go1_lab.stairs_fd`,不能写成裸的 `go1_lab`。只有下面的 stress pipeline 把 `go1_lab` 当作机器人任务前缀,再拼接具体地形。 单任务的 `--task-name` 必须是注册表里的完整名称,例如 `go1_lab.flat``go1_lab.stairs_fd`,不能写成裸的 `go1_lab`。只有下面的 stress pipeline 把 `go1_lab` 当作机器人任务前缀,再拼接具体地形。
### 9.3 跨地形压力测试 ### 9.3 跨地形压力测试
```bash ```bash
MUJOCO_GL=glfw python robogauge/scripts/run.py \ cd /opt/RoboGauge
MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/python robogauge/scripts/run.py \
--task-name go1_lab \ --task-name go1_lab \
--model-path resources/models/go1/policy_robotlab_26000.pt \ --model-path /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt \
--experiment-name go1_robotlab_26000_stress \ --experiment-name go1_robotlab_26000_stress \
--stress-benchmark \ --stress-benchmark \
--stress-terrain-names flat slope_fd slope_bd stairs_fd stairs_bd wave obstacle \ --stress-terrain-names flat slope_fd slope_bd stairs_fd stairs_bd wave obstacle \
@@ -558,17 +762,15 @@ RoboGauge 的 `dof_power` 是归一化质量分,不是瓦特或电机温度。
先启动服务端: 先启动服务端:
```bash ```bash
conda activate robogauge cd /opt/RoboGauge
cd RoboGauge MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/python robogauge/scripts/server.py --port 9973 --num-processes 8
python robogauge/scripts/server.py --port 9973 --num-processes 8
``` ```
再启动训练: 再启动训练:
```bash ```bash
conda activate go2_rl_robotlab cd /opt/go2_rl_robotlab
cd go2_rl_robotlab OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/train.py \
python scripts/rsl_rl/train.py \
--task=RobotLab-Go1-v0 \ --task=RobotLab-Go1-v0 \
--num_envs=4096 \ --num_envs=4096 \
--max_iterations=26000 \ --max_iterations=26000 \
@@ -600,19 +802,20 @@ task_name="go1_lab.flat"
这里推荐使用 `go1_pro_deploy/deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py`,因为它与 RobotLab 的 10 帧/450 维 ONNX 接口一致。 这里推荐使用 `go1_pro_deploy/deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py`,因为它与 RobotLab 的 10 帧/450 维 ONNX 接口一致。
```bash ```bash
cd /path/to/go1_pro_deploy cd /opt/go1_pro_deploy/deploy_45dim_rl_gym
conda activate <DEPLOY_ENV>
MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \ MUJOCO_GL=glfw /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx --onnx /opt/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx
``` ```
这是带窗口和键盘的交互命令,需要可用的 X11/桌面。Linux 使用普通 `python`;只有 macOS 才通常需要 `mjpython`。脚本内部会 `chdir` 到自身目录,因此 `--onnx` 使用绝对路径。无图形环境应使用 8.4 节的 `--sample` 命令。
楼梯测试: 楼梯测试:
```bash ```bash
MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \ MUJOCO_GL=glfw /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx \ --onnx /opt/go1_pro_deploy/deploy_45dim_rl_gym/policy_robotlab_26000.onnx \
--terrain deploy_45dim_rl_gym/terrains/stairs/stairs_3.xml \ --terrain /opt/go1_pro_deploy/deploy_45dim_rl_gym/terrains/stairs/stairs_3.xml \
--spawn-x -0.6 \ --spawn-x -0.6 \
--spawn-z 0.34 --spawn-z 0.34
``` ```
@@ -644,16 +847,26 @@ sim2sim 重点检查:
BPU 量化不是把 ONNX 改一个后缀。至少需要: BPU 量化不是把 ONNX 改一个后缀。至少需要:
1. 已通过接口检查的 `policy_robotlab_26000.onnx` 1. 已通过接口检查的 `policy_robotlab_26000.onnx`
2. 来自相同观测构建逻辑的真实部署日志 2. 与部署观测构建逻辑一致的 10 帧/450 维 `float32` PTQ 输入样本
3. 从 RL 状态提取的 10 帧/450 维 `float32` 校准样本 3. 使用浮点 ONNX 对这批输入执行推理得到的参考输出
4. 浮点 ONNX、图变换 ONNX、量化模型三者的逐样本输出对比。 4. 浮点 ONNX、图变换 ONNX、量化模型三者的逐样本输出对比。
当前 26000 模型使用 `calibration_data_26000_robotlab_fast64/` 中的 64 个 PTQ 校验样本。这批数据来自 ONNX 推理流程,不是 X5 量化产生的模型 `.bin`。需要重新生成时,先检查供 `make_calibration_data.py` 使用的 ONNX 推理日志:
```bash
find /opt/go1_pro_deploy/logs \
-path '*/robotlab_go1_deploy_*/steps.jsonl' \
-type f -print
```
`make_calibration_data.py` 读取日志中的 `mode: RL` 和 45 维 `obs_single`,按部署顺序重建 10 帧/450 维历史,并写出工具链所需的 raw float32 校准输入 `.bin`。这里的 `.bin` 是 PTQ 输入文件X5 编译完成后生成的模型也使用 `.bin` 后缀,但两者用途完全不同。脚本找不到匹配日志或有效样本不足时会中止,不会绕过数据准备继续编译。
当前量化脚本会保留 actions 输出、降级 opset、包装为 BPU 需要的 4D 输入,并把 MoE grouped Conv 等价替换为 Gemm以减少 CPU fallback。中间 norm 节点位于 actor 之前,不能随意删除或移到后处理。 当前量化脚本会保留 actions 输出、降级 opset、包装为 BPU 需要的 4D 输入,并把 MoE grouped Conv 等价替换为 Gemm以减少 CPU fallback。中间 norm 节点位于 actor 之前,不能随意删除或移到后处理。
量化脚本内部流程如下: 量化脚本内部流程如下:
```text ```text
真实日志 steps.jsonl ONNX 推理流程日志 steps.jsonl
-> make_calibration_data.py 生成 float32 featuremap 校准样本 -> make_calibration_data.py 生成 float32 featuremap 校准样本
-> keep_actions_output.py 只保留 actions 输出 -> keep_actions_output.py 只保留 actions 输出
-> downgrade_policy_to_opset11.py 降级到工具链可接受的 opset -> downgrade_policy_to_opset11.py 降级到工具链可接受的 opset
@@ -674,27 +887,37 @@ BPU 量化不是把 ONNX 改一个后缀。至少需要:
| `--flat-dim` | 平铺输入维度;不填时为 `45 * history-len` | RobotLab 为 `450`Gym 为 `225` | | `--flat-dim` | 平铺输入维度;不填时为 `45 * history-len` | RobotLab 为 `450`Gym 为 `225` |
| `--samples` | 校准样本数量,越大越慢但覆盖更稳 | 默认 `64`,必要时 `128` | | `--samples` | 校准样本数量,越大越慢但覆盖更稳 | 默认 `64`,必要时 `128` |
| `--min-samples` | 最少有效样本数,不足则中止 | 默认 `32` | | `--min-samples` | 最少有效样本数,不足则中止 | 默认 `32` |
| `--log-prefix` | 从 `logs/` 下筛选部署日志的目录前缀 | `robotlab_go1_deploy` | | `--log-prefix` | 从 `logs/` 下筛选 ONNX 推理日志的目录前缀 | `robotlab_go1_deploy` |
| `--cal-tag` | 校准目录标签,区分 RobotLab/Gym | `robotlab``gym` | | `--cal-tag` | 校准目录标签,区分 RobotLab/Gym | `robotlab``gym` |
| `--compare-limit` | 浮点 ONNX 等价对比样本数 | 默认 `64` | | `--compare-limit` | 浮点 ONNX 等价对比样本数 | 默认 `64` |
| `--quant` | 量化策略 | 默认 `int16``int8` 仅作对照 | | `--quant` | 量化策略 | 默认 `int16``int8` 仅作对照 |
| `--docker-image` | D-Robotics CPU 工具链镜像 | X5/S100 各自不同 | | `--docker-image` | D-Robotics CPU 工具链镜像 | X5/S100 各自不同 |
量化建议在 Mac 或训练机的 Docker 中完成,不在 X5/S100 板端跑 Docker。板端只负责加载产物做离线测速、数值对齐和实机部署。 量化建议在 Mac 或训练机的 Docker 中完成,不在 X5/S100 板端跑 Docker。本文训练/量化主机的仓库固定为 `/opt/go1_pro_deploy`板端只负责加载产物做离线测速、数值对齐和实机部署。
量化脚本内部直接调用 `docker`。运行 X5/S100 脚本前先验收 daemon
```bash
sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker info >/dev/null
```
### 11.2 RDK X5 ### 11.2 RDK X5
X5 使用 D-Robotics X5 CPU 工具链镜像: X5 使用 D-Robotics X5 CPU 工具链镜像:
```bash ```bash
docker pull openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8 sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker load \
-i /opt/envs/go2_rl_robotlab/docker-toolchain/images/openexplorer_ai_toolchain_ubuntu_20_x5_cpu_v1.2.8.tar
# 或在可联网的 Docker 主机直接拉取:
# sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker pull openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8
``` ```
脚本默认会用 `docker run --rm --platform linux/amd64` 启动这个镜像,并把当前仓库挂载到 `/workspace/deploy_go1_pro`。量化机执行: 脚本默认会用 `docker run --rm --platform linux/amd64` 启动这个镜像,并把当前仓库挂载到 `/workspace/deploy_go1_pro`。量化机执行:
```bash ```bash
cd /path/to/go1_pro_deploy cd /opt/go1_pro_deploy
sudo env PATH=/opt/envs/go2_rl_robotlab/docker-toolchain/bin:${PATH} \
bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \ bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \
--policy ../policy_robotlab_26000.onnx \ --policy ../policy_robotlab_26000.onnx \
--round 26000 \ --round 26000 \
@@ -704,6 +927,7 @@ bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \
--min-samples 32 \ --min-samples 32 \
--log-prefix robotlab_go1_deploy \ --log-prefix robotlab_go1_deploy \
--cal-tag robotlab \ --cal-tag robotlab \
--compare-limit 64 \
--docker-image openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8 \ --docker-image openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8 \
--quant int16 --quant int16
``` ```
@@ -715,16 +939,10 @@ X5 关键配置:
- int16 时脚本在 YAML 中写入 `optimization: "set_all_nodes_int16"` - int16 时脚本在 YAML 中写入 `optimization: "set_all_nodes_int16"`
- `hb_mapper checker` 默认会先运行;明确知道模型已检查过时才使用 `--skip-checker` - `hb_mapper checker` 默认会先运行;明确知道模型已检查过时才使用 `--skip-checker`
预期产物:
```text
deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_gemm/
policy_robotlab_26000_int16_gemm.bin
```
如果要量化旧 Gym 5 帧模型,必须同步修改历史长度、日志前缀和标签: 如果要量化旧 Gym 5 帧模型,必须同步修改历史长度、日志前缀和标签:
```bash ```bash
sudo env PATH=/opt/envs/go2_rl_robotlab/docker-toolchain/bin:${PATH} \
bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \ bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \
--policy ../policy_35k.onnx \ --policy ../policy_35k.onnx \
--round 35k \ --round 35k \
@@ -734,6 +952,8 @@ bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \
--quant int16 --quant int16
``` ```
以下是 **RDK X5 目标板** 命令。板端软件按交付约定安装在 `/root/go1_pro_deploy`;这是硬件系统路径,不是训练/量化镜像路径,也不应复制回 `/opt` 镜像执行:
板端先做完全离线自检,不连接电机控制: 板端先做完全离线自检,不连接电机控制:
```bash ```bash
@@ -752,14 +972,18 @@ X5 的 featuremap 模型不要直接改用 `hobot_dnn.pyeasy_dnn.forward()`。
S100 使用新版 S100/S600 CPU 工具链镜像: S100 使用新版 S100/S600 CPU 工具链镜像:
```bash ```bash
docker pull registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0 sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker load \
-i /opt/envs/go2_rl_robotlab/docker-toolchain/images/ai_toolchain_ubuntu_22_s100_s600_cpu_v3.7.0.tar
# 或在已登录 registry 的 Docker 主机直接拉取:
# sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker pull registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0
``` ```
脚本同样在量化机 Docker 中运行,不在 S100 板端运行 Docker 脚本同样在量化机 Docker 中运行,不在 S100 板端运行 Docker
```bash ```bash
cd /path/to/go1_pro_deploy cd /opt/go1_pro_deploy
sudo env PATH=/opt/envs/go2_rl_robotlab/docker-toolchain/bin:${PATH} \
bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_s100.sh \ bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_s100.sh \
--policy ../policy_robotlab_26000.onnx \ --policy ../policy_robotlab_26000.onnx \
--round 26000 \ --round 26000 \
@@ -769,6 +993,7 @@ bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_s100.sh \
--min-samples 32 \ --min-samples 32 \
--log-prefix robotlab_go1_deploy \ --log-prefix robotlab_go1_deploy \
--cal-tag robotlab \ --cal-tag robotlab \
--compare-limit 64 \
--docker-image registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0 \ --docker-image registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0 \
--march nash-e \ --march nash-e \
--quant int16 --quant int16
@@ -781,13 +1006,6 @@ S100 关键配置:
- int16 时脚本在 YAML 中写入 `quant_config.model_config.all_node_type: int16` - int16 时脚本在 YAML 中写入 `quant_config.model_config.all_node_type: int16`
- `compiler_parameters.core_num` 当前为 `1`,优先保证单次策略推理低延迟;需要多核吞吐测试时应另做离线 benchmark不要直接改实机脚本。 - `compiler_parameters.core_num` 当前为 `1`,优先保证单次策略推理低延迟;需要多核吞吐测试时应另做离线 benchmark不要直接改实机脚本。
预期产物:
```text
deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_s100_gemm/
policy_robotlab_26000_s100_int16_gemm.hbm
```
产物同步到 S100 后,先看模型信息再测速: 产物同步到 S100 后,先看模型信息再测速:
```bash ```bash
@@ -833,12 +1051,9 @@ deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_s100_gemm/
公开 SDK 可用于核对通用 API、结构体字段和安全调用方式但不要直接运行带位置目标的官方示例。先只编译 公开 SDK 可用于核对通用 API、结构体字段和安全调用方式但不要直接运行带位置目标的官方示例。先只编译
```bash ```bash
git clone https://github.com/unitreerobotics/unitree_legged_sdk.git git clone https://github.com/unitreerobotics/unitree_legged_sdk.git /opt/unitree_legged_sdk
cd unitree_legged_sdk cmake -S /opt/unitree_legged_sdk -B /opt/unitree_legged_sdk/build
mkdir build cmake --build /opt/unitree_legged_sdk/build --parallel
cd build
cmake ..
cmake --build . --parallel
``` ```
本地 `walk-these-ways/go1_gym_deploy/unitree_legged_sdk_bin/lcm_position.cpp` 可作为官方 SDK 接入策略控制环的公开参考。阅读时重点关注 UDP 收发线程、`LowState` 到策略观测的转换、`Safety` 调用和退出流程,不要照搬其网络地址、增益或速度范围到另一台机器人。 本地 `walk-these-ways/go1_gym_deploy/unitree_legged_sdk_bin/lcm_position.cpp` 可作为官方 SDK 接入策略控制环的公开参考。阅读时重点关注 UDP 收发线程、`LowState` 到策略观测的转换、`Safety` 调用和退出流程,不要照搬其网络地址、增益或速度范围到另一台机器人。
@@ -929,7 +1144,7 @@ pgrep -fl 'keep_sport_alive|Legged_sport|appTransit'
- 用相同 450 维输入比较 PyTorch、ONNX 和 BPU 输出。 - 用相同 450 维输入比较 PyTorch、ONNX 和 BPU 输出。
- 检查 12 维动作的顺序、符号、范围和有限性。 - 检查 12 维动作的顺序、符号、范围和有限性。
- 测量平均、P99 和最大推理时间。 - 测量平均、P99 和最大推理时间。
- 对零输入、真实日志输入和边界输入做回归。 - 对零输入、PTQ 校验输入和边界输入做回归。
### 14.2 第 1 级:只读 LowState ### 14.2 第 1 级:只读 LowState
@@ -1094,7 +1309,7 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms
### 16.3 BPU 很快,但真机表现比 ONNX 差 ### 16.3 BPU 很快,但真机表现比 ONNX 差
速度合格不代表数值合格。使用同一批真实 450 维输入逐帧比较 ONNX/BPU重点查 featuremap 输入、量化校准分布、输出 reshape、CPU fallback 和 runtime 调用生命周期。 速度合格不代表数值合格。使用同一批 PTQ 校验输入逐帧比较 ONNX/BPU重点查 featuremap 输入、量化校准分布、输出 reshape、CPU fallback 和 runtime 调用生命周期。
### 16.4 TensorBoard 总回报上涨,但 RoboGauge 下降 ### 16.4 TensorBoard 总回报上涨,但 RoboGauge 下降
@@ -1106,7 +1321,10 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms
## 17. 发布前检查清单 ## 17. 发布前检查清单
- [ ] RoboGo 镜像和容器启动信息已补全 - [ ] RoboGo 镜像名称、拉取命令、容器启动参数和持久化目录已补全;当前文档中的阻断项不再是 TODO
- [ ] `/opt/IsaacLab``v2.3.2`pip 环境为 IsaacLab `2.3.2.post1`、Isaac Sim `5.1.0.0`、PyTorch `2.7.0`,且没有重新挂载旧 `/opt/IsaacSim`
- [ ] 运行用户可写训练、RoboGauge、MuJoCo 和 Isaac Sim runtime 目录,且 `OMNI_KIT_ACCEPT_EULA=YES` 已注入。
- [ ] 镜像 1 轮训练自检通过,并保存 `model_0.pt`、日志和参数文件。
- [ ] 硬件、接线、网络和急停章节已由设备负责人补全。 - [ ] 硬件、接线、网络和急停章节已由设备负责人补全。
- [ ] 所有仓库 commit 和 Python 依赖已记录。 - [ ] 所有仓库 commit 和 Python 依赖已记录。
- [ ] 15000、19500、26000、33500 候选已注明课程阶段,并完成 TensorBoard 与 RoboGauge 对比。 - [ ] 15000、19500、26000、33500 候选已注明课程阶段,并完成 TensorBoard 与 RoboGauge 对比。
@@ -1114,8 +1332,9 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms
- [ ] ONNX 输入 450、输出 12关节顺序为 `FR, FL, RR, RL` - [ ] ONNX 输入 450、输出 12关节顺序为 `FR, FL, RR, RL`
- [ ] RoboGauge 单任务使用完整的 `go1_lab.*` 注册名,而非裸 `go1_lab``go2_lab` - [ ] RoboGauge 单任务使用完整的 `go1_lab.*` 注册名,而非裸 `go1_lab``go2_lab`
- [ ] MuJoCo 平地、转向、侧移、急停和台阶测试通过。 - [ ] MuJoCo 平地、转向、侧移、急停和台阶测试通过。
- [ ] 真实日志校准集与模型版本一致。 - [ ] PTQ 输入、ONNX 参考输出与模型版本一致。
- [ ] X5/S100 量化模型通过离线精度和延迟验收。 - [ ] X5/S100 量化模型通过离线精度和延迟验收。
- [ ] X5/S100 工具链归档已通过 SHA-256 校验,并在具备 Docker daemon 的主机完成 `docker load`
- [ ] 私有 SDK 的协议、密钥和专有实现未写入公开文档。 - [ ] 私有 SDK 的协议、密钥和专有实现未写入公开文档。
- [ ] 实机测试严格完成只读、观测、推理、状态机、悬空、地面分级流程。 - [ ] 实机测试严格完成只读、观测、推理、状态机、悬空、地面分级流程。
- [ ] 每条停机路径均已实际演练。 - [ ] 每条停机路径均已实际演练。