Skip to content

Roadmap #1452: microduck 任务与上游 microduck_rl 训练配方对齐(集成分支) - #1464

Merged
TATP-233 merged 14 commits into
dev/issue-1042-manager-based-apifrom
dev/issue-1452-microduck-rl-alignment
Sep 3, 2026
Merged

Roadmap #1452: microduck 任务与上游 microduck_rl 训练配方对齐(集成分支)#1464
TATP-233 merged 14 commits into
dev/issue-1042-manager-based-apifrom
dev/issue-1452-microduck-rl-alignment

Conversation

@TATP-233

@TATP-233 TATP-233 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Closes #1452 | Roadmap 集成分支最终 PR | Base: dev/issue-1042-manager-based-api(declared base,已在集成点同步其最新 head 73dd2403

集成结果

microduck 三任务(velocity_flat / sitstand_flat / ground_pick_flat,ppo tree,mjwarp owner)的训练配方与上游 microduck_rl HEAD @ 29e887ec 逐项对齐(执行器路线 A:保持 XML position PD,不对齐 BAM),并交付机器可检查的对齐 contract(防漂移)与受控对比 benchmark 设施。

Child PR 列表(全部经本地 gate + review 合入本分支)

child issue PR 内容
1 #1453 #1458 对齐 contract(alignment_contract.py,81 条/velocity)+ audit_microduck_alignment.py + 防漂移测试 + microduck_alignment_rollout.py
2 #1454 #1460 物理层:sim_dt 0.005/substeps 4、scene XML 显式 solver(implicitfast/Newton/10/20/1e-8/0.01)、reset_base 分布、startup mass/inertia DR(新 randomize_body_mass_inertia + Entity/transaction body_inertia 写入路径)、push per-env、去 base_height 终止
3 #1455 #1461 reward 栈对齐上游 HEAD:track_linear_velocity 2.0/√0.1、新增 upright/self_collisions/body_pose_tracking(挂起)、variable_posture 双 std、body_ang_vel ω_xy、head_pose_tracking 2.0;移除 orientation/base_height/alive/flight_phase/lin_vel_z
4 #1456 #1462 基建:env RNG 播种(owner YAML seed 42)、init_at_random_ep_len 适配层修复(wrapper setter 传播进 env 真实计数)、num_envs 4096、max_iterations 2000(覆盖全部 curriculum 档位)
5 #1457 #1463 对比 benchmark:microduck_alignment_compare.py(tfevents 跨 seed 汇总)+ 真实训练对比报告 scripts/microduck_alignment_report.md

验收证据

  • 配置层uv run scripts/audit_microduck_alignment.py184 MATCH / 0 GAP / 0 MISMATCH(NOTE 仅 max_iterations 预算与 mujoco-warp 版本两个非判定项)。
  • 对比实验(2000 iter × 4096 envs;UniLab seed 42/43 双 run,上游 seed 42 单 run——上游 seed43 按 maintainer 决策跳过):两侧均收敛到稳定行走(episode length 976 vs 945,time_out 占比 95.0% vs 88.7%);剩余差距 return -26.4%、收敛 785 vs 128 iter,归因于决策 A 保留的 PD-vs-BAM 执行器动力学差异(平滑性惩罚大一个数量级、tracking_ang_vel 0.023 vs 0.679),次因 mujoco-warp 3.10.0.3 vs 3.8.1;详见报告文档。进一步收敛需启动路线 C(复刻 BAM,独立 roadmap)。
  • 最终 head ed88d1b1(含 declared base 同步)本地 make test-all:2554 passed, 28 skipped, 1 xfailed;pre-commit 与 benchmark 检查全部通过。

用户可见行为变化

microduck 三任务(ppo tree)mjwarp/mujoco 两后端的物理步长(100→200Hz)、求解器、reset 分布、DR、reward 栈、终止集合、默认训练规模/seed 变化;训练 run 变为可复现。sac tree 未动(已知 alive=10.0 vs ppo 无 alive 的内部不一致,留给后续决策)。其他任务行为不变(env seed 与 episode 错峰传播均为 opt-in/向后兼容)。

范围复核遗留(实施期间新增的决策项,已在 child PR 记录)

  1. ResetStateTransaction/Entity 新增 body_inertia bind/write(base 层 owner API 面扩展,additive;SimBackendget_body_inertia getter,补它属 unisim-core,未做)。
  2. ManagerBasedRlEnv 新增冷路径 set_episode_length_buf(rsl_rl 5.0.1 适配)。

