Compare commits

..

3 Commits

Author SHA1 Message Date
cyy_mac
ab7fcf480d docs: expand deployment logging guidance 2026-07-31 16:46:58 +08:00
cyy_mac
8c1dd4f82b docs: expand bpu quantization guide 2026-07-31 16:38:02 +08:00
cyy_mac
ca80135bc4 docs: polish deployment guide 2026-07-31 16:32:11 +08:00

View File

@@ -384,22 +384,27 @@ python -c "import onnxruntime as ort; s=ort.InferenceSession('policy_robotlab_26
预期输入为 450 个 `float32`,输出为 12 个动作。输入输出不匹配时不要继续 sim2sim 或量化。 预期输入为 450 个 `float32`,输出为 12 个动作。输入输出不匹配时不要继续 sim2sim 或量化。
### 8.4 训练仓库自带的 MuJoCo 快速检查 ### 8.4 独立 MuJoCo 快速检查
训练仓库还提供了基于 TorchScript 的 Go1 MuJoCo 入口。它接收当前 45 维单帧观测,并在模型内部维护 10 帧历史,适合在进入完整 RoboGauge 评估前做一次快速检查 如果你要做的是“和部署链路一致”的快速检查,直接使用部署仓库里的 ONNX 入口。它读取当前 45 维单帧观测,并在脚本内部维护 10 帧历史,适合在进入完整 RoboGauge 评估前核对观测、动作缩放和地形 XML
```bash ```bash
mkdir -p deploy/pre_train/go1 cd /path/to/go1_pro_deploy
cp <RUN_DIR>/exported/policy.pt deploy/pre_train/go1/policy.pt MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx
``` ```
确认 `deploy/deploy_mujoco/configs/go1.yaml` 中的 `policy_path``xml_path` 指向正确模型与场景,再运行 楼梯测试同样直接切 terrain
```bash ```bash
MUJOCO_GL=glfw python deploy/deploy_mujoco/deploy_go1.py MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx \
--terrain deploy_45dim_rl_gym/terrains/stairs/stairs_3.xml \
--spawn-x -0.6 \
--spawn-z 0.34
``` ```
该入口默认检测游戏手柄,`LX/LY` 控制前后和侧向速度,`RX` 控制转向;未检测到手柄时使用 YAML 中的固定指令。它与后文带键盘、ONNX 和更多日志检查的独立部署脚本用途不同 脚本默认 `--clip-actions 100.0``--max-target-step 0.0`。如果你要做更保守的起步测试,可以再按日志逐步收紧这些参数;不要把旧版本的示例值当成固定默认
## 9. RoboGauge 自动评估 ## 9. RoboGauge 自动评估
@@ -506,22 +511,18 @@ task_name="go1_lab"
cd /path/to/go1_pro_deploy cd /path/to/go1_pro_deploy
conda activate <DEPLOY_ENV> conda activate <DEPLOY_ENV>
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \ MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx \ --onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx
--clip-actions 4.0 \
--max-target-step 0.15
``` ```
楼梯测试: 楼梯测试:
```bash ```bash
mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \ MUJOCO_GL=glfw mjpython deploy_45dim_rl_gym/deploy_go1_onnx_mujoco_lab.py \
--onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx \ --onnx deploy_45dim_rl_gym/policy_robotlab_26000.onnx \
--terrain deploy_45dim_rl_gym/terrains/stairs/stairs_3.xml \ --terrain 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
--clip-actions 4.0 \
--max-target-step 0.15
``` ```
键盘映射: 键盘映射:
@@ -557,9 +558,47 @@ BPU 量化不是把 ONNX 改一个后缀。至少需要:
当前量化脚本会保留 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
真实日志 steps.jsonl
-> make_calibration_data.py 生成 float32 featuremap 校准样本
-> keep_actions_output.py 只保留 actions 输出
-> downgrade_policy_to_opset11.py 降级到工具链可接受的 opset
-> make_bpu_4d_onnx.py 把 [1, D] 输入包装成 [1, 1, 1, D]
-> replace_group_conv_with_gemm.py 把 MoE grouped Conv 替换为等价 Gemm
-> compare_4d_onnx.py 检查浮点图变换等价
-> hb_mapper / hb_compile 生成板端模型
```
脚本中的主要可调变量含义:
| 参数 | 含义 | 常用设置 |
| --- | --- | --- |
| `--policy` | 原始 ONNX 路径,必须在部署仓库内 | `../policy_robotlab_26000.onnx` |
| `--round` | 输出目录和校准目录里的轮次标签,不参与计算 | `26000``35k` |
| `--name` | 输出模型 basename不填时取 ONNX 文件名 | `policy_robotlab_26000` |
| `--history-len` | 历史帧数,用于重建输入维度 | RobotLab 为 `10`Gym 为 `5` |
| `--flat-dim` | 平铺输入维度;不填时为 `45 * history-len` | RobotLab 为 `450`Gym 为 `225` |
| `--samples` | 校准样本数量,越大越慢但覆盖更稳 | 默认 `64`,必要时 `128` |
| `--min-samples` | 最少有效样本数,不足则中止 | 默认 `32` |
| `--log-prefix` | 从 `logs/` 下筛选部署日志的目录前缀 | `robotlab_go1_deploy` |
| `--cal-tag` | 校准目录标签,区分 RobotLab/Gym | `robotlab``gym` |
| `--compare-limit` | 浮点 ONNX 等价对比样本数 | 默认 `64` |
| `--quant` | 量化策略 | 默认 `int16``int8` 仅作对照 |
| `--docker-image` | D-Robotics CPU 工具链镜像 | X5/S100 各自不同 |
量化建议在 Mac 或训练机的 Docker 中完成,不在 X5/S100 板端跑 Docker。板端只负责加载产物做离线测速、数值对齐和实机部署。
### 11.2 RDK X5 ### 11.2 RDK X5
量化机执行 X5 使用 D-Robotics X5 CPU 工具链镜像
```bash
docker pull openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8
```
脚本默认会用 `docker run --rm --platform linux/amd64` 启动这个镜像,并把当前仓库挂载到 `/workspace/deploy_go1_pro`。量化机执行:
```bash ```bash
cd /path/to/go1_pro_deploy cd /path/to/go1_pro_deploy
@@ -573,9 +612,17 @@ 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 \
--docker-image openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8 \
--quant int16 --quant int16
``` ```
X5 关键配置:
- `march` 固定为 `bayes-e`
- 输入类型为 `featuremap`,运行时输入 shape 是 `obs_4d [1, 1, 1, 450]`
- int16 时脚本在 YAML 中写入 `optimization: "set_all_nodes_int16"`
- `hb_mapper checker` 默认会先运行;明确知道模型已检查过时才使用 `--skip-checker`
预期产物: 预期产物:
```text ```text
@@ -583,6 +630,18 @@ deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_gemm/
policy_robotlab_26000_int16_gemm.bin policy_robotlab_26000_int16_gemm.bin
``` ```
如果要量化旧 Gym 5 帧模型,必须同步修改历史长度、日志前缀和标签:
```bash
bash deploy_45dim_rl_gym/bpu_quantization/quantize_policy_x5.sh \
--policy ../policy_35k.onnx \
--round 35k \
--history-len 5 \
--log-prefix rlgym_go1_deploy \
--cal-tag gym \
--quant int16
```
板端先做完全离线自检,不连接电机控制: 板端先做完全离线自检,不连接电机控制:
```bash ```bash
@@ -598,6 +657,14 @@ X5 的 featuremap 模型不要直接改用 `hobot_dnn.pyeasy_dnn.forward()`。
### 11.3 S100 ### 11.3 S100
S100 使用新版 S100/S600 CPU 工具链镜像:
```bash
docker pull registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0
```
脚本同样在量化机 Docker 中运行,不在 S100 板端运行 Docker
```bash ```bash
cd /path/to/go1_pro_deploy cd /path/to/go1_pro_deploy
@@ -610,10 +677,18 @@ 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 \
--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
``` ```
S100 关键配置:
- `--march nash-e` 对应当前 S100 平台;不要沿用 X5 的 `bayes-e`
- 输出是 `.hbm`,不是 X5 的 `.bin`
- int16 时脚本在 YAML 中写入 `quant_config.model_config.all_node_type: int16`
- `compiler_parameters.core_num` 当前为 `1`,优先保证单次策略推理低延迟;需要多核吞吐测试时应另做离线 benchmark不要直接改实机脚本。
预期产物: 预期产物:
```text ```text
@@ -621,6 +696,13 @@ deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_s100_gemm/
policy_robotlab_26000_s100_int16_gemm.hbm policy_robotlab_26000_s100_int16_gemm.hbm
``` ```
产物同步到 S100 后,先看模型信息再测速:
```bash
/usr/hobot/bin/hrt_model_exec model_info \
--model_file deploy_45dim_rl_gym/bpu_quantization/mapper_output_26000_s100_gemm/policy_robotlab_26000_s100_int16_gemm.hbm
```
板端测速: 板端测速:
```bash ```bash
@@ -775,6 +857,8 @@ pgrep -fl 'keep_sport_alive|Legged_sport|appTransit'
运行 ONNX/BPU 推理并记录 action仍不发送电机命令。检查 action 无 NaN/Inf、无持续饱和、静止状态不发散ONNX 和 BPU 的动作差在离线验收范围内。 运行 ONNX/BPU 推理并记录 action仍不发送电机命令。检查 action 无 NaN/Inf、无持续饱和、静止状态不发散ONNX 和 BPU 的动作差在离线验收范围内。
从这一级开始,命令必须显式保留 `--log-dir logs`;只要要判断板端实时性,就同时加 `--log-timing`。日志目录会在启动时自动创建,终端退出时会打印 `Log saved:` 路径。
X5 示例: X5 示例:
```bash ```bash
@@ -784,7 +868,8 @@ python3 deploy_45dim_rl_gym/bpu_deploy_x5/deploy_go1_robotlab_bpu_x5_fastcpp.py
--infer-check \ --infer-check \
--log-dir logs \ --log-dir logs \
--print-every 50 \ --print-every 50 \
--max-steps 500 --max-steps 500 \
--log-timing
``` ```
S100 示例: S100 示例:
@@ -796,7 +881,8 @@ python3 deploy_45dim_rl_gym/bpu_deploy_s100/deploy_go1_robotlab_bpu_s100_fastcpp
--infer-check \ --infer-check \
--log-dir logs \ --log-dir logs \
--print-every 50 \ --print-every 50 \
--max-steps 500 --max-steps 500 \
--log-timing
``` ```
### 14.5 第 4 级:悬空状态机,不启用 RL ### 14.5 第 4 级:悬空状态机,不启用 RL
@@ -832,6 +918,8 @@ IDLE -> CALIBRATE -> HOLD -> OBS_TEST -> INFER_TEST
先用已经通过地面测试的 ONNX 版本确定基线,再在相同软件保护、相同指令、相同场地上测试 BPU。两次测试只替换推理后端。若 BPU 行为异常,回到离线输入逐帧对比,不能通过放宽关节或姿态保护继续测试。 先用已经通过地面测试的 ONNX 版本确定基线,再在相同软件保护、相同指令、相同场地上测试 BPU。两次测试只替换推理后端。若 BPU 行为异常,回到离线输入逐帧对比,不能通过放宽关节或姿态保护继续测试。
对照日志至少要能证明三件事:同一段动作里 `commands` 接近一致,`action_raw/action_safe/joint_targets` 的差异在离线验收范围内,`policy_ms/loop_dt_ms/state_age_ms` 没有让 BPU 版本比 ONNX 版本产生额外控制延迟。若 BPU 端 `policy_ms` 很低但 `loop_dt_ms` 仍不稳,应继续查 SDK 收包、构包和系统调度,而不是只看 BPU 占用率。
### 14.10 第 9 级:坡面、台阶和扰动 ### 14.10 第 9 级:坡面、台阶和扰动
复杂地形是最后阶段。先从低难度、低速度和正向通过开始,再逐步测试侧向、反向、急停和摩擦变化。每次增加难度前必须确认前一级多次可复现。 复杂地形是最后阶段。先从低难度、低速度和正向通过开始,再逐步测试侧向、反向、急停和摩擦变化。每次增加难度前必须确认前一级多次可复现。
@@ -845,20 +933,54 @@ metadata.json
steps.jsonl steps.jsonl
``` ```
元数据应包含 Git commit、模型哈希、推理后端、控制周期、PD 参数、动作限制、保护阈值、设备型号、测试人员和场景。逐步日志至少包含 部署脚本默认在 `--log-dir` 下创建带时间戳的目录,例如
```text ```text
timestamp / state / state_reason logs/robotlab_go1_deploy_YYYYMMDD_HHMMSS/
commands_raw / commands ```
obs_single / obs_history
不要关闭日志来“省性能”。实机调试阶段宁可降低打印频率,也要保留 JSONL 日志后续量化校准、ONNX/BPU 对齐、力矩保护分析和动作异常定位都依赖这些记录。
`metadata.json` 用来复现实验条件。当前部署脚本会自动写入:
```text
created_at
num_obs / history_len / onnx_input_dim
action_scale / default_dof_pos
joint_names_sdk / joint_names_policy / joint_order_policy
lowcmd_backend 或 BPU backend
history_expected_span_ms
命令行传入的所有标量参数
```
发布或多人复现实验时,还应额外记录 Git commit、模型哈希、板端系统版本、BPU runtime 版本、设备型号、测试人员和场景。只给一条 `Log saved:` 路径而没有对应模型与参数后续无法判断问题来自策略、量化、SDK 还是现场操作。
`steps.jsonl` 是逐周期日志。当前脚本每条记录至少包含:
```text
step / time_wall / mode / state_reason
commands_raw / commands / rc_lx / rc_ly / rc_rx / rc_ry / rc_buttons
obs_single / history_fill / history_zero_pad
action_raw / action_safe action_raw / action_safe
joint_targets joint_targets
dof_pos / dof_vel / tau_est dof_pos / dof_vel / tau_est / motor_mode / motor_temperature / motor_reserve
base_ang_vel / projected_gravity / imu_rpy imu_rpy_deg / imu_quat / base_ang_vel / projected_gravity
inference_ms / loop_ms battery_soc
battery / temperature / communication_status loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms
``` ```
这些字段的用途:
- `mode``state_reason`:判断处于 `MONITOR``OBS_CHECK``INFER_CHECK``RAMP``RL` 还是故障/阻尼路径;保护触发时首先看这里。
- `commands_raw``commands`区分遥控器原始输入、deadzone/比例/交换后的策略输入,避免把遥控映射问题误判成模型问题。
- `obs_single``history_fill``history_zero_pad`:检查 45 维观测和历史缓存是否正确预热;刚进 RL 时历史未填满属于高风险段。
- `action_raw``action_safe`:区分模型原始输出与 clip、smooth、trip 检查后的实际动作;若二者差异大,说明部署端限制正在影响行为。
- `joint_targets``dof_pos``dof_vel``tau_est`:分析目标角、实际角、速度和力矩保护之间的因果关系。
- `motor_mode``motor_reserve``motor_temperature`:定位电机是否掉出 servo、是否有错误码或过热。
- `loop_dt_ms``recv_ms``policy_ms``work_ms``state_age_ms`:判断慢在推理、收包、构包发送还是系统调度。
分析日志时不要只看最后一帧。应从 `state_reason` 第一次不为 `ok``action_safe` 第一次明显被 clip、`motor_mode` 第一次异常、`tau_est` 第一次接近阈值、`loop_dt_ms` 第一次超过 20 ms 的位置向前回看至少 1 到 2 秒。
一次测试通过的最低条件: 一次测试通过的最低条件:
- 无 NaN/Inf、状态超时和控制周期持续超期。 - 无 NaN/Inf、状态超时和控制周期持续超期。