这几天围绕supermimic的perception做了一些探索,但是不太成功,姑且记录一下进展。下面内容由codex记录生成。
这几天围绕 SuperMimic 做了一轮探索,想解决的问题其实很直接:已经有一个能在平地上跟踪人体动作的策略,能不能让它看到地形,然后在保留动作意图的同时,自己调整落脚和身体运动?
这个想法说出来很自然。人走上台阶的时候,不会把原来的动作原封不动地搬上去,也不会完全忘掉自己本来要往哪里走。那我能不能给模型加一个局部高度图,让它也学会这件事?
最后的结果是,还没有做到。
地形物理、局部感知、训练和评测都跑起来了,也有一些局部改善。但到现在,我还没有得到一个整体超过原平地策略,而且能把提升稳定归因于空间感知的版本。中间甚至出现过训练越久、动作越差,以及几次策略更新就明显崩掉的情况。
所以这篇就当一次失败记录。把每一步为什么做、为什么又转向写下来,也免得以后只记得“试过,没用”,却忘记当时到底试到了哪一步。
先把地形训练本身做成立
先交代一下起点。我用的是 Uni-SuperMimic / UniLab 的实现和 MuJoCo Warp 仿真。已有两次本地平地训练可以作为后续对照,都跑到了 12,000 轮;其中梯度累积版本在本地 40 段动作检查中没有失败。不过这只能说明我手里有可用的历史基线,不能算完成了原论文的复现认证。
最开始的想法比较朴素:给策略、世界模型和 critic 都加入地形条件,再按照地面高度修正参考动作。
但这件事首先卡在了工程上。reset 和参考动作的世界坐标要统一,参考路径经过哪里,就要逐帧采样哪里的地面;策略看到的高度图,还得和物理碰撞使用的三角面一致。细网格又触发了高度场接触截断,最后把碰撞网格改到了 0.125 m。梯度累积、续训记录和越界处理也都做了修正。
这里还有个很容易记错的细节:最初那份旧作业只跑到第 500 轮,当时还在世界模型预训练阶段,策略根本没有开始学习。所以它不能被描述成“地形策略已经训练了一半”。作业在跑,和我想研究的东西开始被训练,是两回事。
修正之后,我先把地形高度降到原来的四分之一,只保留 18 段 walk / run / sprint。先看温和地形上的局部跟踪能否成立。
这一版跑完了 12,000 轮,日志累计约 14.61 小时。选出的检查点在默认 126 个五秒窗口中全部完成,回报也还可以。但专门挑出真正经过台阶和坡面的 54 个窗口之后,结果就没那么漂亮了。
| 同一地形场景下的策略 | 完成窗口 | 根部 XY 误差 | 关节 RMSE |
|---|---|---|---|
| 历史平地策略 | 52/54 | 38.68 cm | 7.71° |
| 温和地形策略 | 53/54 | 47.98 cm | 10.76° |
上台阶确实有改善:完成数从 16/18 到 18/18,根部误差也下降了。但下台阶和坡面退步,整体动作误差更大。正常地图、置零地图和打乱地图时,完成数分别是 53、51、49,说明输入会影响行为,却还不足以证明这种影响带来了整体优势。
这是第一次需要收回最初的乐观判断。机器人能把窗口跑完,不代表它完成了我真正想要的地形适配。
后面的评测都得把完成数、动作误差、路径进度和地图贡献拆开看。另外,不同阶段改过地图、奖励和窗口,数字只能在各自的配对协议里比较,不能直接串成一条“越来越好”的曲线。
真正加上感知之后,训练反而把动作练坏了
接下来做了更完整的感知版本。
这次把人体动作意图和地形实现分开:意图编码器不读地形,动作 decoder 结合本体状态和局部地图执行。地图是带有效性、时效信息的因果高度记忆,分辨率为 0.1 m,整体 41×41,供策略查询 21×21 的局部 patch,还显式加入了 200 ms 指令延迟。
这里的“感知”也需要说清楚:高度来自仿真视锥内的高度场采样,没有运行真实深度成像或 SLAM。这是一个可部署接口方向上的模拟,距离真实机器人的感知链还有区别。
训练沿用 SuperMimic 的主线:在真实仿真中收集转移,世界模型拟合 8 步,策略在模型中展开 32 步并反向传播,critic 提供长期价值。任务上强调根部轨迹、朝向和上身意图,减弱下身风格约束,希望腿部能有空间适应地形。
这一阶段还有一次比较实在的效率优化。早期配置因为微批太小、反复分发和快照操作,预估要跑大约 15 天。调整索引、静态形状编译和微批之后,策略与 critic 更新从旧配置的 20.50 秒降到 4.03 秒,完整感知版每轮大约 5.47 秒。最后用 1,024 个环境跑到 12,000 轮,累计约 15.56 小时,收集约 3,085 万条真实转移。
训练预算确实跑完了。但动作质量没有随之变好。
在一组针对性的 54 窗口检查中,结果是这样的:
| 策略 / 输入 | 完成窗口 | 根部 XY 误差 | 上身位置误差 |
|---|---|---|---|
| 原生平地策略 | 54/54 | 16.74 cm | 2.99 cm |
| 感知版早期检查点 | 54/54 | 13.69 cm | 2.86 cm |
| 感知版最终检查点 | 54/54 | 18.54 cm | 10.49 cm |
| 最终检查点,地图平面化 | 54/54 | 18.45 cm | 10.46 cm |
早期检查点一度比平地策略好,但继续训练之后,这点收益没有保住,上身动作还明显失真了。更麻烦的是,把地图的空间高度变化抹平,结果几乎不变。
这次平面化仍保留了身体离地高度等信息,所以不能当成完全没有地形输入的实验。但至少它没有提供“策略已经学会利用地图空间结构”的证据。
到这里,我需要重新考虑:给了输入,模型就一定会学会使用吗?它究竟在根据地图调整动作,还是在利用别的信息降低某些误差,同时牺牲掉了原本的动作质量?
世界模型预测得准,梯度就可信吗?
第一轮重构试图从任务目标和优化方式上解决动作变形:恢复原生动作目标接口,把空间几何和身体离地高度分开,使用更完整的全身跟踪目标,并修正价值 bootstrap 和终止处理。
结果更糟。到第 40 轮、实际 20 次策略更新之后,54 个窗口的完成数从 54 降到 37;根部误差从 13.95 cm 升到 189.05 cm,回报从 0.9082 降到约 −0.0050。世界模型的 8 步误差指标也明显上升。
这个结果首先说明新配置训练失稳了,不能据此把“感知”或者全部重构思路一起判死刑。于是后面固定共同起点,分别检查学习率、末端价值项和想象展开长度。
把策略学习率从 降到 后,至少没有继续以同样的方式迅速崩掉。但“训练稳定”和“任务更好”仍然差得很远。在留出地形的 252 个配对窗口上:
- 完整感知 v1 的根部误差低于平地策略,但上身误差从约 3 cm 增加到约 10 cm,完成数也下降了。
- 32 步、关闭 learned-value 的分支保住了一些上身质量,路径跟随仍然退步。
- 8 步、关闭 learned-value 的分支只完成了 6/252 个窗口,明显失败。
所以“长展开有问题,那就缩短”也没有直接解决问题。尤其最后一组,误差只统计到了实际执行的片段;一个早早失败的策略,不能因为某项平均误差看起来还行就被认为表现不错。
这一阶段最值得留下来的问题,是世界模型的状态预测和它给出的优化方向之间的区别。
固定动作做预测,完整感知版在 36 次诊断中,8 步根部和足端误差大约只有 0.78 cm、1.75 cm;到了 32 步,分别增加到约 7.89 cm、7.97 cm。短期拟合看上去并不差。
但策略训练依赖的是:沿着模型给出的方向修改动作,真实物理里的结果会不会更好?
为此,又用独立的 CPU MuJoCo 对 162 个窗口做了固定动作扰动验证。32 步模型预测有收益的一些小步方向,在真实物理中平均仍是负收益;从中段接触状态检查 8 步方向,又能保留部分有用的局部导数。
这说明问题比“世界模型完全错了”更具体。它能预测一些局部变化,也能给出部分有用方向,但这不足以保证长时间策略优化可靠。同样,局部导数有用,也推不出短视野闭环训练一定有效——前面的 8 步分支已经给了反例。
critic 也会明显影响更新。同一批真实数据、同一模型和策略,只切换末端价值项,一次更新的原始梯度范数分别为 9.12 和 1.61,方向余弦只有 0.159。末端价值项确实显著主导了这次更新,但这还不是它导致全部长期退化的证明。
后来还试过只接受很小的候选更新,锁定后再做留出评测。两次重复平均下来,根部误差只改善 0.35 cm,95% 区间跨零,主配对完成数还从 250 降到 249,也没过预设门槛。
小更新能带来局部变化,但还没有变成可靠的任务提升。
换条路:先改参考,再绕开模型梯度
走到这里,我开始把问题往前拆:会不会给定的参考动作本身就不适合地形?如果动作目标有问题,让策略更努力地跟踪它,也未必能解决。
于是先做了一个离线参考适配探针。直接读取完整窗口和真实地形,识别支撑、摆动阶段,通过足端目标、骨盆高度和 IK 修改参考,再交给现有 tracker。
它有意拿到了额外未来信息,目的是先隔离“感知不够好”和“参考不适合地形”这两个问题。
结果仍然没有成立。54 个强相关窗口里,初版修正参考逐帧的运动学检查通过率有 94.22%,但完整窗口全部采样点都通过的只有 16/54。平地 tracker 的根部误差几乎没变,完成数反而从 53 降到 52。
再检查实现,还发现了接触标签误判抬高、倒置的脚,以及摆动包络缺陷造成异常轨迹的问题。修掉这些之后,支撑几何有改善,但摆动目标仍可能穿地,也没有约束整段动力学。
所以这一步没有构造出一个经过验证、真正可执行的地形参考。“脚的位置看起来对了”和“整段动作能被物理系统执行”之间,还缺了不少东西。这次失败不能拿来否定参考教师路线,只能说明我做出来的探针还不足以检验它。
随后又绕开世界模型的策略梯度,改用真实物理 PPO。冻结原生意图 encoder、latent 到动作的 decoder 和归一化,只让感知模块调整 pre-tanh latent,并训练独立的 value。
这里比较了两种任务:一种保留全身跟踪,一种放松腿部姿态、速度、骨盆高度和倾斜约束,希望它能保留高层意图,同时调整落脚。
两个分支各跑了 100 轮、约 164 万条真实转移。训练没有出现前面那种同类模型梯度失稳,但也没有超越基线:在这轮独立的 252 个留出窗口中,平地策略完成 251 个,根部误差 23.60 cm;两个 latent PPO 分支都完成 250 个,根部误差分别为 25.74 cm、25.32 cm,路径进度也下降。
放松腿部约束没有自动带来更好的步态。一个可能的限制是,冻结的 decoder 约束了 latent 能表达的动作和探索范围,但这仍然只是需要进一步检验的解释,不能说已经找到根因。
最后把 decoder 也打开了,还是没有过关
既然怀疑固定动作先验限制适配,那就再把 decoder 打开。
最后一轮冻结意图 encoder 和归一化,开放动作 decoder,新增地图通路从零初始化,用真实物理 PPO 学习 29 维关节动作。同时独立训练一组地图空间高度平面化的对照,用来区分 decoder 微调本身的效果和地图结构的贡献。
这一轮有个很具体的数值问题:BF16 的 batch 差异会导致参数还没更新,KL 就已经约为 0.0086。改成 FP32 后降到约 ,才把这个干扰排掉。策略学习率也从 降到 。
两组各训练 100 轮、约 164 万条真实转移,物理容量溢出和动作 clamp 都为零。在 54 个固定四秒窗口中:
| 策略 | 完成窗口 | 根部 XY 误差 | 上身误差 | 路径进度 |
|---|---|---|---|---|
| 原生平地策略,FP32 | 53/54 | 27.64 cm | 3.26 cm | 91.21% |
| 开放 decoder,正常地图 | 53/54 | 28.03 cm | 3.32 cm | 91.20% |
| 开放 decoder,独立无空间训练 | 54/54 | 29.67 cm | 3.16 cm | 91.82% |
正常地图版比平地基线的根部误差增加了 0.39 cm;相对独立无空间训练组,根部误差减少了 1.65 cm,但 95% 区间跨零,上身误差更大,还少完成一个窗口。
两组都没有达到预设的“根部误差至少改善 2 cm,且区间排除零”门槛。因此这轮没有选出可以进入后续大训练和留出评测的胜出模型。
它至少说明,在这次短预算里,把 decoder 打开也没有自动产生有效的感知行为。至于更长训练、不同数据或不同接口会怎样,这轮实验还回答不了。
这几天到底留下了什么
回头看,最开始我把它想成了一个“给已有策略多加一种输入”的问题。做下来才发现,地形改变的是接触要求,而原有参考、动作先验和优化目标未必允许对应的动作。
约束放松了,动作容易失真;decoder 冻住了,可能限制适配;decoder 打开之后,短预算里也没学出可靠的地图使用。再叠加长时间模型梯度和价值项,优化方向还可能进一步偏离真实物理中的收益。
这些都是目前证据支持继续检查的问题方向,还不能合并成一个已经证实的唯一根因。我也不想把每次没成功都解释成“再调几个参数就好了”。至少到现在,这条链路没有给出足够可靠的结果。
但有几件事已经更清楚了:能活下来不等于保留了动作,根部误差下降不等于全身控制更好,地图输入影响行为也不等于空间感知有用。把训练完整跑完,和把最初的想法验证出来,确实是两回事。
后续如果重启,我更倾向于先构造接触一致、经过真实物理验证的地形教师或参考,再配合可以继续学习的动作执行器。不过这只是下一步候选方向,这个项目还没有把它验证出来。
目前就先停在这里,保存代码、数据和这些没有过关的结果。最初想得到的那个“看到地形之后,仍然能把原来的动作做好”的策略,这几天还没有做出来。