G1 编程与工程 IsaacLab

G1-23dof 强化学习训练实战复盘与经验总结

2026-04-12 · 5 min read

G1-23dof 强化学习训练实战复盘与经验总结

文档版本:V1.0
来源:blind_teacher_v2_training_report.md + phase1_report.md
编写日期:2026-04-12
适用任务:全任务(Velocity / Blind-Teacher / Fusion)


1. 核心经验速查

这些是从真实训练中总结的实战教训,每一条都对应一次或多次失败。

# 经验 教训级别
1 PPO 超参数过大 + 小 mini_batch → NaN 崩溃 🔴 致命
2 固定抬脚高度无法同时适配平地和楼梯 🟡 重要
3 Curriculum 晋级门槛过高会导致降级 🟡 重要
4 动作 scale 偏小会限制关节运动范围 🟡 重要
5 局部最优是长期训练的必然风险 🟢 有用
6 Domain Randomization 过强会延长训练时间 🟢 有用

2. NaN 崩溃七层防御体系

2.1 事故经过

V1 训练到 iter 6849 时突然出现 value_loss=NaN,后续所有梯度更新失效。

根因分析

rsl_rl PPO 使用单个 Adam optimizer 同时更新 actor 和 critic。当 value_loss 出现极端梯度时,其 momentum 通过共享 optimizer 污染 actor 的 noise_std 参数,导致动作噪声发散,进而 reward 崩溃。

2.2 危险配置 vs 修复配置

参数 危险值(V1) 修复值(V2) 参考
learning_rate 1.0e-3 5.0e-4 StairV4: 5e-4
num_mini_batches 4 16 StairV4: 16
desired_kl 0.02 0.01 Fusion: 0.01

核心教训num_mini_batches=4 意味着每次更新只用 1024 个样本(4096×24/4),梯度估计噪声大,极易被极端值带偏。

2.3 七层防御代码

# L1: 噪声参数化(actor_critic.py)
noise_std = exp(log_noise_std)  # 数学保证 std > 0

# L2: value_loss clamp(ppo.py:318)
value_loss = clamp(value_loss, max=10.0)

# L3: reward clamp(rollout_storage.py:92)
reward = clamp(reward, min=-20, max=20)

# L4: returns clamp(rollout_storage.py:155)
returns = clamp(returns, min=-100, max=100)

# L5: 梯度 NaN 检测,跳过更新(ppo.py:391-399)
if torch.isnan(grad).any():
    optimizer.step()  # 跳过

# L6: ratio clamp(ppo.py:298)
ratio = clamp(ratio, min=0.01, max=100)

# L7: loss NaN/Inf 跳过 backward(ppo.py:374-375)
if not torch.isfinite(loss):
    continue  # 跳过此次更新

3. Terrain Level 停滞在 5-6 的问题排查

3.1 问题描述

V2 训练 18000+ iterations 后: - 存活率 97%+ ✅ - reward 81+ ✅ - terrain level 卡在 5~6/9,无法突破

3.2 已尝试的 4 种 Curriculum 方案

方案 晋级条件 结果 分析
tracking_exp_vel 速度跟踪 > 0.7 ❌ 卡住 台阶上速度波动大,分数永远达不到 0.7
vel_aggressive 固定 2.0m distance > 2.0m ❌ 卡住 距离够但策略找到了"省力走法"
cmd_adaptive ratio=0.8 distance > 12.8m@0.8m/s ❌ 降级 门槛过高,机器人在台阶上走不了那么远
cmd_adaptive ratio=0.5 distance > 8.0m@0.8m/s 🔄 恢复中 上升趋势但缓慢

3.3 四大制约因素

因素 1:动作 Scale 偏小(最可能)

关节 BlindTeacher V2 StairV4(成功突破)
hip_roll 0.35 0.5
ankle_pitch 0.4 0.5
ankle_roll 0.4 0.5

结论:hip_roll 控制侧向抬腿,scale 偏小直接限制了跨越高台阶时的动作幅度。

因素 2:地形组成差异

V2 StairV4
台阶总比例 45% 57%
最大台阶高度 0.20m 0.25m

V2 的台阶训练时间比 StairV4 少 12%,且最大难度低 5cm。

因素 3:感知延迟(Blind 设计局限)

Height_scan 安装在 torso_link,检测的是脚下地形高度,不是前方的预测。机器人只有踩上台阶才能感知,无法提前规划抬腿。

这是 BlindTeacher 的设计定位(为 Depth-Student 提供教师信号),但确实限制了高难度地形表现。

因素 4:局部最优(长期训练必然风险)

18000 iter 后,策略在 level 5-6 已经非常稳定。"不摔跤 + 不耗能" 的局部最优不需要学会爬高台阶。

3.4 待尝试方案(按优先级)

优先级 方案 预期效果
P0 hip_roll 0.35→0.5, ankle 0.4→0.5 对齐 StairV4 的成功配置
P1 stairs_up 28%→35%, max_height 0.20→0.25m 增加高难度地形暴露
P2 从头训练(清除局部最优) 跳出局部最优陷阱
P3 promotion_ratio 0.5→0.3 降低晋级门槛

4. Curriculum 演进路线

4.1 演进时间线

Phase 0: terrain_levels_vel(纯速度门控)
   ↓ 发现问题:转圈也能升级
