• 正文
  • 相关推荐
申请入驻 产业图谱

十分钟读论文 | Bridge-WA:预测世界“在哪变、怎么变”,再让机器人出手

14小时前
143
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

转载自公众号:敢敢AUTOHUB

0. 简介

Bridge-WA 面向语言条件下的机器人操作任务,处理的是现有视觉-语言-动作模型只会从当前画面映射到动作、却不显式建模动作之后场景如何变化的矛盾。它没有在部署时生成一整段未来视频,而是先用一个 5B 未来变化教师模型(future-change teacher)学习操作过程中的场景演化,再把这份知识蒸馏成三类紧凑先验——未来令牌、变化图、运动流图,最后通过 WorldBridge 模块把它们注入动作 transformer。

从 VLABench 上 52.8% 的平均成功率、以及 Dobot 真机 Hard 轨道相对 X-VLA 提升 11.1 个百分点这两个结果看,这套方法最值得关注的地方是它在分布外视觉扰动下的鲁棒性。下面结合论文正文与附录实现,重点拆解三类先验从哪里来、怎样注入动作决策、以及为什么困难场景下差距会被进一步拉大。

论文地址:https://arxiv.org/html/2607.02195
项目主页:https://hcplab-sysu.github.io/BRIDGE-WA

1. world-action 先验作用

1.1 世界模型对控制有用的,不是那段逼真视频

先看一个具体冲突。给机器人一句“把黄瓜放进最上层抽屉再关上”,它要做的绝不只是认出黄瓜和抽屉。它得预判:抓取之后哪个物体会跟着移动、拉开抽屉时接触区域落在哪、抽屉又会沿哪个方向滑出。世界模型(world model)本来是补这一环的天然方向——从 Ha 与 Schmidhuber 的 World Models 到 DeepMind 的 Dreamer 系列,思路都是“先想象未来、再决策”。但把这套搬到真实机器人上,麻烦立刻出现:在部署端跑一个几十亿参数的生成式世界模型、每一步再解码出一整帧未来图像,代价高到无法接受。这里的关键是,一段逼真的未来视频里,绝大多数像素是背景、纹理、光照,和控制的关系微乎其微。

1.2 现有路线的三类缺口

把相关工作摊开看,大致分成三类,每一类都有各自的短板。第一类是反应式 VLA,如 RT-2、OpenVLA、π₀,它们直接学“当前观测加指令到动作”的映射,高效但未来后果被弱建模,容易被外观捷径带偏;第二类是完整的 world-action 模型(WAM),把未来状态和动作联合建模(业界综述见 World Action Models 与 From World Models to World Action Models),能力强但训练推理开销大;第三类是密集视频/图像预测,如 Geometry-Enhanced Video World Models 这类工作,问题在于生成的未来常常物理上不自洽,且算力都花在了像素细节上。换句话说,对控制真正有用的“未来”,往往比一帧照片级的画面要小得多,它是一张告诉策略“干预在哪生效、受影响区域怎么动”的结构化变化场。这就是 Bridge-WA 要造 world-action 先验这个新词的动机。

2. 整体框架:训练时学重活,部署时只留轻活

2.1 输入输出接口

Bridge-WA 考虑的是从多视角 RGB、本体感知和语言出发的操作问题,这也是当前主流 VLA 的标准输入配置。在时刻 ,策略观测到的上下文和要输出的动作块定义如下,其中  是  路相机图像, 是本体状态(proprioception), 是语言指令, 是动作块长度。把这几项写清楚,是为了后面能明确区分“策略看到什么”和“世界先验额外提供什么”:

普通的 VLA 直接学  这个从观测到动作的映射,简洁但把未来后果留在了模型外部。Bridge-WA 则先预测一个紧凑的世界先验 ,再把它作为条件送进策略。这里的关键是引入了三个变量——未来令牌 、变化图 、运动流图 ,它们分别回答“结果、在哪变、怎么变”三个问题,把原本隐式的未来后果显式地摆到了策略面前:

