PAPER DEEP DIVE
FADA:人形控制的少样本动力学适应
该工作提出 Planner-IDM 框架:先用特权信息训练 oracle 策略,再通过 DAgger 蒸馏成规划器与逆动力学模型;部署时冻结规划器,仅用约2分钟目标域数据监督微调 IDM,使机器人适应坡面、负载与执行器变化。
一句话总结
FADA 把人形控制器拆成“规划器指定六步本体感知意图 + 逆动力学模型把意图变成动作”,部署后冻结规划器,只用约两分钟目标域执行轨迹对 IDM 做低秩微调;这让 Unitree G1 与 Booster T1 在坡面、软地、负载和持续拉力下完成从 20% 到 80–100% 的成功率跃迁,也不需要目标域奖励、示教、动捕或仿真器重标定。
研究背景与动机
仿真已经成为人形控制器的主要训练场。域随机化能覆盖摩擦、负载、执行器响应和观测噪声,DAgger 能把特权教师蒸馏成只靠本体感知的学生,IsaacSim 又提供了大规模安全试错空间。问题在于,这些组件解决的是源域分布内的稳健性:一旦真实硬件的地形刚度、接触状态、载荷位置或执行器响应落在分布之外,同一个控制命令可能不再诱导同样的身体运动。
这种差距不会因为策略泛化到了“相似任务”就自动消失。窄坡上的落脚误差、软地上的姿态漂移、单侧负载造成的重心偏移、持续外力造成的力矩补偿误差,都会在全身自由度间相互放大。小误差改变接触时刻,接触时刻改变支撑多边形,支撑多边形又反过来改变下一步动作的有效性。因此,人形全身控制的 sim-to-real 问题不只是“感知不足”,更是“意图到动作的映射发生了位移”。
论文在 Figure 2 中把现有方法分成两个大方向。零样本路线靠域随机化和历史条件化上下文吸收扰动,部署时不更新参数;目标域数据路线则做系统辨识、残差动力学或策略微调。前者往往保守,后者又要求可辨识模型、示教或可计算的目标域奖励。作者的问题因此很尖锐:能否只用少量目标域普通执行数据,在没有目标域奖励、特权标签、最优示教和准确先验模型的情况下,完成高精度人形控制适应?
普通执行轨迹是容易被忽略的监督来源。机器人按零样本策略跑约两分钟时,本就产生了配对的本体感知观测和已执行动作。虽然这些轨迹不是最优的,但每个未来观测窗口都因果地对应一组真实发生过的动作。FADA 的核心洞察就是把这个自监督配对用作逆动力学监督:在新物理条件下,重新校准“给定意图应该输出什么动作”的执行端,而不是重新学习任务语义。
这一设计的产业含义比单个任务指标更重要。全策略微调容易把命令解释、任务规划和执行耦合在一起改动,安全风险和数据成本都高;只微调执行端则可以保留已验证的任务接口。FADA 仓库把六步管线、oracle checkpoint、MuJoCo 与真机采集代码一并发布,训练、蒸馏、ONNX 导出、目标域采集、LoRA 微调和前后对比都能按 README 复现。
问题设定:什么允许改,什么必须冻结
设固定任务为 $\mathcal{T}$,部署条件为 $\xi$。每个任务和条件对应一个 MDP:
$$\mathcal{M}_{\mathcal{T},\xi}=(\mathcal{S},\mathcal{O},\mathcal{A},p_{\xi},r_{\mathcal{T}}).$$
这里 $s_t\in\mathcal{S}$ 是完整状态,$o_t\in\mathcal{O}$ 是部署可用的本体感知观测,$a_t\in\mathcal{A}$ 是动作,$c_t\in\mathcal{C}$ 是任务命令或参考运动。域偏移集中在转移函数 $p_{\xi}$ 上,而任务奖励 $r_{\mathcal{T}}$ 在目标域不可用。源域训练有特权 oracle $\pi^{o}(s_t,c_t)\mapsto a_t^{\star}$,可部署学生只接收历史 $\mathcal{O}_t^H$、动作历史 $\mathcal{A}_t^H$ 和命令 $c_t$:
$$\pi^{s}(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},c_{t})\mapsto a_{t},\quad\mathcal{O}_{t}^{H}=(o_{t-H+1},\ldots,o_{t}),\quad\mathcal{A}_{t}^{H}=(a_{t-H},\ldots,a_{t-1}).$$
目标域采集数据被记为
$$\mathcal{D}_{\mathrm{tgt}}=\{\tau_{i}\}_{i=1}^{N_{\mathrm{roll}}},\qquad\tau_{i}=\{(o_{t},c_{t},a_{t})\}_{t=0}^{T_{i}}.$$
这三条式子划清了问题的边界:适应只能读 $\mathcal{D}_{\mathrm{tgt}}$,不能读目标域奖励,不能读特权接触力和地形高度,也不能用专家动作做标签。模型输出的所有 $H$ 和 $K$ 都有具体含义:实验用 30 帧历史 $H=30$ 和 6 步预测视界 $K=6$。
方法详解:把执行端变成可微调的接缝
FADA 的结构性判断是:地形、负载和执行器变化通常不改变“该往哪里走、该跟踪哪段参考”,但会改变“为达成那个意图必须施加什么动作”。因此它把学生策略写成 Planner-IDM 因子化 $\pi^{s}=(P_{\phi},I)$。Planner 读取历史和命令,输出 $K$ 步未来本体感知意图 $\hat{Y}_{t}^{K}$;IDM 读取历史、动作历史和这个未来窗口,输出动作块 $\hat{U}_{t}^{K}$。部署只执行第一个动作:
$$\hat{Y}_{t}^{K}=P_{\phi}(\mathcal{O}_{t}^{H},c_{t}),\qquad\hat{U}_{t}^{K}=I(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},\hat{Y}_{t}^{K}),\qquad\hat{a}_{t}=\Pi_{1}(\hat{U}_{t}^{K}).$$
$\Pi_1$ 是这个方法里最容易被误解的算子。它不只是取数组第一项,更是训练与部署的契约:IDM 虽然预测六步动作块,但训练目标只匹配第一个动作,部署也只执行第一个动作。这让学习目标与 receding-horizon 执行不发生错位,也让目标域 rollout 中因果配对的“未来观测 + 实际动作”天然成为监督。
源域 IDM 学习:用真实执行过的动作做逆动力学标签
从 DAgger-style 源域 rollout 中取出窗口 $(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},Y_{t,\mathrm{exec}}^{K},U_{t,\mathrm{exec}}^{K})$。注意 $U_{t,\mathrm{exec}}^{K}$ 是学生当时实际执行的动作,不是 oracle 动作。IDM 的源域损失为
$$\mathcal{L}_{I}(\psi)=\mathbb{E}_{(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},Y_{t,\mathrm{exec}}^{K},U_{t,\mathrm{exec}}^{K})\sim\mathcal{D}_{I}^{\mathrm{src}}}\left[\left\|\Pi_{1}\!\left(I(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},Y_{t,\mathrm{exec}}^{K})\right)-\Pi_{1}(U_{t,\mathrm{exec}}^{K})\right\|_{2}^{2}\right].$$
这解释了为什么同一个目标能搬到不完美的目标域数据。DAgger 源域本来混合了教师引导和较弱的学生轨迹;IDM 学到的不是“理想 oracle 会做什么”,而是“某个物理因果序列下实际发生的那组动作”。目标域 rollout 同样是不最优的真实执行,只是物理条件变了,所以它仍然构成合法的逆动力学样本。
源域 Planner 学习:可行动的未来,而不是可回归的未来
直接让 planner 回归 oracle 未来观测是失败的。观测轨迹看起来合理,不代表经过 IDM 后会得到正确动作。FADA 因此让 planner 的输出先经过当前 IDM,再对 oracle 第一动作求 MSE,并在反向传播到 planner 时对 IDM 停梯度:
$$\mathcal{L}_{P}(\phi)=\mathbb{E}_{(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},c_{t},a_{t}^{\star})\sim\mathcal{D}_{P}^{\mathrm{src}}}\left[\left\|\Pi_{1}\!\left(I_{\bar{\psi}}(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},P_{\phi}(\mathcal{O}_{t}^{H},c_{t}))\right)-a_{t}^{\star}\right\|_{2}^{2}\right].$$
这里 $I_{\bar{\psi}}$ 表示梯度不穿过 IDM。这个设计把 planner 的评价标准从“未来像不像”改成“未来是否有利于动作预测”。附录 B 还给出 planner 的残差形式 $\hat{Y}_{t}^{K}=o_t+\Delta\hat{Y}_{t}^{K}$,说明它预测的是相对最近观测的增量。源码中 `fada/planner_idm/model.py` 和 `common/backbone.py` 实现 planner 与 IDM 的 transformer 结构,`trainer_batching.py` 管理未来观测掩码、噪声和损失分支。
oracle relabeling:在学生轨迹上恢复特权标签
planner 的 oracle 第一动作不是采集时直接存下的。系统会保存学生轨迹中每个访问状态处的仿真快照;rollout 结束后,把 oracle 放回同一状态,在相同命令下前滚 $K$ 步,得到因果一致的 oracle-shadow 对 $(Y_{\mathrm{orac}}^{K},U_{\mathrm{orac}}^{K})$,取其第一动作作为 $a_t^\star$。轨迹来源批次则用真实执行对 $(Y_{\mathrm{traj}}^{K},U_{\mathrm{traj}}^{K})$:
$$(Y_{I}^{K},U_{I}^{K})=\begin{cases}(Y_{\mathrm{traj}}^{K},U_{\mathrm{traj}}^{K}),&\text{for trajectory-source batches},\\ (Y_{\mathrm{orac}}^{K},U_{\mathrm{orac}}^{K}),&\text{for oracle-source batches}.\end{cases}$$
这不是廉价的标签插补。oracle-shadow 是物理前滚产生的,未来观测与动作之间保持因果一致,避免了用不存在的轨迹伪造监督。源码 `fada/planner_idm/trainer_rollout.py` 明确执行 snapshot restore、oracle forward 和 oracle-shadow chunk 组装,这是论文与代码的关键对应点。
目标域适应:冻结意图端,只学一个低秩执行修正
部署时先让零样本 FADA-zs 在目标域跑约 6000 个控制步。对 locomotion 任务,这是 50 Hz 下约两分钟;对全身跟踪任务,是六次约 20 秒参考运动。从这些普通轨迹中切出监督窗口 $\mathcal{W}_{\mathrm{tgt}}$,只优化 IDM 的低秩增量 $\Delta\psi$:
$$\mathcal{W}_{\mathrm{tgt}}=\left\{\left(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},Y_{t,\mathrm{exec}}^{K},U_{t,\mathrm{exec}}^{K}\right)\right\},$$
$$\ell_{\mathrm{adapt}}(\Delta\psi)=\mathbb{E}_{(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},Y_{t,\mathrm{exec}}^{K},U_{t,\mathrm{exec}}^{K})\sim\mathcal{W}_{\mathrm{tgt}}}\left[\left\|\Pi_{1}\!\left(I_{\psi+\Delta\psi}(\mathcal{O}_{t}^{H},\mathcal{A}_{t}^{H},Y_{t,\mathrm{exec}}^{K})\right)-\Pi_{1}(U_{t,\mathrm{exec}}^{K})\right\|_{2}^{2}\right].$$
适应后的策略是 $\pi^{\mathrm{ft}}=(P_{\phi},I_{\psi+\Delta\psi})$。LoRA 的作用不只是省显存。全参数微调会放大两分钟数据中的过拟合,而低秩参数化限制了执行修正的表达空间,迫使模型学习跨目标、跨姿态一致的动力学补偿。源码 `fada/common/lora_utils.py` 用 `LoRALinear` 与 `LoRAMultiheadAttention` 包住线性层和 packed QKV,同时保持基座冻结;`finetune_idm_lora.py` 是目标域微调入口。
为什么要冻结规划器
“必须冻结”其实应写成“必须冻结 planner”:目标域数据由零样本策略收集,所以它只包含旧意图接口下可行的经验。如果同时改 planner,新意图可能指向没有监督支撑的动作方向,旧数据反而会污染接口。冻结 planner 还保证前后接口完全一致,便于用相同命令序列做 pre/post 对比。第 5.6 节的 7 自由度机械臂实验把这一点说得很清楚:同一末端目标在 0、2.5、5.0 kg 腕载下的 planner RMSE 只变化约 7%,而 IDM 微调能显著降低跟踪误差和一致性差距。
flowchart TB
subgraph SRC["Source training"]
ORC[Privileged oracle] --> DAS[DAgger rollouts]
DAS --> YU[Realized future Y and executed U]
YU --> IDM1[IDM first-action loss]
DAS --> REL[Oracle relabel snapshots]
REL --> PLAN[Planner through frozen IDM]
PLAN --> STUDENT[Planner-IDM student]
end
STUDENT --> ZS[Zero-shot FADA-zs]
ZS --> COL[Collect about 2 min target rollouts]
COL --> WIN[Extract paired windows]
WIN --> LORA[LoRA update on IDM only]
LORA --> FT[Adapted policy]
FT --> RUN[Execute first action]
RUN --> VERIFY[Same command pre/post test]
图中两条损失并不是通用流程图。源域 IDM 用真实执行动作,planner 却要通过冻结 IDM 对 oracle 第一动作求导;目标域则把同样的首动作契约用于 LoRA。每一步只动一个组件,接口始终可测。
代码对应:方法不是概念,而是一条可运行链
第一处对应是 oracle relabeling。`trainer_rollout.py` 保存访问状态快照,并在 rollout 后运行 oracle 得到未来观测与动作 chunk,直接实现 Algorithm 1 的 S2。第二处对应是 LoRA 冻结。`common/lora_utils.py` 定义基座冻结的低秩线性层与注意力,`finetune_idm_lora.py` 从目标域 H5 数据集注入 adapter 并导出 ONNX。第三处对应是首动作执行。推理侧 `locomotion_fada.py` 只消费第一个动作,并在采集模式中把实际未来观测与实际动作写入窗口。README 也明确:源域是 oracle PPO,第 2 步是 Planner-IDM DAgger,第 4 步可以先用 MuJoCo 采数据,真机 H5 走同一格式。
实验结果:增益集中在执行端
平台是 Unitree G1(29 DoF)和 Booster T1(23 DoF)。所有学生策略在 IsaacSim 训练,历史 $H=30$、视界 $K=6$。真机五个任务包括 15° 双坡穿越、约 3 kg 不对称杂货负载、软地功夫跟踪、T1 单臂 1 kg 负载和约 6 kg 拉篮。真机每任务平均 5 次硬件试验,主 sim-to-sim 平均 20 次。适应预算统一为约 6000 控制步,即 50 Hz 下约两分钟。
真机:两个成功率任务几乎翻倍
| 方法 | G1 坡面成功率 | G1 负载速度误差 | G1 软地 MPJPE | T1 负载速度误差 | T1 拉篮成功率 |
|---|---|---|---|---|---|
| TF-DAgger | 0% | 1.000±0.203 | 1.00±0.091 | 1.000±0.132 | 0% |
| FADA-zs | 20% | 1.289±0.711 | 1.18±0.103 | 1.043±0.025 | 20% |
| FADA | 80% | 0.797±0.018 | 0.86±0.084 | 0.866±0.040 | 100% |
表中归一化误差以 TF-DAgger 为 1.0,越低越好。两个成功率任务的均值从 20% 提到 90%,TF-DAgger 均为 0%。三个连续误差任务相对 FADA-zs 平均降低 27.4%,相对 TF-DAgger 平均降低 15.9%。同时,五个任务的 IDM loss 全部下降。这说明性能改善不是某一次跑得好,而是与新物理条件对齐的动作预测普遍变准。
零样本失败呈现两种模式。坡面和软地触地时策略仍能发起正确技能,但落脚和姿态误差逐渐积累;负载或拖拽时规划意图仍合理,动作映射却无法继续实现意图。IDM 微调正好作用在这两种模式上:它不重写任务,而是重新校准执行映射。G1 在形变软垫上的功夫跟踪尤其说明问题,因为软垫不在源域随机化分布内。
sim-to-sim:目标监督必须有正确作用点
| 方法 | G1 坡面 | G1 功夫 | T1 负载 | T1 坡面 | T1 Falcon |
|---|---|---|---|---|---|
| TF-DAgger | 1.000±0.439 | 1.000±0.052 | 1.000±0.143 | 1.000±0.252 | 1.000±0.086 |
| TF-CoPred-zs | 0.973±0.387 | 1.031±0.068 | 1.029±0.142 | 1.080±0.224 | 0.943±0.133 |
| TF-CoPred-ft | 1.611±0.488 | 1.421±0.198 | 1.737±0.387 | 1.193±0.246 | 1.054±0.162 |
| FADA-zs | 0.946±0.358 | 0.961±0.055 | 1.042±0.147 | 1.034±0.334 | 0.880±0.094 |
| FADA | 0.800±0.236 | 0.714±0.048 | 0.885±0.135 | 0.914±0.193 | 0.347±0.043 |
IsaacSim-to-MuJoCo 五任务上,FADA 相对 FADA-zs 平均降低 24.7% 归一化误差,相对 TF-DAgger 平均降低 26.8%。最大增益出现在 T1 Falcon:机器人要在跟踪速度的同时抵消持续向下拉力,动作补偿误差直接决定成败,FADA 将误差降到 0.347。反例同样重要:TF-CoPred-ft 改进未来观测预测,却让所有任务变差。可见预测未来观测不等于修正动作生成。
视界、目标设计、LoRA 和数据预算
| 设计 | 关键数字 | 结论 |
|---|---|---|
| 预测视界 $K$ | $K=1$ 归一化误差 1.000;$K=6$ 为 0.830/0.813;$K=10/15$ 无增益 | 六步未来窗口约带来 18% 提升,更长视界不必要 |
| 损失设计 | 去掉首动作监督,真机成功率从 10/10 降到 4/10;去掉 planner-through-IDM,降到 7/10;两者都去,只剩 1/10 | 训练目标必须匹配 receding-horizon 执行 |
| LoRA vs 全参微调 | G1 坡面 0.8463 vs 1.1000;T1 负载 0.8489 vs 1.1163;T1 坡面 0.8846 vs 1.2918 | 两分钟预算下全参 IDM 过拟合,低秩约束反而稳 |
| 目标数据量 | 6000 步(约两分钟)误差 0.758;10k/20k/30k 为 0.793/0.794/0.777 | 六千步进入平台区,继续采数据收益很小 |
| 角色分离 | 0 到 5 kg 腕载 planner RMSE 从 0.049 到 0.052 rad;IDM 适应把一致性差距降约 54%,末端误差降约 24% | 意图端基本不变,执行端才是域偏移的主要作用点 |
这些消融彼此咬合。首动作监督保证训练与部署不脱节;planner-through-IDM 保证未来预测是可行动的;LoRA 保证少量目标数据只学低维修正;6000 步预算则把整个流程压进真机可接受的时间。作者还在 1024 并行环境下的 IsaacSim-to-IsaacSim 域偏移中验证增益,避免把结论归因于两个仿真器的实现差异。
局限性
作者明确列出三点。第一,FADA 依赖非平凡的零样本性能:如果源训练策略在目标域立刻灾难性失败,就无法采集有用的观测-动作配对,需要恢复控制器或辅助采集。第二,IDM 虽然语义上是执行模块,但仍在特定任务分布内训练,可能保留任务相关结构;一个更任务无关的执行模型有待研究。第三,当前适应只用本体感知和已执行动作,不显式建模地形几何或载荷分布;当主要偏移来自外感受时,这个设计可能不够。
我的独立判断是还有一个工程边界:6000 步平台区针对实验中的坡面、负载、拉力和软地变化成立,但不能外推为“任何动态系统都两分钟收敛”。如果部署初期频繁摔倒,采集分布会被截断;如果域偏移表现为高频接触时序变化,50 Hz 本体感知窗口也许要重新设计。论文的 LoRA 证据很稳,但稳定性边界必须按任务逐个测。
总结与展望
FADA 的价值不在单点指标,而在一个可维护的控制架构:意图生成与执行实现分离,域偏移只更新执行端。它证明了目标域普通执行数据本身就是监督,只要训练契约与部署接口一致,两分钟就足够完成一次低秩动力学对齐。对开发者来说,这比“再随机化一些参数”更主动,也比“重训全策略”安全得多。
后续方向可以沿三个层次展开:把 IDM 接口做成跨任务共享的执行模块;在外感受或世界模型表征中扩展适应信号;把恢复控制器、安全采集和 LoRA 微调纳入同一条在线流程。若这些能够闭环,人形部署会从一次性迁移走向持续运行中的例行校准。
许多人形迁移失败不是机器听错了任务,而是旧动作表在新物理里失效;FADA 只重写动作表,两分钟就够。