Phase 1: quality_gated_terrain_curriculum(距离+存活率双门控)
   ↓ 存活率门控导致晋级过慢
StairV4: terrain_levels_vel_aggressive(固定 2.4m 距离)
   ↓ 对某些地形有效但非通用
V1: tracking_exp_vel(速度跟踪分数 > 0.7)
   ↓ 台阶上速度波动大,永远达不到 0.7
V2: terrain_levels_cmd_adaptive(速度自适应距离门控)
   ↓ 目前最优,但仍卡在 level 6

4.2 Command-Adaptive Curriculum 详解

# 晋级:走过距离 > max(cmd_vel × episode_time × 0.5, 2.0m)
# 降级:走过距离 < cmd_vel × episode_time × 0.2

# 速度越快,晋级门槛越高(防止冲刺后摔到)
# 速度越慢,保底 2.0m 门槛(防止低速时无限晋级)
训练阶段 平均速度 晋级门槛 降级门槛
初期 0.05 m/s 2.0m(保底) 0.2m
中期 0.30 m/s 3.0m 1.2m
后期 0.80 m/s 8.0m 3.2m

5. 关键设计决策复盘

5.1 V1 → V2 三大改进

改进 1:固定抬脚 → 地形自适应抬脚

V1 问题:固定 0.15m 目标 - 平地上:抬脚 15cm 过多(浪费能量) - 楼梯上:0.15m < 0.17m 台阶(磕碰)

V2 解决方案

# height_scan 检测前方地形落差
variation = height_scan.max() - height_scan.min()
stair_factor = clamp(variation / 0.08, 0, 1)

# 目标高度动态插值
target = 0.12 + stair_factor * 0.08  # 0.12m(平) ~ 0.20m(楼梯)

效果:terrain level 5-6 上 feet_swing_adaptive 奖励达到 89% 最大值,说明自适应机制有效。

改进 2:forward_progress 加倍激励

V1 问题:distance_scale=4.0 导致近距离梯度太平,机器人缺乏前进动力。

# V1: tanh(distance / 4.0)  → 1m 行走仅得 0.24 分
# V2: tanh(distance / 2.0)  → 1m 行走可得 0.46 分(+92%)

# weight 也从 1.0 → 2.0,总激励约 ×3

改进 3:PPO 超参数修复(防崩溃)

见第 2 节。

5.2 决策:从头训练 vs 热启动

问题:Phase 0 的 Actor 输入 78D,Phase 1 是 265D(+ height_scan),MLP 第一层维度不匹配。

结论:写部分权重加载器的成本 > 多训练几小时。从头训练 + init_noise_std=0.5 足够稳定。


6. 训练监控指标体系

6.1 核心指标(每日必查)

指标 健康范围 崩溃前兆
value_loss < 1.0 > 10.0 或 NaN
noise_std 单调下降或稳定 持续上升
Mean episode length > 700(70%) 突然下降
terrain_levels 持续上升 停滞 > 5000 iter
reward 单调上升 突然下降

6.2 分层奖励贡献分析

以 V2 iter 18701 为例,各项奖励贡献:

奖励项 实际值 最大值 达成率 状态
track_lin_vel_xy 1.68 2.00 84% ✅ 良好
forward_progress 1.54 2.00 77% ✅ 良好
feet_swing_adaptive 1.33 1.50 89% ✅ 良好
gait 0.29 0.30 97% ✅ 接近满分
alive 0.25 0.25 100% ✅ 满分
track_ang_vel_z 0.25 0.75 33% ⚠️ 偏低
action_rate -0.53 ⚠️ 最大负项

分析:action_rate(动作变化率)是最大负项,说明策略倾向于高频率动作调整,而非稳定步态。


7. 经验总结清单

7.1 训练开始前

  • [ ] num_mini_batches 至少 16(4096 envs 下)
  • [ ] desired_kl ≤ 0.01(过大会导致更新过于激进)
  • [ ] init_noise_std 验证:期望初期 std ≈ 0.5
  • [ ] Domain Randomization 参数记录在案

7.2 训练初期(0~5000 iter)

  • [ ] 检查 value_loss 是否稳定(< 1.0)
  • [ ] 检查 noise_std 是否开始下降(而非上升)
  • [ ] terrain level 应该在 1~3 范围内
  • [ ] episode length 应该 > 500

7.3 训练中期(5000~20000 iter)

  • [ ] terrain level 应持续上升(若停滞 > 3000 iter 开始排查)
  • [ ] 检查各奖励项贡献比例是否合理
  • [ ] action_rate 负值不应过大(过大说明动作不平滑)
  • [ ] 倒地率(bad_orientation)应 < 10%

7.4 训练收尾

  • [ ] terrain level 达到目标(通常 6~8 为良好)
  • [ ] noise_std 应趋于稳定(不再下降)
  • [ ] value_loss 应稳定在低位
  • [ ] 做 3 次以上独立 play 测试验证泛化性

版本记录

版本 日期 修改内容 作者
V1.0 2026-04-12 初始版本,整理自 V1/V2 训练报告 AI Assistant

本文档由 AI 辅助整理自 unitree_lab_locomotion 仓库训练复盘文档

← 上一篇
G1-23dof Fusion 多传感器融合任务配置规范 (V0~V11)
下一篇 →
G1-23dof 强化学习训练文档 Phase 1 总结
← 返回博客列表