其中  是逐视角的空间变化图,取值被归一化到零到一之间; 是图像坐标下的运动流图,最后一维的二维向量编码了每个位置的位移方向。这套设计原则可以一句话概括:用一份“动作充分”(action-sufficient)的世界变化摘要,替代密集的未来图像预测,把算力从像素细节转移到控制相关信号上。

难点提示(为什么不预测整帧未来):可以把它类比成开车并线。老司机并线时脑子里不会渲染出一整幅未来街景,而是只锁定三件事——目标车道(结果)、后视镜里那辆车的位置(哪里会变)、它正在逼近还是远离(朝哪个方向动)。Bridge-WA 给机器人的,正是这三样最省算力、又最贴近决策的信息。

2.2 训练与推理的关键不对称

Bridge-WA 最重要的一个结构设计,是训练和部署时”角色完全不同”。训练阶段,一个冻结的未来变化教师负责定义预测监督空间,离线产出三类监督目标并存成缓存;轻量预测器学着从当前上下文复原这些先验。到了推理阶段,教师模型和离线缓存被整体移除,在线路径上只剩下  和被世界先验条件化的动作 transformer。这意味着策略训练既不用反向传播穿过庞大的教师,也不用反复解码未来视频。这里要厘清的是,正是这种不对称,让 Bridge-WA 稳稳落在”反应式 VLA”和”完整 WAM”之间那块最实用的中间地带。

3. 第一条核心机制:Future Tokens 与 Change Maps

3.1 机制核心思路

三类先验里,Future Tokens 和 Change Maps 承担的是“高层语义与空间定位”的角色。Future Tokens 表示任务最终应到达的结果状态,但它并不要求生成一张清晰的完成图,而是给动作模型一个全局的目标语境(outcome context)。举例来说,“把葡萄放进盘子”这个任务,Future Tokens 编码的是“葡萄应位于目标盘中”这样一类结果信息,而不是像素级画面。Change Maps 则回答“哪里会变”,它把策略的注意力从桌面、背景、光照这些无关区域,收敛到夹爪接触点、抽屉边缘、目标容器和被操作物体上。直观理解是,它相当于在一张嘈杂的画面上,替策略提前圈出了几块“值得看”的区域

3.2 工程价值

这两类先验不是可有可无的装饰。论文在 VLABench-5 上做了消融:以“不加世界令牌”的 46.3% 平均成功率为基线,只加变化图(Change-only)能提升到 48.4%,而只加运动流(Flow-only)反而掉到 45.2%。这意味着,运动信息只有在被结果或空间变化“锚定”之后才有价值——脱离了“去哪”和“在哪变”,单纯的“怎么动”反而成了噪声。这里的关键是,Change Maps 提供了一个稳定的空间支撑,让后续的运动线索有处安放。

3.3 代码透视:三类监督目标的构建

下面这段是从 scripts/precompute_bridge_wa_cache_all.py 抽取的三类先验构建逻辑。它展示了冻结教师如何从一次未来预测里,一次性吐出未来令牌、变化图、运动流三类缓存目标,供后续 policy 训练直接读取。为什么要离线构建?因为这样可以避免 policy 训练时反复调用 5B 教师前向,把计算成本前置到缓存构建阶段,从而让策略训练和普通 VLA 一样高效:

# scripts/precompute_bridge_wa_cache_all.py
def build_change_maps(front_latents: torch.Tensor, future_latents: torch.Tensor) -> torch.Tensor:
    if future_latents.dim() == 5:
        future_latents = future_latents[:, :, 0]
    delta = future_latents.float() - front_latents.float()
    change_map = torch.linalg.vector_norm(delta, dim=1, keepdim=True)
    change_map = change_map / (change_map.amax(dim=(-2, -1), keepdim=True) + 1e-6)
    return change_map

def build_flow_maps(world_teacher, front: torch.Tensor, future_latents: torch.Tensor,
                   flow_workers: int) -> torch.Tensor:
    future_images = _decode_future_images_batch(world_teacher, future_latents)
    target_hw = future_latents.shape[-2:]
    return _compute_optical_flow_maps_batch(front, future_images, target_hw,
                                            flow_workers=flow_workers)

这段代码做了一件事:把教师预测的未来潜变量,压缩成三类和控制强相关的信号。build_change_maps 计算未来与当前潜变量的 L2 范数差异并归一化到 [0,1],定位变化区域;build_flow_maps 先解码出未来图像,再用光流算法给出运动方向。为什么这样设计?因为直接把整帧未来图像交给策略,等于让它自己去大海捞针;而变化图和运动流图等于替策略做完了最耗神的信息提炼。工程细节上,这些函数在训练前离线跑一次,policy 训练时直接读缓存,不再触发教师前向。

4. 第二条核心机制:Motion-Flow Maps

4.1 设计动机

为什么不能只有 Future Tokens 和 Change Maps?因为“哪里会变”还不足以决定动作质量。核心问题在于,对推、拉、插入、打开、放置这类接触密集操作,局部的运动方向往往直接决定成败——同样是拉抽屉,方向偏一点动作就废了。Motion-Flow Maps 用图像坐标下的向量场(flow field)编码这种前瞻性的运动趋势,它在 Change Maps 圈出的区域之上,进一步标注“这块区域接下来应该朝哪个方向动”。

直觉理解(变化图与运动流的分工):如果说 Change Maps 是一张“热力图”,告诉你哪几块地方即将发生事情;那 Motion-Flow Maps 就是叠在热力图上的一组箭头,告诉你每块地方的东西正朝哪个方向挪。前者管注意力,后者管方向感,两者合起来才构成一次完整的“预判”。

4.2 代码透视:光流方向的编码

运动流图的核心,是把当前帧与预测未来帧之间的稠密光流,转成一个带方向的向量场,再归一化到网络可用的分辨率和尺度上。这一步既要保留“动多少”的幅值信息,也要保留“朝哪动”的方向信息,两者在下游各有用途。下面按论文描述还原这一编码逻辑:

# 依据 Bridge-WA 论文对 motion-flow map 的描述还原,非官方源码
def encode_motion_flow(I_current, I_future, grid_hw=(16, 16)):
    flow = optical_flow(I_current, I_future)      # [H, W, 2],逐像素位移
    flow = resize_flow(flow, grid_hw)             # 降采样到 flow 先验分辨率
    magnitude = flow.norm(dim=-1, keepdim=True)   # 位移幅值,用于注意力偏置
    direction = flow / (magnitude + 1e-6)         # 单位方向向量
    return torch.cat([flow, direction], dim=-1)   # 同时保留幅值与方向

这段代码的关键是同时保留了”幅值”和”方向”。为什么?因为后续 WorldBridge 要用它做两件事:方向决定动作朝哪走,幅值决定这块区域在注意力偏置里的权重。工程细节上,运动流图偏好更精细的分辨率——论文的分辨率扫描显示,Flow Maps 从 2×2 的 45.2% 提升到 16×16 的 49.0%,所以这里默认用了 16×16 的网格。

4.3 三类先验的非对称容量分配

一个容易忽略的亮点是三类先验的”非对称容量分配”。论文的分辨率扫描给出一个反直觉结论:并不是所有先验都越精细越好。Future Tokens 作为全局摘要,在 1×1 时最好(46.8% SR / 60.2% PS),放大到 4×4 反而掉到 43.4% SR;Change Maps 在中等的 8×8 达到峰值(49.4% SR);只有 Flow Maps 需要高分辨率(16×16 最佳)。这意味着,Bridge-WA 给三类先验分别配了紧凑、中等、精细三档分辨率,而不是一刀切。

5. 训练时的监督模块:5B World Teacher

5.1 教师模型的设计取舍