长期维护责任(roadmap 已确认)

microduck 对齐 contract 测试(上游版本演进时需人工重锚定,锚点集中在 alignment_contract.py docstring);对比 benchmark 脚本与报告模板。

Base 非 main,按 gate 规则本地 gate + review 构成完整合入门槛;远程 CI 由后续实际进入 main 的 PR 承担。

TATP-233 and others added 14 commits September 3, 2026 16:28
…n facilities

Issue #1453 (child 1/5 of #1452): declarative owner-layer contract table
against pollen-robotics/microduck_rl @ 29e887ec, read-only audit script,
drift-guard test, and zero-action statistical rollout script for the three
MicroDuck tasks (ppo tree, mjwarp owner).
…ment-baseline

feat(microduck): 对齐基线 contract 与受控对比设施
- scene_flat.xml <option>: implicitfast/Newton/pyramidal, iterations 10,
  ls_iterations 20, tolerance 1e-8, ls_tolerance 0.01 (upstream mjlab SimCfg
  injection values; timestep stays backend-owned via sim_dt)
- ppo microduck base: sim_dt 0.005 (substeps 4), push_robot per-env interval,
  terminations drop base_height (time_out + tilt 70 deg + nan_detection)
- reset_base event: reset_root_state_uniform xy +-0.5 m, yaw +-pi,
  z +[0, 0.01] on keyframe z=0.12, zero velocities, joints exactly HOME
- randomize_body_mass_inertia event: alpha-only pseudo_inertia slice scaling
  trunk_base mass+inertia by one shared log-uniform factor in [0.95, 1.05],
  sampled once per env and replayed every reset (upstream startup semantics);
  ResetStateTransaction/Entity gain body_inertia bind/write with a
  caller-compiled, mass-cross-validated default table
- alignment_contract: flip physics/solver/events/terminations entries to
  match; tests updated and extended
…cs-alignment

feat(microduck): 物理层对齐上游 microduck_rl(sim dt / solver / reset / DR / termination)
- thread env-level RNG seed through the three microduck mjwarp owners
  (env.seed=42): the Hydra -> BackendAdapter -> registry chain already
  reaches ManagerBasedRlEnvCfg.seed, so command/noise/delay/DR sampling is
  now reproducible across runs; unset owners keep the None default
- fix init_at_random_ep_len: RslRlVecEnvWrapper.episode_length_buf becomes
  a property whose setter propagates into the env's real episode counters
  via the new ManagerBasedRlEnv.set_episode_length_buf cold-path entry
  (keeps episode_length_buf and state.info["steps"] in sync); upstream
  mjlab's wrapper setter writes the env buffer directly, so staggering is
  effective upstream and now matches here
- scale alignment: algo.num_envs 2048 -> 4096 and algo.seed 1 -> 42 in all
  three mjwarp owners; max_iterations 500 -> 2000 (2000 x 24 = 48000 env
  steps, exactly covering every curriculum terminal stage; final budget
  remains a child 5 decision)
- flip infra.num_envs / infra.seed contract entries to match and add an
  infra.env_seed match entry guarding the new YAML field
…d-alignment

feat(microduck): velocity reward 栈对齐上游 microduck_rl HEAD
…-alignment

feat(microduck): 训练基建对齐上游(env RNG 播种 / init_at_random_ep_len / 规模与 seed)
Parse rsl_rl tfevents from multiple run dirs per side, aggregate
final-window stats and convergence speed across seeds, and emit a
markdown comparison report plus JSON curve dump. Handles aliased
reward/termination term names between the two codebases, skips
aborted runs with a warning, and degrades gracefully to single-seed
statistics.

Issue #1457 (roadmap #1452 child 5/5).
…rison-benchmark

benchmark(microduck): 受控对比验收——UniLab vs 上游 microduck_rl 统计一致性报告
…' into dev/issue-1452-microduck-rl-alignment
@TATP-233
TATP-233 requested a review from caozx1110 as a code owner September 3, 2026 12:40
@TATP-233
TATP-233 merged commit 530a20d into dev/issue-1042-manager-based-api Sep 3, 2026
@TATP-233
TATP-233 deleted the dev/issue-1452-microduck-rl-alignment branch September 3, 2026 13:08
@TATP-233

TATP-233 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

MicroDuck 对齐对比报告 + 剩余不一致的根因分析

