Thinker-WM:面向具身智能的共享多模态骨干统一世界模型
0. 简介
Thinker-WM 是 UBTECH Thinker Team 的具身世界模型,要处理的是操作机器人动手之前无法预演后果这件事:此前多数世界模型只预测下一帧画面,动作与场景几何被留在生成过程之外,靠下游模块事后反推。它把 RGB 视频、度量深度和机器人动作各自用专属编解码器翻译进同一套中间表示,交给共享的 Unified Dynamics Transformer 用一组权重联合推演,再靠把条件模态的 flow time 置零这一手段切出六种功能。证据上,EWMBench 综合分 4.66、WorldOlympiad 机器人子榜 0.740、WorldArena 12 项协议 71.73 三处综合排名第一,给入真实动作后 EWMBench 升到 5.03。下面结合论文与官方推理仓库,拆解共享发生在哪一层、六个模式怎样共用骨干、以及这些数字各自能证明什么。

1. 研究问题与现有方法的缺口
1.1 先生成再反推留下的那条接缝
具身智能这条线上,"世界模型"这四个字被用得很松。早期 World Models、PlaNet、Dreamer 那一支把它理解成一个压缩的潜在模拟器:把观测压进隐空间,用循环网络学状态转移,让策略在模型内部"想象"的 rollout 里训练,从而少和真机交互。这条路线极其高效,代价是隐变量只对训练时见过的那批环境与任务友好,互联网级的视觉先验和开放世界常识进不来,模型在陌生场景里很快就露怯。核心问题在于,这类模型的隐空间是围绕特定任务优化出来的,它没有继承任何外部的视觉知识。
后来的路线把世界模型推向大规模生成模型,GAIA-1 从车队数据里学生成式驾驶场景,Genie 从海量视频里学可控的潜在接口,UniSim 把图像、机器人、导航数据混在一起做通用模拟器,Cosmos 把预训练生成模型直接定位成可复用的世界基础模型。这一支继承了强大的视觉与时间先验,但动作接口往往是间接的:动作被表达成潜在控制量、自然语言指令,或者干脆先由视频生成器产出未来,再由一个独立的逆动力学模型反推动作。这条流水线写成两段公式就是先 x ^ t + 1 : t + H = g ψ ( x t , c ) \hat{x}_{t+1:t+H}=g_\psi(x_t,c) x^t+1:t+H=gψ(xt,c)、再 a t = h ϕ ( x ^ t + 1 : t + H , x t ) a_t=h_\phi(\hat{x}_{t+1:t+H},x_t) at=hϕ(x^t+1:t+H,xt),两段之间那条接缝意味着视频模型从没学过"动作会怎样改变世界",它只学过"什么样的画面看起来合理"。
1.2 三类路线的缺口各自在哪
把现有工作按耦合位置分三类,缺口就清楚了。第一类是多专家或分流路线,Motus 用 Mixture-of-Transformers 把视觉语言理解、视频生成、逆动力学、策略学习各挂一个专家,MotuBrain 用三流架构配数据金字塔;这类做法的耦合发生在系统层,专家之间靠接口传张量。第二类是共享 Transformer 但按通道分离,UWM 让图像与动作共享一个 transformer、用不同噪声配置表达不同条件分布,Diffusion Forcing 用独立噪声水平支持多条件分布;这类耦合发生在注意力层,但图像与动作始终是两条独立的扩散通道。第三类把几何请进来,GeoSem-WAM 加几何与语义未来预测,WAM4D 用轻量空间寄存器 token 由未来深度监督,DreamZero 在图像到视频扩散骨干上联合去噪视觉轨迹与动作。
三类都在往"更多信号进同一个网络"走,但信号之间大多靠接口、条件机制或模态专属参数化连接,没有真正在同一种表示里共同演化。这篇工作的判断因此很直接:多模态统一应该发生在表示层,而不是接口层。这里的关键是,接口层的统一只保证张量能传过去,表示层的统一才能让"动作导致几何变化、几何变化约束下一步动作"这条链被同一组参数同时惩罚。
2. 整体框架:三条生成通道,一个共享骨干
2.1 输入输出接口与共享时间窗
模型的初始化来自 Wan2.2 TI2V-5B 视频生成骨干,视觉部分直接继承它预训练好的 patch embedding、调制层和位置几何,连注意力块都直接拿来用;深度与动作是新增通道,需要从零初始化。语言侧用一个冻结的 Qwen3-VL-2B 提供任务级理解,它不参与生成,只作为结构化条件注入。这三类权重处理方式不同是刻意的:视觉先验值钱要保住,几何与动作在预训练模型里根本没有对应物只能新起,语言理解已经在 Qwen 里训得很好、冻住它就不会被机器人数据把语义能力拽坏。
给定观测 o t o_t ot 与任务条件 c c c,模型建模的不是三个边缘分布,而是三模态在同一条时间轴上的联合分布。这个区别决定了损失的形状:如果把三个模态拆开各自建模,网络只是在同一份数据上跑三个互不干涉的任务;联合分布则要求任何一路的预测误差都要在另外两路的上下文里被惩罚,耦合是写进目标函数里的:
p ( v t + 1 : t + H , d t + 1 : t + H , a t + 1 : t + H ∣ o t , c ) p\left(v_{t+1:t+H},\,d_{t+1:t+H},\,a_{t+1:t+H}\mid o_t,\,c\right) p(vt+1:t+H,dt+1:t+H,at+1:t+H∣ot,c)
其中
v
v
v、
d
d
d、
a
a
a 分别是 RGB 视频、度量深度与机器人动作,
H
H
H 是三模态共享的同一个时间窗。这里要厘清的是,共享时间窗与"三个模型并排跑"的分界线正在于此:并排跑的三个模型可以在各自的时间尺度上优化,也可以各自挑最舒服的损失权重,代价是它们永远学不到三者之间的因果链;共享时间窗把三者的预测误差绑在同一条时间轴上一并惩罚,耦合于是变成结构性的,而不是事后用接口拼出来的。

图 2:四路输入经专属编码器变成规模不同的 token 序列,落进同一条时间窗由共享 UDT 联合推演,再各自解码回视频、深度与动作。
| 组件 | 层数 | 权重来源 | 作用 |
|---|---|---|---|
| 视觉编码器 E v , d \mathcal{E}_{v,d} Ev,d | 8 blocks | 继承 | 编码 RGB 与几何 token |
| RGB UDT U \mathcal{U} U | 14 blocks | 继承 | 建模外观与交互 |
| 物理保真 UDT U \mathcal{U} U | 14 blocks | 继承 | 建模几何与交互 |
| 视觉解码器 D v , d \mathcal{D}_{v,d} Dv,d | 8 blocks | 继承 | 解码 RGB 与几何输出 |
| 动作编码器 E a \mathcal{E}_a Ea | 8 blocks | 新初始化 | 编码动作 token |
| 动作解码器 D a \mathcal{D}_a Da | 8 blocks | 新初始化 | 解码可执行动作 |
| 理解分支 und | 4 个 MLP block | 新初始化 + Qwen3-VL | 提供任务与规划指导 |
2.2 三个模态各有专属接口,共享只发生在中间

从这张编解码全链路图能读出一处容易被忽略的设计:深度通道并不是"再复制一份视觉分支"这么潦草。仓库配置里有 depth_uni_clone_layers: 14,意味着共享 UDT 的最后 14 层给深度准备了独立的参数副本,视频、动作、语言走原层,深度走克隆层。这个设计在源码里随处可见 depth_model if (name == "depth" and depth_model is not None) else model 这样的分支判断,q/k/v/o、ffn、modulation 全部按段分发。换句话说,共享发生在注意力的交互里,专属性保留在参数的归属上,这两件事被拆开处理了。
进一步看,这个安排还有一层工程含义。如果深度与视频完全共享最后 14 层,那么几何损失的梯度会直接改写视频的投影矩阵;而在预训练阶段深度大量来自伪标签时,这等于用不可靠的标注去修改 Wan 辛苦学来的视觉先验。给深度一份参数副本,既保留了"几何 token 能参与同一套注意力"的耦合,又把它对视频参数的干扰降到了零,代价只是多了 14 层显存。
3. 语言条件:三字段 schema 与冻结 VLM
3.1 三字段 schema 与针对格式的随机扰动
语言在这里的角色很克制。数据集里的指令格式千奇百怪,有的只写"把杯子拿起来",有的写成一段完整描述还带场景交代,还有的是采集标注自动生成的长句。Thinker-WM 把它们统一归一化成三字段结构化 prompt:Task 写任务目标,Scene 写场景,Action 写具体操作意图。固定 schema 的价值在于把"我要做什么"“在什么环境里做”"怎么下手"这三件本来混在一句话里的事拆开,让语言编码器面对一个稳定的语义骨架,而不是每次都要重新猜这句话的哪一部分是重点。
训练时还额外做扰动:合并重复出现的字段、随机打乱三字段顺序、随机丢字段;评测时固定回 Task–Scene–Action 顺序。这套扰动的目的很明确,逼模型依赖语义内容而不是字段位置或"schema 是否完整"这种表面线索。一个没做过这种正则化的模型很容易学到"看到第三个字段才开始干活"的捷径,换个数据源就崩,这类捷径在混合语料上几乎必然出现。
3.2 机器人身份放在条件侧而非生成序列
Qwen3-VL-2B 全程冻结,最后的隐状态被截断到最多 1000 个 token,经一个线性桥接加四个残差 MLP block 投到模型宽度,得到条件序列 h und h_{\texttt{und}} hund。它不进自注意力,只通过交叉注意力影响生成流。这个位置安排很关键:语言是全局条件,整段视频共享同一个任务意图,不该被逐层改写成一个会随画面漂移的隐状态;如果让语言 token 也参与自注意力,它会被视觉与动作的局部信息不断冲刷,几百层之后"用户到底要干什么"这件事可能已经模糊了。
机器人身份也不是靠文本描述的,而是 8 个可学习的 robot token,直接拼接在
h
und
h_{\texttt{und}}
hund 前面构成编码器与解码器的交叉注意力上下文。配置里每个本体都带一个 robot_token_index,用来在这张查找表里定位自己那组 token 的起始偏移。于是同一个"双臂 26 维 A2-D"和"7 维 LIBERO Panda"在模型眼里不是两段不同的文字描述,而是两组可优化的调制向量:
c = [ r 1 : 8 ; h und ] c=\left[\,r_{1:8}\;;\;h_{\texttt{und}}\,\right] c=[r1:8;hund]
用可学习向量而不是字符串"agibot-a2-d",好处是本体身份进入的是一个连续、可优化的表示空间,模型可以自己决定"这台机器人的动作统计特征"该往哪个方向调制注意力。把本体信息放在条件侧则让序列布局对所有本体保持同一套,本体差异退化成一个"往哪个方向调制注意力"的问题,而调制本来就是 Transformer 最擅长的事。
4. 视觉与几何:共享拓扑、分开投影
4.1 3900 个 token 的隐空间契约
RGB 帧和深度图都由冻结的 Wan2.2 VAE 压进同一个隐空间拓扑。在 640×480 分辨率下,49 帧被映射成 13×30×40 的隐网格,再用 kernel ( 1 , 2 , 2 ) (1,2,2) (1,2,2) 的 patchify 得到 13 × 15 × 20 = 3900 13\times15\times20=3900 13×15×20=3900 个 token,每条视觉流各 3900 个。同一套 VAE、同一套时空组织,让 RGB 与深度占据可对齐的隐坐标——第 t t t 帧第 ( h , w ) (h,w) (h,w) 个位置的外观 token 与几何 token 天然落在同一个时空格点上,注意力学起来不需要额外学一套跨模态位置对齐。如果两条流各自训一个 VAE,光是把两个隐空间对齐就够写一整篇论文。
但两条流的输入输出投影是分开的:RGB token 直接投到模型宽度,深度 token 走自己的 patch embedding,再加一个可学习的 stream embedding 把"几何"与"外观"区分开,解码时各自走专属输出投影。共享的是拓扑,分离的是统计特性。直观理解是,RGB 的隐变量服从自然图像分布,深度的隐变量服从几何分布,两者可以直接复用同一套 VAE 的空间组织,但绝不能共用同一个输入投影,否则网络拿到一批无法区分来源的向量,只能靠数值分布去猜。
4.2 深度编解码:解析可逆的对数映射
深度不是原始毫米值直接喂进去的,中间有一层解析可逆的编码。直接把 0.15 到 4 米的数值喂进网络有两个问题:量纲与 RGB 的 [0,1] 差了几个数量级,且近距离的绝对误差和远距离的绝对误差被同等对待,而操作任务恰恰对近处精度最敏感。所以先把米制深度压到 [0,1] 灰度,再展开成三通道让 Wan VAE 直接吃。仓库里这层写得很干净:
# thinkerwm/thinker_wm/depth_codec.py
if mode == "log":
log_near, log_far = math.log(z_near), math.log(z_far)
z_c = z.clamp(z_near, z_far)
# 对数刻度:近距离分辨率高、远距离压缩,贴合机械臂工作区间
v = 1.0 - (torch.log(z_c) - log_near) / (log_far - log_near)
...
invalid_v = 0.0 if invalid_to == "far" else 1.0
v = torch.where(valid, v, torch.full_like(v, invalid_v))
x = v if out_range == "01" else v * 2.0 - 1.0
x = x.unsqueeze(-3).expand(*x.shape[:-2], 3, *x.shape[-2:])
这段把连续深度压进灰度码值,1 - 让近处变亮、远处变暗,符合人的视觉直觉;z.clamp 保证越界值落在区间端点而不是产生 NaN;无效像素统一映射到远端(invalid_to="far"),再乘 2 减 1 落到
[
−
1
,
1
]
[-1,1]
[−1,1] 与 VAE 输入域对齐。默认区间是 depth_z_near: 0.15、depth_z_far: 4.0、mode: log,覆盖桌面操作机器人绝大多数工作距离。把深度展开成三通道不是浪费,这样它可以直接复用 Wan VAE 的视觉编码器、不必为几何单独训一个 VAE,代价只是三通道信息冗余;解码时 decode_to_depth_m 对三通道取均值,因为生成出来的三通道会有轻微差异。
4.3 深度数据的三种来源与四道质量门

