世界-动作模型(World-Action Model)这两年在具身智能和机器人学习圈子里被讨论得越来越多,但真正把"预训练"这件事做透、做成开放模块化架构的工作并不多。OpenWAM 这个方向之所以值得单独拿出来聊,是因为它试图回答一个很实际的问题:当我们想让一个模型同时理解"世界会怎么变"和"我该怎么做"时,到底应该怎么组织数据、怎么切分模块、怎么设计预训练目标,才能让下游任务真正受益,而不是训完一堆权重却不知道怎么用。这篇内容适合正在做机器人策略学习、视频预测、多模态预训练,或者单纯对世界模型感兴趣的朋友,我会从架构拆解、数据组织、预训练目标设计、模块化取舍几个角度,把这类系统化世界-动作模型预训练里最容易踩的坑和最容易忽略的细节讲清楚。
1. 为什么"世界-动作"要放在一起预训练
1.1 单独训世界模型和单独训策略,各自的天花板在哪
先说一个我观察到的现象:很多团队做机器人学习时,习惯把"预测未来"和"决定动作"拆成两个独立模块。世界模型负责根据当前观测和动作预测下一帧观测,策略模型负责根据观测输出动作。听起来分工清晰,但实际跑起来问题不少。
单独训世界模型,最大的问题是它学到的表征往往对"动作"不敏感。举个例子,你用一个视频预测模型去预测机械臂下一帧画面,它可能只学会了"物体在重力下会下落""机械臂会缓慢移动"这类统计规律,但对"如果我施加一个向左的力,物体会怎么变"这种反事实推理几乎没有建模。结果就是,世界模型预测得挺准,但策略模型拿它的隐状态去做决策时,发现这些特征对动作选择没有区分度。
单独训策略模型,问题反过来:样本效率极低。强化学习里动辄几百万步交互,本质上就是因为策略没有"世界会怎么响应我的动作"这个先验。人类学开车的时侯,不需要真的撞一次墙才知道墙不能撞,因为我们脑子里有一个粗略的物理世界模型。策略模型缺的就是这个。
把两者放在一起预训练,核心动机就是让模型在同一个表征空间里同时学到"状态如何演化"和"动作如何影响状态演化"。这样下游微调时,策略网络拿到的特征天然带有动作条件信息,样本效率会明显不一样。
1.2 动作条件预测:世界-动作模型的最小内核
如果只保留一个最核心的机制,那就是动作条件预测(action-conditioned prediction)。形式化地说,给定当前观测 $o_t$、历史隐状态 $h_t$、以及一个候选动作 $a_t$,模型要预测 $o_{t+1}$ 或者它的隐表征 $z_{t+1}$。
这个目标看起来简单,但它逼着模型做三件事:
- 从观测里抽取和动作相关的物理量(位置、速度、接触状态)
- 建立动作到状态变化的映射(动力学)
- 区分"动作导致的改变"和"环境自身演化"(比如背景里飘动的窗帘)
第三点特别容易被忽略。我见过不少实现,模型确实学会了预测下一帧,但仔细看注意力图,它其实在复制上一帧,动作输入几乎没起作用。这种情况在数据里动作幅度小、环境变化大的时候尤其严重。解决办法后面会讲,核心思路是让动作信息必须通过某种瓶颈,不能让它被观测的冗余信息淹没。
1.3 预训练在这里扮演的角色
预训练的价值在于,它让模型在大规模、多样化、无标注或弱标注的数据上先建立"世界怎么运作"的通用先验,然后再用少量目标任务数据微调。对于世界-动作模型,预训练数据可以来自:
- 大规模机器人操作轨迹(有动作标签)
- 人类视频(无动作标签,但可以做动作伪标注或自监督)
- 仿真环境里生成的海量交互数据
- 甚至纯视频预测数据(只训世界模型部分)
OpenWAM 强调"开放模块化",我理解它的意图是:不同来源的数据适合训练不同模块,不同任务需要不同模块组合,所以架构上要允许灵活拼装,而不是一个铁板一块的大模型。
2. OpenWAM 的模块化拆解:哪些部分该分开,哪些必须耦合
2.1 编码器、动力学、解码器的三段式划分
一个典型的世界-动作模型可以拆成三段:
| 模块 | 输入 | 输出 | 主要职责 |
|---|---|---|---|
| 观测编码器 | 原始观测(图像/点云/状态向量) | 隐表征 $z_t$ | 压缩感知信息,保留动力学相关量 |
| 动力学模块 | $z_t$ + 动作 $a_t$ | 下一隐状态 $z_{t+1}$ | 建模状态转移 |
| 解码器 | $z_{t+1}$ | 重建观测或预测 | 提供训练信号,约束表征 |
这个划分的好处是每个模块可以独立替换。比如编码器可以用 ResNet 预训练权重初始化,也可以用 ViT;动力学模块可以用 RNN、Transformer 或者状态空间模型;解码器可以重建像素,也可以只预测关键点。
但这里有个关键取舍:编码器和动力学模块的耦合程度。如果编码器训得太"好",把观测压成一个和动作无关的紧凑表征,动力学模块就很难从里面提取动作敏感信息。我的经验是,编码器不要训得太充分,或者要在编码器输出上做动作条件的辅助损失,逼它保留动作相关信息。
2.2 动作编码为什么不能简单拼接
很多实现里,动作就是直接和隐状态拼接(concatenate)然后送进动力学网络。这在动作维度低、语义简单的时候能用,但一旦动作空间复杂(比如高维连续控制、多模态动作),简单拼接就不够了。
更合理的做法是给动作单独一个编码器,把它映射到和状态表征同一空间,然后用条件调制(比如 FiLM、cross-attention)的方式注入。这样动作信息不是被"加"进去,而是"调制"状态演化的方式。类比一下:拼接像是把调料直接倒进锅里,调制像是根据调料调整火候和翻炒方式,后者对最终味道的控制更精细。
OpenWAM 的模块化设计里,动作编码器应该是可插拔的。离散动作、连续动作、语言指令形式的动作,都可以有各自的编码器,输出统一维度的动作表征,再接入动力学模块。
2.3 模块间接口设计:维度、频率、时间尺度
模块化最容易翻车的地方是接口。我踩过的坑包括:
- 维度不匹配:编码器输出 256 维,动力学模块期望 512 维,中间加个线性层凑合,结果训练不稳定
- 时间频率不一致:观测 10Hz,动作 50Hz,直接对齐会丢信息
- 时间尺度混淆:有的模块处理单步转移,有的处理多步预测,混在一起梯度传播很乱
建议在架构设计阶段就把接口定死:隐状态维度统一、动作表征维度统一、时间步对齐策略明确(是插值、是下采样、还是用层次化时间结构)。这些看起来是工程细节,但它们直接决定了模块能不能真正独立替换。
3. 预训练目标怎么设计才不白训
3.1 重建损失、对比损失、预测损失的配比
预训练目标通常不是单一的。常见的有:
- 重建损失:从隐状态重建观测,逼编码器保留信息
- 预测损失:预测下一隐状态或下一观测,逼动力学模块学转移
- 对比损失:让相似状态的表征靠近,不同状态远离,提升表征判别性
- 动作条件损失:确保动作输入对预测结果有可测量的影响
配比很关键。我试过的一个失败案例是重建损失权重过大,结果模型把所有容量都用来记像素细节,动力学模块几乎没学到东西。后来把重建损失降下来,加上动作条件损失,预测精度和下游策略性能都上来了。
一个可参考的起步配比是:预测损失为主(权重 1.0),重建损失为辅(0.1-0.3),对比损失按需加(0.1 左右),动作条件损失作为正则(0.1-0.5)。具体数值要看数据特性,但原则是不要让辅助损失压过主任务。
3.2 动作条件损失:怎么验证动作真的被用上了
这是我特别想强调的一点。验证动作是否被模型真正利用,不能只看总损失下降。几个实用手段:
- 动作置换测试:把 batch 里的动作随机打乱,看预测损失上升多少。上升明显说明模型依赖动作;几乎不变说明动作没被用上。
- 动作消融:把动作置零或置为均值,看预测变化。变化大说明动作敏感。
- 梯度检查:看动作输入端的梯度范数,太小说明动作对损失影响微弱。
如果发现动作没被用上,常见原因和对策:
| 现象 | 可能原因 | 对策 |
|---|---|---|
| 动作置换后损失几乎不变 | 动作信息被观测冗余淹没 | 增大动作条件损失权重,或对观测编码加信息瓶颈 |
| 动作梯度范数极小 | 动作编码器初始化差或学习率低 | 单独给动作编码器更高学习率 |
| 只在动作幅度大时有效 | 数据里小动作样本不足 | 重采样或数据增强 |
3.3 多步预测与课程学习
单步预测容易训,但学到的动力学短视。多步预测(rollout 多步)能逼模型学长期一致性,但训练难度大,容易误差累积。
我的做法是课程学习:先单步,再 2-3 步,逐步加到 5-10 步。每加一步,学习率适当降低,避免早期不稳定。另外,多步预测时可以用teacher forcing 和 free running 混合:一部分序列用真实观测喂入,一部分用模型自己预测的隐状态继续 rollout,这样既稳定又逼近推理时的真实情况。
OpenWAM 如果要做系统化预训练,多步 rollout 能力应该是核心指标之一,因为下游规划任务往往需要模型预测多步之后的后果。
4. 数据组织:预训练数据从哪来、怎么混
4.1 机器人轨迹、人类视频、仿真数据的取舍
三类数据各有优劣:
- 机器人轨迹:有真实动作标签,和下游任务分布最接近,但量少、场景窄、采集贵
- 人类视频:量大、场景丰富,但没有动作标签,需要伪标注或自监督
- 仿真数据:量无限、标签完美,但存在 sim-to-real 差距
预训练时的混合策略,我倾向于以机器人轨迹为锚,人类视频扩场景,仿真数据补多样性。具体比例看下游任务:如果下游是桌面操作,机器人轨迹占比可以高些;如果下游场景开放,人类视频和仿真数据要加权重。
人类视频的动作伪标注是个技术活。简单做法是用光流或关键点轨迹作为动作代理,但噪声大。更精细的做法是训练一个逆动力学模型,从相邻帧推断动作,再用这个伪动作做预训练。逆动力学模型本身可以用有动作标签的机器人数据训。
4.2 数据配比与采样策略
预训练数据配比不是拍脑袋定的。我一般会做小规模消融:固定模型和训练步数,只改配比,看下游微调后的性能。虽然费算力,但比盲目训一个大模型再发现配比错了要划算。
采样策略上,有几个实用技巧:
- 按任务难度加权:动力学复杂的片段多采
- 按动作多样性加权:动作分布均匀的片段优先
- 去重:相似片段太多会让模型过拟合到特定模式
- 时间窗口采样:不要总是从头开始,随机截取中间片段能增加状态多样性
4.3 数据质量比数量更重要
这一点我在多个项目里反复验证过。一万条高质量、动作标注准确、场景多样的轨迹,往往比十万条噪声大、动作标签错位的轨迹训出来的模型更好。预训练阶段的数据清洗和验证,值得花总时间的 30% 以上。
具体要检查的:
- 动作标签和观测是否时间对齐
- 观测是否有丢帧、模糊、曝光异常
- 动作是否在合理范围内(异常值要处理)
- 场景是否过于单一(多样性检查)
5. 模块化带来的工程挑战与应对
5.1 模块独立训练与联合微调的冲突
模块化设计的一个诱惑是"每个模块单独训好再拼起来"。但实际做下来,单独训好的模块拼在一起往往不 work,因为每个模块的最优表征空间不一致。
我的经验是:预训练阶段可以分模块训,但一定要有一个联合微调阶段,让模块间的接口对齐。联合微调时学习率要小,避免破坏预训练学到的先验。可以分层设置学习率:编码器最小,动力学模块中等,新加的任务头最大。
5.2 版本管理与可复现性
模块化系统里,模块版本组合爆炸。今天用编码器 v1 + 动力学 v2,明天换编码器 v3,结果性能变了,你都不知道是哪个模块的锅。
建议:
- 每个模块独立版本号,记录训练数据、超参、commit hash
- 组合配置用配置文件管理,不要硬编码
- 关键实验做完整记录,包括随机种子
- 定期做回归测试,确保新模块不破坏已有组合
这些是工程规范,但模块化系统不做这些,很快就会变成一团乱麻。
5.3 推理时的模块调度与延迟
模块化在训练时灵活,推理时可能带来延迟。如果每个模块是独立网络,前向传播的串行开销不可忽略。对于实时控制任务,延迟是硬指标。
应对方式:
- 能合并的模块在推理时合并(比如编码器和动力学模块融合)
- 用蒸馏把大模块压小
- 对延迟敏感的场景,提前编译或量化
- 模块调度异步化,预测和控制解耦
6. 下游任务适配:预训练权重怎么用才不浪费
6.1 冻结、微调、还是加适配器
拿到预训练权重后,下游适配有三种主流方式:
- 冻结主干,只训任务头:适合下游数据极少的情况,但性能上限低
- 全量微调:性能上限高,但需要较多数据和算力,且容易过拟合
- 适配器/低秩微调:折中方案,只训少量参数,保留预训练先验
我的建议是先用冻结+任务头跑 baseline,再试适配器,最后如果数据够再全量微调。不要一上来就全量微调,那样预训练的价值可能被覆盖掉。
6.2 表征质量评估:线性探测与少样本微调
评估预训练表征质量,线性探测(linear probe)是快速手段:冻结主干,只训一个线性分类器或回归器,看性能。如果线性探测就很差,说明表征本身不行,微调也难救。
少样本微调更能反映实际使用场景:用 10%、1% 甚至更少的下游数据微调,看性能下降幅度。下降慢说明预训练先验强。
6.3 从预训练到规划的衔接
世界-动作模型的一个高级用法是做基于模型的规划(model-based planning):用模型预测不同动作序列的后果,选最优的。这要求模型不仅能预测,还要能给出不确定性估计,否则规划会被错误预测带偏。
预训练阶段如果能加入不确定性建模(比如用集成、dropout、或者显式的概率输出),下游规划会稳很多。这一点在 OpenWAM 这类系统化框架里应该作为一等公民考虑,而不是事后补。
7. 我踩过的几个典型坑与排查思路
7.1 损失下降但下游不涨
这是最让人抓狂的情况。预训练损失曲线很漂亮,下游微调却不如随机初始化。排查链路:
- 先确认下游任务和预训练任务是否真的相关。如果预训练全是视频预测,下游是力控装配,表征可能不匹配。
- 检查表征是否坍缩。用 t-SNE 或 PCA 看隐状态分布,如果所有状态挤在一起,说明表征没区分度。
- 检查动作条件是否失效(用 3.2 的置换测试)。
- 检查微调学习率是否太大,把预训练先验冲掉了。
我遇到过一次,最后发现是编码器输出做了 LayerNorm,把动作相关的小幅变化归一化掉了。去掉 LayerNorm 或改成更温和的归一化就好了。
7.2 多步 rollout 发散
多步预测训着训着误差爆炸。原因通常是误差累积 + 训练和推理不一致。对策:
- 课程学习,逐步增加 rollout 步数
- 混合 teacher forcing
- 加不确定性惩罚,让模型在不确定时不要过度自信
- 检查隐状态是否有数值不稳定(梯度爆炸、激活饱和)
7.3 模块替换后性能骤降
换了一个"更好"的编码器,结果整体性能下降。这往往不是新模块差,而是接口不匹配。检查:
- 新模块输出分布是否和旧模块一致(均值、方差)
- 是否需要重新校准下游模块的输入归一化
- 联合微调是否充分
模块化系统的"即插即用"是有条件的,接口对齐和联合微调不能省。
8. 一些实操建议与后续可扩展方向
如果你打算动手做类似 OpenWAM 的系统化预训练,我的建议是:
- 先搭最小闭环:编码器 + 动力学 + 解码器,单步预测,小数据,先跑通
- 再加动作条件:验证动作真的被用上,再扩数据
- 再做多步和课程:逐步增加难度
- 最后做模块化和大规模预训练:前面不稳,后面白搭
后续可扩展的方向,我个人比较看好几个:一是把语言指令作为动作的一种形式纳入统一框架,让模型同时理解"做什么"和"怎么做";二是引入层次化时间结构,让模型在不同时间尺度上做预测和规划;三是把不确定性建模做扎实,支撑更可靠的基于模型的决策。
这个领域变化很快,很多细节还在演进。但核心逻辑我觉得不会变:让模型在统一表征空间里同时理解世界演化和动作影响,用模块化换取灵活性和可扩展性,用预训练换取样本效率和泛化能力。把这三点做扎实,比追任何单个 SOTA 指标都重要。