本报告原以 scripts/microduck_alignment_report.md 入库,按 maintainer 要求移至本评论区(移除 PR:#1466)。报告可由 uv run scripts/microduck_alignment_compare.py 重新生成。

第一部分:对比报告

终段窗口 = 每 run 末尾 20% iterations;收敛速度 = mean_reward 首次达到自身终段均值 80% 的 iteration。

Runs

UniLab

run seed max_iterations
logs/rsl_rl_ppo/MicroduckVelocityFlat/2026-09-03_18-54-37_mjwarp 42 2000
logs/rsl_rl_ppo/MicroduckVelocityFlat/2026-09-03_19-20-43_mjwarp 43 2000

Upstream (microduck_rl)

run seed max_iterations
…/microduck_rl/logs/rsl_rl/velocity/2026-09-03_19-48-28_seed42 42 2000

⚠ upstream 侧只有 1 个 run,std 不可用,统计仅供参考。

总览指标

指标 UniLab 上游 相对差
mean_reward 终段均值 83.751 ± 5.422 113.833 (n=1) -26.4%
episode length 终段均值 976.211 ± 13.477 944.644 (n=1) +3.3%
收敛 iteration (80% final reward) 784.500 ± 132.229 128.000 (n=1) +512.9%

Reward term 终段对比

term (UniLab / 上游) UniLab 终段 上游终段 相对差
action_rate / action_rate_l2 -0.801 ± 0.127 -1.039 (n=1) +22.9%
air_time 1.391 ± 0.129 1.024 (n=1) +35.8%
body_ang_vel -0.349 ± 0.073 -0.031 (n=1) -1030.8%
dof_pos_limits -0.025 ± 0.017 -0.001 (n=1) -2494.5%
foot_clearance -0.022 ± 0.001 -0.004 (n=1) -401.2%
foot_swing_height -0.077 ± 0.007 -0.003 (n=1) -2203.4%
head_pose_bias -0.219 ± 0.000 -0.224 (n=1) +2.3%
head_pose_tracking 1.702 ± 0.047 1.705 (n=1) -0.1%
leg_pose / pose 0.062 ± 0.087 0.608 (n=1) -89.7%
self_collisions -0.007 ± 0.007 -0.001 (n=1) -581.4%
tracking_ang_vel / track_angular_velocity 0.023 ± 0.006 0.679 (n=1) -96.6%
tracking_lin_vel / track_linear_velocity 0.903 ± 0.171 1.267 (n=1) -28.7%
upright 1.605 ± 0.079 1.713 (n=1) -6.4%

Termination 构成对比

term (UniLab / 上游) UniLab 终段 上游终段 相对差
tilt / fell_over 0.214 ± 0.125 0.501 (n=1) -57.4%
time_out 4.038 ± 0.066 3.914 (n=1) +3.1%

终段占比:UniLab tilt 5.0% / time_out 95.0%;上游 fell_over 11.3% / time_out 88.7%。两侧均无 NaN 终止。

第二部分:剩余 -26.4% return 差距的根因分析

配置审计为 184 MATCH / 0 GAP(scripts/audit_sim2sim_contracts.py 口径的 microduck 对齐审计),即训练基建层面(obs/reward/curriculum/PPO 超参/网络结构/命令采样)已逐项对齐。在此前提下,剩余差距由以下三层原因构成,均有实验证据:

原因 1(主因):执行器模型不同 —— 两侧不是同一个 MDP

上游用 BAM(Beyond-Adda-Model)xl330-m6 电压舵机模型(固件 P 环 kp_fw=200、输入电压 DR 6.5–8.2 V、Coulomb/Stribeck/负载摩擦预算、15–30 ms 指令延迟);UniLab 用 XML position PD(kp=50, kv=0.5, forcerange ±0.96 N·m)。受控探针实验(两侧各 64 envs、seed 42、mjwarp 后端、真值直读 sim state)测得动力学差异是量级性的:

探针 UniLab (PD) 上游 (BAM) 倍数
零 action 姿态保持:基座角速度 ‖ω‖ 0.064 rad/s 1.049 rad/s ~16×
零 action:倾倒次数 / 倾倒 env 数(400 步) 35 / 35-of-64 383 / 64-of-64 ~11×
零 action:首次倾倒平均时刻 251 步(≈5 s,推力诱发) 64 步(≈1.3 s,自发性倾倒
膝关节 +0.2 rad 阶跃:t90 2 步(40 ms) ~18.6 步(~370 ms,补充协议近似值) ~9×
阶跃稳态误差 0.0004 rad -0.068 rad(34% 静态下垂) ~170×
零 action 稳态关节误差(承重关节) ≤0.0012 rad knee 0.148 rad(8.5°)、ankle 0.084 rad ~89×(总体均值)

BAM 的 HOME 姿态在零 action 下根本不是稳定平衡(膝下垂 8.5° → CoM 移出支撑域 → 平均 1.3 s 自发性倾倒),策略从第一步起就被迫学主动平衡;UniLab 的 PD 站姿近乎钉死(8 s 内仅推力能推倒),"站死不动"是近乎免费的强局部最优。这直接解释训练曲线上的两个观察:

  • 收敛慢 ~6 倍(128 vs 785 iter):BAM 侧 episode 前 1–2 s 持续产生倾倒/恢复强梯度经验;UniLab 侧策略要先卸载被动站立局部最优。曲线上 iter 50–100 上游 ep_len 从 136 跳到 815,UniLab 同期 39→109。
  • tracking_ang_vel 0.02 vs 0.68、leg_pose 0.06 vs 0.61:转身/姿态调整要对抗强得多的静止最优解;上游没有这个静止盆地。

此外 PD(40 ms 建立、无摩擦滤波)把 50 Hz 动作抖动几乎无损传到机身,BAM 的摩擦+电压限幅+延迟等效低通把高频动作能量衰减掉——同权重下 UniLab 的 body_ang_vel(-0.349 vs -0.031)、dof_pos_limits、foot_swing_height 类惩罚读数天然更大。

结论:即使基建完全一致,只要执行器模型不同,两个 MDP 的动力学内核就不同,"数值一致"在原理上不可达;量级性的执行器差异是剩余 return 差距的主要载体。要做到数值级一致,需要把 BAM 执行器模型本身也移植到 UniLab 侧(属新的 roadmap 范畴)。

原因 2(UniLab 侧 bug,可独立修复):步态项接触门控取错了力分量

src/unilab/tasks/locomotion/common/gait_terms.py:122_FootContactTerm 对 3-D force 传感器取第 2 列[0 if width == 1 else 2 ...])。但 microduck 的 left/right_foot_contact 是 MuJoCo <contact data="force"> 传感器,其力向量在接触坐标系下第 0 列是法向力(实测站立时每脚 2.4–4.1 N、合计 ≈ 机重 8 N;第 1/2 列为小切向分量)。上游 mjlab 侧用 found > 0 门控,不受此影响。

实测门控分歧(UniLab env、64 envs):

场景 第 0 列(法向,正确)接触率 第 2 列(gait_terms 现行)接触率 两约定一致率
站立(零 action) 98.3% 3.5% 5.2%
行走样动作 46.7% 20.9% 74.1%

即站立时 UniLab 的步态项把双脚 96.5% 的时间误判为"在空中"。受污染的范围:feet_air_time(weight 3.0)、feet_swing_heightfeet_slip 奖励,以及喂给策略的 foot_air_time / foot_contact / foot_contact_forces obs 通道。与训练读数方向吻合:UniLab air_time 虚高(1.39 vs 1.02,+36%)、foot_swing_height 惩罚放大 25 倍(-0.077 vs -0.003)。这部分差距与执行器无关,修复门控列约定即可回收(建议单独立项;注意 manager_terms.py 的 microduck 专用接触项已正确取第 0 列,修复时需兼顾 width-1 found 与 width-3 force 两种传感器形态及其他机器人在用的 site-frame 力传感器约定)。

原因 3(次因):模拟器版本与随机性

UniLab 用 mujoco-warp 3.10.0.3,上游用 3.8.1;接触求解器细节差异存在但探针未显示其主导任何观察到的量级性差异。上游仅 1 个 seed 的 run,-26.4% 中亦含 seed 噪声成分(UniLab 双 seed 间 std 已有 ±5.4)。

归因汇总

  • 配置/基建层:已对齐(184 MATCH / 0 GAP),不是剩余差距的来源。
  • 剩余 -26.4% ≈ 执行器动力学差异(主因,MDP 层面不同,需移植 BAM 才能数值级一致)+ 接触门控 bug(可独立修复的 UniLab 缺陷)+ 模拟器版本/seed 噪声(次要)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant