Roadmap #1452: microduck 任务与上游 microduck_rl 训练配方对齐(集成分支) - #1464
Conversation
…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)
…1455-microduck-reward-alignment
- 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
…1456-microduck-infra-alignment
…-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
MicroDuck 对齐对比报告 + 剩余不一致的根因分析
第一部分:对比报告终段窗口 = 每 run 末尾 20% iterations;收敛速度 = mean_reward 首次达到自身终段均值 80% 的 iteration。 RunsUniLab
Upstream (microduck_rl)
总览指标
Reward term 终段对比
Termination 构成对比
终段占比:UniLab tilt 5.0% / time_out 95.0%;上游 fell_over 11.3% / time_out 88.7%。两侧均无 NaN 终止。 第二部分:剩余 -26.4% return 差距的根因分析配置审计为 184 MATCH / 0 GAP( 原因 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)测得动力学差异是量级性的:
BAM 的 HOME 姿态在零 action 下根本不是稳定平衡(膝下垂 8.5° → CoM 移出支撑域 → 平均 1.3 s 自发性倾倒),策略从第一步起就被迫学主动平衡;UniLab 的 PD 站姿近乎钉死(8 s 内仅推力能推倒),"站死不动"是近乎免费的强局部最优。这直接解释训练曲线上的两个观察:
此外 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,可独立修复):步态项接触门控取错了力分量
实测门控分歧(UniLab env、64 envs):
即站立时 UniLab 的步态项把双脚 96.5% 的时间误判为"在空中"。受污染的范围: 原因 3(次因):模拟器版本与随机性UniLab 用 mujoco-warp 3.10.0.3,上游用 3.8.1;接触求解器细节差异存在但探针未显示其主导任何观察到的量级性差异。上游仅 1 个 seed 的 run,-26.4% 中亦含 seed 噪声成分(UniLab 双 seed 间 std 已有 ±5.4)。 归因汇总
|
Closes #1452 | Roadmap 集成分支最终 PR | Base:
dev/issue-1042-manager-based-api(declared base,已在集成点同步其最新 head73dd2403)集成结果
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 合入本分支)
alignment_contract.py,81 条/velocity)+audit_microduck_alignment.py+ 防漂移测试 +microduck_alignment_rollout.pyrandomize_body_mass_inertia+ Entity/transaction body_inertia 写入路径)、push per-env、去 base_height 终止init_at_random_ep_len适配层修复(wrapper setter 传播进 env 真实计数)、num_envs 4096、max_iterations 2000(覆盖全部 curriculum 档位)microduck_alignment_compare.py(tfevents 跨 seed 汇总)+ 真实训练对比报告scripts/microduck_alignment_report.md验收证据
uv run scripts/audit_microduck_alignment.py→ 184 MATCH / 0 GAP / 0 MISMATCH(NOTE 仅 max_iterations 预算与 mujoco-warp 版本两个非判定项)。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 记录)
ResetStateTransaction/Entity新增 body_inertia bind/write(base 层 owner API 面扩展,additive;SimBackend缺get_body_inertiagetter,补它属 unisim-core,未做)。ManagerBasedRlEnv新增冷路径set_episode_length_buf(rsl_rl 5.0.1 适配)。长期维护责任(roadmap 已确认)
microduck 对齐 contract 测试(上游版本演进时需人工重锚定,锚点集中在
alignment_contract.pydocstring);对比 benchmark 脚本与报告模板。Base 非
main,按 gate 规则本地 gate + review 构成完整合入门槛;远程 CI 由后续实际进入main的 PR 承担。