数据侧的深度来源分三种:第一人称立体视频用 Fast-FoundationStereo 做双目匹配,真机单目视频用 DepthAnything3 打伪标签,仿真里直接精确渲染。伪标签要过 clip 级质量门:时间一致性、有效深度比例、与可用传感器深度的一致性,不合格的整段丢弃。这套流程决定了后面那个深度消融能有多可信——约 4000 小时的机器人数据带对齐深度,只占全部机器人数据的四成,剩下的六成只能靠视觉与动作学习。这意味着几何监督的覆盖面从一开始就是有边界的,读者读实验部分时要把这个前提放在心上。
5. 统一动作空间:20 维槽位与相对末端位姿
5.1 语义槽位映射与有效性掩码
动作比视觉难统一得多。不同本体有不同的维度、坐标系、控制约定与执行器接口,一个共享生成模型必须先把这些差异在某处抹平。Thinker-WM 选择在模型边界抹平:所有本体映射进一个固定的 U = 20 U=20 U=20 维统一动作空间,语义排布是双臂的末端增量位置、6D 旋转、夹爪状态。形式上,对本体 r r r 的原始动作 a ∈ R d r a\in\mathbb{R}^{d_r} a∈Rdr 定义语义槽位映射 π r : { 1 , … , U } → { 1 , … , d r } ∪ { − 1 } \pi_r:\{1,\ldots,U\}\to\{1,\ldots,d_r\}\cup\{-1\} πr:{1,…,U}→{1,…,dr}∪{−1} 与有效性掩码 m u m_u mu:
a ~ u = { a π r ( u ) , π r ( u ) ≥ 0 0 , π r ( u ) = − 1 m u = { 1 , π r ( u ) ≥ 0 0 , π r ( u ) = − 1 \tilde{a}_u=\begin{cases}a_{\pi_r(u)}, & \pi_r(u)\geq 0\\ 0, & \pi_r(u)=-1\end{cases} \qquad m_u=\begin{cases}1, & \pi_r(u)\geq 0\\ 0, & \pi_r(u)=-1\end{cases} a~u={aπr(u),0,πr(u)≥0πr(u)=−1mu={1,0,πr(u)≥0πr(u)=−1
π r ( u ) = − 1 \pi_r(u)=-1 πr(u)=−1 的维度填零、不加噪、不进损失,这一条很重要,否则零填充会被当成真实目标去学,模型会莫名其妙地学会"某些关节永远不动"。单臂机器人只有左侧 10 维有效时,右侧 10 维如果进损失,模型就被反复教"右手永远是零",这个错误先验会通过共享权重传染给双臂本体。配置里这段是最直观的证据:
# configs/inference_example.yaml
unified_bands:
eef_left_pos: [0, 3] # 左臂末端增量位置(米)
eef_left_rot6: [3, 9] # 左臂末端相对位姿 6D 旋转
eef_left_gripper: [9, 10] # 左夹爪开合 [-1,1]
eef_right_pos: [10, 13] # 右臂
eef_right_rot6: [13, 19]
eef_right_gripper: [19, 20]
robot_names:
agibot-a2-d:
action_dim: 26
# local dim -> 统一空间列号;-1 表示该本体没有这个自由度
unified_dim_map: [0, 1, 2, -1, -1, -1, 9, -1, -1, -1, -1, -1, -1,
10, 11, 12, -1, -1, -1, 19, -1, -1, -1, -1, -1, -1]

图 4:三个不同维度的本体动作如何散入同一条 20 列语义槽位带,无效列填零并被掩码排除在损失之外。
5.2 相对位姿与 6D 旋转参数化
旋转的表示更讲究。所有本体统一成相对末端位姿:位置是相对条件帧的位移 Δ p t = p t − p 0 \Delta p_t=p_t-p_0 Δpt=pt−p0,姿态是相对旋转 R t r e l = R 0 ⊤ R t R_t^{\mathrm{rel}}=R_0^{\top}R_t Rtrel=R0⊤Rt,再用连续的 6D 参数化存。位置用差值、姿态用左乘相对旋转,两者都锚在条件帧上,于是整条轨迹只表达"从这个起点开始怎么动",与场景在世界系里的绝对位置无关。锚定在各自的起始帧上,动作就和全局坐标系解耦了:换场景、换相机位姿、换本体都可以比,同一段"向左平移 5 厘米再闭合夹爪"的轨迹无论机器人站在房间哪个角落都是同一个数值序列。
# thinkerwm/thinker_wm/action_repr.py
def relative_rotation_6d(state_rot, action_rot, repr_name, quat_order="xyzw"):
"""B1/B2 target transform: state absolute 6D + action relative 6D (R_rel = R_s^T * R_i)."""
r_s = repr_to_matrix(state_rot, repr_name, quat_order) # [..., 3, 3]
r_i = repr_to_matrix(action_rot, repr_name, quat_order) # [..., T, 3, 3]
r_rel = r_s.transpose(-1, -2).unsqueeze(-3) @ r_i
return matrix_to_6d(r_s), matrix_to_6d(r_rel)
这段同时返回两样东西:条件帧姿态的绝对 6D,以及动作序列相对它的 6D。前者给模型提供"我现在朝哪个方向"的锚点,后者才是要生成的目标。用 6D 而不是四元数,是因为 rotvec、quat、rot3 三种原始格式都能无损转进转出,而 6D 在回归任务上是连续的——四元数的双覆盖与正负歧义在生成模型里会变成额外噪声,模型可能在两个等价表示之间来回跳,损失永远降不下去。
直觉理解(为什么非要 6D 而不是四元数):把一个旋转想成一扇门上的把手位置。四元数给它两个互为镜像的答案,物理上是同一扇门,但数值上相隔很远,回归模型看到两个"正确答案"会晕。6D 表示把旋转矩阵的前两列摊平,同一个姿态只有一个值,梯度就不会被这份二义性吃掉。
5.3 时间对齐与动作 token 压缩
时间上,视觉与动作固定 6:1 对应:48 帧视频对应 288 步动作,一个 kernel 和 stride 都为 6 的 Conv3d 把动作序列压成 48 个宽 3072 的 token,解码器再把每个 token 展开回 6 × 20 6\times20 6×20 的动作值。这样动作 token 与视觉隐序列共享同一个时间跨度,同时体积足够小,能被塞进同一个注意力里跑。如果不压缩,3900 个视觉 token 旁边再挂 288 个动作 token,注意力矩阵会被拉长,而动作那部分的时间分辨率远高于视频,意味着大量 token 描述的是同一帧画面内部的细微变化,对建模"世界怎么变"几乎没有增量信息。
动作归一化也放在模型边界,且按本体分别做:action_norm_policy: gripper_hand_minmax 把夹爪与灵巧手维度缩到
[
−
1
,
1
]
[-1,1]
[−1,1],其余维度保留物理单位。这样做的好处是不同本体的统计差异不会污染共享表示,平移量的米与旋转的弧度本来就该按物理意义处理,不该被粗暴统一到某个区间里丢掉量纲。代价是 action_stats.json 这类每本体统计文件成了部署的必需品,换一台机器人就得配一份新统计,这份文件缺失或错配会静默地毁掉输出。
6. 共享动力学 Transformer:有向注意力
6.1 预训练单向、后训练双向
共享骨干最容易犯的错,是让所有模态在每一层都对称地互相看。Thinker-WM 没这么干。预训练阶段 RGB 与动作构成主生成路径,二者通过自注意力互看;深度是单向的,读视频和动作但不回写;语言被隔离在自注意力之外,只走交叉注意力。这套安排不是工程上的图省事,而是有明确的优先级判断:哪些信息现在可信、哪些不可信、哪些根本不该被改写。方向性在这里是一种显式的信任声明,而不是让网络自己去学该看谁——后者在数据质量参差的混合语料上几乎一定学歪。
到了后训练阶段,数据换成有准确深度监督的目标机器人数据,RGB 与动作 token 也被允许读深度,几何因而从单向监督信号变成双向的多模态精修来源。这里值得注意的一个细节是 depth_detach_video_kv 这个开关:它允许在深度读视频时把 K/V 截断梯度,连"梯度回流"这条路也一并堵住,只留下纯前向的信息流。
难点提示(方向性注意力为什么不是随手一写):把它想象成公司里的信息流。实习生可以读所有会议纪要,但他的笔记不能直接改总监的方案。深度在预训练阶段就是那个实习生——它的标注里混着大量伪标签,让它单向读视频、动作没问题,让它回写就等于用不确定的信息去改已经稳定的判断。只有等它转正(有准确深度监督)之后,才允许双向。
6.2 每个 reader 各发一次注意力

…详情请参照古月居
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)