Bridge-WA 的教师  不是一个现成的文生视频模型,而是基于 Wan2.2-TI2V-5B 生成式骨干、受机器人状态条件约束的“未来变化教师”。为什么用它、而不是通用视频模型?因为通用模型的预测目标和“操作引起的场景变化”不对齐。这里的关键是训练分两步走:教师先在真实机器人数据集 BridgeData V2 上预训练,学习由动作引起的未来观测结构;再在目标基准或真机数据上后训练微调,让预测和下游本体、相机布局、任务分布对齐。为什么单帧监督而不是整段视频?因为策略需要的是固定时序偏移处的未来结构,而非逐帧的视频流。工程细节上,后训练只更新 5B 的 DiT 主干,Wan VAE 与文本编码器保持冻结。

5.2 离线缓存的构建

教师微调完成后被整体冻结,此后只承担一个职责:对下游数据集逐样本跑一遍,把三类先验离线写进缓存。这样 policy 训练时就不必再触发任何教师前向。下面的伪代码概括了 scripts/precompute_bridge_wa_cache_all.py 的主循环逻辑,重点看它存了哪些字段、为什么这么存:

# scripts/precompute_bridge_wa_cache_all.py 主循环(简化)
cache = {}
for sample_key, batch in dataloader:
    front_latents = encode_current(batch)
    future_latents = world_teacher.predict_future(batch, delta=30)

    future_tokens = pool_future(future_latents)
    change_map = build_change_maps(front_latents, future_latents)
    flow_map = build_flow_maps(world_teacher, batch["images"], future_latents,
                               flow_workers=args.flow_workers)

    cache[sample_key] = {
        "future_tokens": future_tokens.half(),  # 半精度存储
        "change_map": change_map.half(),
        "flow_map": flow_map.half(),
        "meta": {"delta": 30, "camera_order": batch["camera_order"]},
    }
    save_cache(cache, cache_dir)

这段代码的设计取舍值得展开。为什么要存半精度、还要存 meta?前者是为了压缩几十万样本的缓存体积、减轻数据加载压力;后者是为了让缓存条目能和 policy 训练时的输入严格对齐。这意味着世界先验监督在整个 policy 训练过程中是确定性的、可复现的——每次训练读到的目标完全一致,不会因为教师随机采样而漂移。

6. 推理时的执行模块:WorldBridge

6.1 训练 forward:先验如何被注入

WorldBridge 把三类先验转成动作模型可读的条件。它走两条路:一是把先验投影成额外的键/值记忆(memory key/value),供策略查询读取;二是把变化图和运动流图转成加性注意力偏置(additive attention bias),温和地引导注意力。下面是从 models/modeling_bridge_wa.py 抽取的 BridgeWAAttention.forward 核心逻辑,可以看到这两条路是如何在一层注意力里同时发生的:

# models/modeling_bridge_wa.py: BridgeWAAttention.forward (simplified)
def forward(self, x, future_tokens=None, change_tokens=None, flow_tokens=None,
           change_token_bias=None, flow_token_bias=None):
    q = self._reshape(self.q(x))
    k_self, v_self = self.kv_self(x).chunk(2, dim=-1)

    k_chunks = [self._reshape(k_self)]
    v_chunks = [self._reshape(v_self)]
    bias_chunks = [x.new_zeros((x.shape[0], x.shape[1]))]

    if future_tokens is not None and future_tokens.numel() > 0:
        future = self._apply_gate(future_tokens, self.future_gate)
        k_chunks.append(self._reshape(self.k_future(future)))
        v_chunks.append(self._reshape(self.v_future(future)))
        bias_chunks.append(x.new_zeros((x.shape[0], future.shape[1])))

    if change_tokens is not None and change_tokens.numel() > 0:
        change = self._apply_gate(change_tokens, self.change_gate)
        k_chunks.append(self._reshape(self.k_change(change)))
        v_chunks.append(self._reshape(self.v_change(change)))
        bias_chunks.append(self.change_bias_scale * change_token_bias.float()
                          if change_token_bias is not None
                          else x.new_zeros((x.shape[0], change.shape[1])))

    if flow_tokens is not None and flow_tokens.numel() > 0:
        flow = self._apply_gate(flow_tokens, self.flow_gate)
        k_chunks.append(self._reshape(self.k_flow(flow)))
        v_chunks.append(self._reshape(self.v_flow(flow)))
        bias_chunks.append(self.flow_bias_scale * flow_token_bias.float()
                          if flow_token_bias is not None
                          else x.new_zeros((x.shape[0], flow.shape[1])))

    k = torch.cat(k_chunks, dim=2)
    v = torch.cat(v_chunks, dim=2)
    attn = (q * self.scale) @ k.transpose(-2, -1)
    attn_bias = torch.cat(bias_chunks, dim=1).to(dtype=attn.dtype, device=attn.device)
    attn = (attn + attn_bias[:, None, None, :]).softmax(dim=-1)
    out = self.attn_drop(attn) @ v
    return self.proj_drop(self.proj(out.transpose(1, 2).reshape(x.shape)))

这段代码做了什么?在每个激活层,策略查询  同时读取标准自注意力和世界先验记忆,并叠加由变化、流图导出的偏置。为什么查询始终以策略为中心?因为这样动作 transformer 自己决定从每个先验源读多强的信息,既保留了自注意力流的完整性,又能温和地被引导向”预期会变、会动”的区域。工程细节上,_apply_gate 让每类先验过一个可学习的门控,change_bias_scale 和 flow_bias_scale 控制偏置强度,未激活的先验直接跳过。

6.2 推理 generate:由粗到细的分层路由

WorldBridge 的注入是分层的,而不是均匀作用在每一层。它按“由粗到细”安排三类先验的作用位置:Future Tokens 在较浅层引入,作为任务级全局结果先验;Change Maps 在中间层注入,把交互落到具体场景区域;Motion-Flow Maps 路由到更接近动作解码的层,因为局部位移方向临近出手时最有用。这个层范围由起始层  和层预算  决定:

其中  是 transformer 深度, 是第  层激活的先验集合。这套排布背后有个朴素道理:先想清楚”要去哪”,再定位”在哪动”,最后才校准”朝哪动”。消融证实了它的价值——仅用注意力偏置的条件化掉到基线以下(44.8%),分层条件化表现最好,达到 50.4%,比无门控条件化的 49.3% 又高出一截。

7. 训练目标:动作模仿加世界先验蒸馏

7.1 损失公式

Bridge-WA 的预测器用回归和余弦对齐两类损失项来蒸馏三类先验,既约束绝对数值的逼近,也约束方向上的对齐。为什么要同时用这两种损失?因为回归项(L1/L2)关注数值误差,余弦对齐项关注向量方向,二者互补才能让预测的先验既"准"又"稳"。先定义余弦距离,其中  是任意两个向量, 是一个防除零的小量(通常取  量级):

三类先验的蒸馏损失把回归项和余弦对齐项加权求和, 是各项权重。未来令牌用 L2 范数衡量回归误差,变化图和运动流用 L1 范数,这是因为后两者是空间分布,L1 对局部异常值更稳健。为什么要区分 L1 和 L2?因为未来令牌是紧凑的全局摘要,平方误差能更强地惩罚离群值;而变化图和运动流是高维空间场,L1 能让优化更关注稠密区域的整体对齐。整个损失可以写成下面这个六项相加的形式:

最终的策略目标,是动作模仿损失加上这份世界先验蒸馏损失,两者联合训练。动作模仿负责拟合人类示范的动作轨迹,世界先验蒸馏负责让预测器学会从当前上下文复原教师给出的未来结构。这两项损失权重相当,既不让先验蒸馏绑架动作分布,也不让动作模仿完全忽略未来信息:

下面这段代码还原了损失权重的装配逻辑,直接对应论文里”六项权重各 0.1”的默认配置。这套配置的含义是,每类先验的回归项和余弦对齐项被等权对待,三类先验之间也是等权。实战中这个配置在多数任务上都表现稳定,不需要逐任务调。为什么能做到如此”一刀切”?因为三类先验本身已经在不同抽象层次上分工明确,它们之间的竞争不如想象中激烈:

# 从论文附录 B.3 默认权重配置提取(代码仓库对应 config/*.yaml)
loss_config = {
    "future_reg": 0.1, "future_cos": 0.1,     # 未来令牌:回归 + 余弦
    "change_reg": 0.1, "change_cos": 0.1,     # 变化图:回归 + 余弦
    "flow_reg":   0.1, "flow_cos":   0.1,     # 运动流:回归 + 余弦
}
L_prior = sum(w * term[k] for k, w in loss_config.items())
L_train = L_action + L_prior                  # 动作模仿 + 世界先验蒸馏

7.2 反直觉的组合现象

这里有个值得注意的组合现象。直觉上会觉得三类先验全加、加得越多越好,但消融给出的答案是否定的。核心问题在于,在一个容量固定的动作 transformer 里,盲目往里塞先验会引入内部竞争。数据能说明问题:Change-only 是 48.4%,Future+Flow 是 48.6%,但把三类简单堆在一起(未分层)的 Future+Change+Flow 只有 46.6%,甚至不如单加一类。这意味着,先验之间不是简单可加的,装配方式比数量更重要——这正是 WorldBridge 要用分层由粗到细路由的根本原因。

8. 部署路径:为什么它几乎和普通 VLA 一样轻

8.1 在线闭环流程

Bridge-WA 的部署闭环可以写得很简单。教师和缓存移除后,在线路径只剩一次紧凑的先验预测( 的一次前向),加上 WorldBridge 里几处注意力投影。这里用一个简化的价值折算形式来帮助理解"先验条件化如何影响长程推进"。可以把动作块在某个时刻的价值,写成从当前到终局的折扣收益, 是折扣因子、 是时序长度、 是任务成败:

这里要厘清的是,Bridge-WA 本身并不依赖显式的价值模型或测试时搜索,上式只是帮助理解“先验条件化如何影响长程推进”的一个视角。真正的在线开销,就是  的一次前向加上动作解码。这意味着,它同时占据了两类方法的优点:比纯 VLA 多了显式的未来变化信息,又比部署式大世界模型省去了在线视频生成

8.2 三类先验在不同任务上的角色切换

三类先验在不同任务上的贡献并不均衡。进一步看真机可视化:在“开抽屉放黄瓜”这类任务里,Change Maps 的高响应峰值集中在夹爪、抽屉边缘和目标物体;而 Flow 方向则清晰地指向抽屉滑出的方向。在纯抓取任务里,Future Tokens 的全局结果语境作用更突出;在推拉类任务里,Motion-Flow Maps 的方向信息占了主导。这说明同一套先验框架,会根据任务性质自动调整三类信息的相对权重。

9. 总结

Bridge-WA 的核心贡献不是再造一个 world-action 名词,而是把“未来建模”拆成 outcome、where、how 三个可蒸馏、可注入的紧凑先验。VLABench 上 52.8% 的平均成功率、Dobot Hard 轨道相对 X-VLA 提升 11.1 个百分点、LIBERO-Plus 上 72.1% 的零样本鲁棒,这三个数据点合起来,足以让这套架构进入下一代轻量 world-action 模型的候选清单。

但先验的短时程本质和缓存构建成本这两个缺口还悬着——前者决定它能不能撑起真正的长程规划,后者决定它能不能在更大数据规模上扩展。等作者把代码和更完整的跨本体评测开源后,再回过头看这套“训练时学重活、部署时只留轻活”的范式,能不能真正落到工业级真实场景。

相关推荐