CVPR 2026 的 HiF-VLA(项目页 / 代码),西湖 + 浙大 + 港科广 + 南大那拨人做的。架构上是 OpenVLA 之上挂两件事:往前用 VLM 直接预测未来 motion vectors,往后用一组历史 motion vectors 经 AdaLN 调制动作流。LIBERO-Long multi-view 刷到 96.4%,比堆 4 帧历史的方案显存少 1/2、延迟少 2/3。
整篇里最有意思的是表征选择,不是 benchmark 数字:MPEG-4 / H.264 编码视频时本来就要算 16×16 macroblock 的帧间位移(motion vectors),是 codec 的副产物。HiF-VLA 直接拿这个东西当时间表征,绕开了堆历史帧爆显存、和在线跑 optical flow 拖延迟两件事。
下面按 motivation → 表征 → 网络(结合 motion_layers/motion_tokenizer.py 真实代码)→ loss → 实验数字 → ablation → caveat 的顺序过一遍。
一、问题:VLA 的 temporal myopia
主流 VLA——OpenVLA、π0、RDT、CogACT——动作头几乎都隐式假设马尔可夫性:输入只有当前观测 o_t 和指令 l,输出 action chunk a_{t:t+n}。短程任务无所谓,长程组合任务(LIBERO-Long 里 10 步 pick-place、CALVIN ABC→D 里 5 条指令串起来)就开始出问题:
- 抓取过程中视角微抖,模型分不清「我已经抓到了正在抬」和「我没抓到要重抓」
- 推、按、盖这类带连续动量的子动作,单帧分不出动作方向
- 多视角下,wrist 相机被夹爪挡住的几帧,全靠时间上下文兜底
把历史帧 stack 起来当然能解决,OpenVLA-OFT 一类就这么干。但代价直接体现在 paper Table 3 上:history-stacking 把 peak GPU 从 30.8GB 干到 63.6GB(×2.06),latency 从 72.9ms 干到 229.5ms(×3.15),SR 反而从 91.0 掉到 90.4。原因不复杂——堆进去的大部分像素和当前帧高度冗余,注意力被静态背景稀释,反而损害了 vision-language 对齐。
另一条路是显式建 world model,预测未来像素帧(SuSIE、CLOVER、VPP 这一族),但要在 robot loop 里实时跑 latent video diffusion,成本压不下来。
HiF-VLA 的判断是:时间维度上真正重要的信息只是「哪里在动、往哪动」,像素冗余在表征阶段就应该被丢掉。
二、为什么选 codec motion vectors
H.264 / MPEG-4 Part 2 在编码视频时,每个 16×16 macroblock 都要做帧间预测,存一个 (Δx, Δy) 块级位移。这套东西在 codec 内部叫 motion vectors,原本是为了压缩率而存在——参考块加位移加残差,就能重建当前块。
HiF-VLA 直接拿这些 codec 副产品当时间表征,每帧拿到一个 (H/16) × (W/16) × 2 的张量。和 optical flow 比有几个好处:
| optical flow (RAFT) | codec MV | |
|---|---|---|
| 计算 | 每帧 ~100ms 级 | codec 已经算好,几乎零成本 |
| 分辨率 | 像素级(噪声大) | 块级(自带空间池化) |
| 数据规模 | 自己跑模型 | 用 ffmpeg 转一次码 |
| 噪声 | 对运动模糊敏感 | 受编码器优化目标过滤 |
代价是 MV 的语义弱于 optical flow,但 paper 在 ablation 里跟 RAFT 对比并不吃亏,对 VLA 任务而言块级精度够用。
抽取流程在 get_save_motion.py 里:先把 RLDS 数据集每条 trajectory 用 ffmpeg 重新编码成 MPEG-4 Part 2,再用 LukasBommes/mv-extractor 把 MV 字段读出来,落盘成 JSON 跟 RLDS 一起读。一次性预处理 + 落盘,训练和 inference 都不再付提取开销——这是延迟数字能控制住的根本原因。
组织方式上,paper 把 MV 按 GOP(Group of Pictures)单元打包:[MV_{t-m:t-m+1}, ..., MV_{t-1:t}, o_t],当前帧作为 keyframe 兜空间一致性,历史 m 帧只保留 MV,不保留像素。和 SVD / video diffusion 那种「全像素历史」的世界模型路线方向相反。
三、Hindsight Encoder:代码层面长什么样
paper Section 6.1 说 Hindsight Encoder 是 4 层 ViT、3D conv 切 patch、加 CLS token。去 motion_layers/motion_tokenizer.py 里翻 HisMotionEncoder 类,能看到具体维度:
| |
几个细节:
hidden_dim=1024直接对齐 Joint Expert 的 embedding dim,省一次额外投影。- Conv3D 第一层用 stride=2 把时空各降一半——原始 GOP 是
h × (H/16) × (W/16) × 2,conv 后变成(h/2) × (H/32) × (W/32) × 1024,token 数压到几十量级。延迟没炸的关键工程细节在这。 - 空间和时间位置编码分开 broadcast 再相加,比 1D 拉平 + 单一 PE 更尊重 MV 的时空结构。
- CLS token 最后接
fc_out出一个全局向量。这里 release 代码默认走 CLS pooling 给单 token;paper 主文写的是多 tokenM_h ∈ R^{K_h × d}。代码和 paper 描述有轻微出入,要复现的话以 paper 为准,把fc_out那一层 bypass、直接取 transformer 的全 token 序列。
整个 hindsight 路径相对 7B 的 Prismatic VLM 参数量可忽略,但它通过 AdaLN 调制 6 层 Joint Expert 的两个流——后面会展开。
四、Foresight + Joint Expert:为什么用 AdaLN
Foresight 不是另一个模型
看到 “foresight reasoning” 容易联想到 video diffusion 之类的独立模块,HiF-VLA 不是。它直接在 OpenVLA 那个 Prismatic-7B 的 LLM context 里塞 K_f 个可学习的 foresight query token + K_a 个可学习的 action token,VLM 在一次 forward 里同时输出未来 motion 和未来 action 的 latent 表征:
paper 把这个叫 “think-while-acting”——想和做共享一次 LLM forward,时间维度上完全并行。Table 3 里 +Foresight 那一行只比 baseline 慢 13.4%(72.9 → 82.7 ms),是因为这一步没引入额外的自回归推理。
VLM 出口后,M_f 和 A_f 进入 Joint Expert。
Joint Expert:6 层 Transformer + AdaLN 调制
Joint Expert 是 6 层、d=1024 的非因果 Transformer。每层做三件事:
[M_f; A_f]在序列维拼起来,共享 Q/K/V 投影,做一次 cross-stream joint attention,让「未来动作」和「未来场景如何动」互相对齐。- 拆开成两个流,各走一个独立的 FFN——共享 attention 但不共享 FFN,让两个流保持不同的 functional role。
- AdaLN 用 hindsight 向量
h_c生成 per-channel 的γ和β:
这一步是「过去如何影响未来」的入口。
为什么不直接把 hindsight 塞进 VLM input
paper Figure 4 那个 ablation 给了判决:如果把 hindsight tokens 拼到 VLM input 序列前,性能比 expert-conditioned 差。作者的解释是 Prismatic VLM 在 OXE 上预训练的输入分布对应「图像 + 文本」,强行插入 motion tokens 会破坏已经训练好的 vision-language 对齐。
工程上这个判断很关键——大模型微调时,只动 decoder 侧、不污染 encoder 侧输入,几乎永远是更稳的选择。AdaLN 把 hindsight 限制在调制信号的角色,作用域只在 Joint Expert 内,VLM 主干完全没感知到 motion 的存在,pretrain 能力得以保留。
RoPE 而不是绝对 PE
Joint Expert 用 RoPE 是合理的——K_f + K_a 这个序列里没有「绝对位置」概念,但相对位置(第几步 foresight 配对第几步 action)很重要。RoPE 在外推和相对编码上比绝对 PE 干净。
五、训练目标
最终 loss 就两项:
和 都是 L1,分别是 n=8 步 action chunk 和 n=8 步 future motion 的 token-wise L1。
λ=0.01 看着很小,但 ablation Table 5 给了完整 sweep:0.1→94.4,0.05→95.2,0.01→96.4,0.001→95.6。
- λ 太大(0.1):模型被迫优先拟合 motion,action chunk 拟合质量退化
- λ 太小(0.001):foresight 头退化成噪声预测,hindsight 调制信号失去意义
- 0.01 这个甜点位的含义:motion 任务是给 Joint Expert 一个「理解时间动态」的辅助压力,而不是要它真预测准未来 MV
辅助任务用极小权重,在 multitask learning 里其实很常见,paper 把数字 sweep 摊出来省得读者自己猜。
六、实验数字
LIBERO-Long(Table 1)
Third-view 单视角:HiF-VLA 94.4 vs OpenVLA-OFT 91.0 vs MemoryVLA 93.4。MemoryVLA 是已知最强的 memory-augmented baseline,HiF-VLA 提了 1 个点。
Multi-view(+wrist):HiF-VLA 96.4 vs OpenVLA-OFT 94.0 vs UniVLA 90.0 vs Seer 87.7。从单视角到多视角 +2 个点,说明 motion 表征和 wrist 的局部细节互补——wrist 相机视野窄但近距离精,对夹爪附近的动量感知最敏感,正好是 MV 最准的区域。
完整 LIBERO 四子集平均 98.0(Spatial 98.8 / Object 99.4 / Goal 97.4 / Long 96.4),刷掉 OpenVLA-OFT 97.1、MemoryVLA 96.5、UniVLA 95.2、π0 94.2。要提醒:这些 baseline 不在同一超参/同一 fine-tuning 预算下,LIBERO 已经接近饱和,平均数意义有限,真正分胜负的是 Long 子集。
CALVIN ABC→D(Table 2)
Avg sequence length(5 条指令串联,每条满分 1):
- Third-view:HiF-VLA 4.08 vs UniVLA 3.80 vs π0 3.65
- Multi-view:HiF-VLA 4.35 vs VPP 4.33 vs Seer 4.28
Multi-view 这里只领先 VPP 0.02。VPP 是 explicit video prediction 方法,延迟和显存都重得多,HiF-VLA 用一个轻得多的方案打到同档。
per-step SR 衰减 98.5 → 94.1 → 88.1 → 81.4 → 73.1,每步 3–7% 折损,是典型的指令链衰减——HiF-VLA 没彻底解决,但比 OpenVLA-OFT 那档稳。
延迟 / 显存(Table 3)——最值得看的一张表
原表(batch=4, hist=4, third-view):
| Variant | Peak GPU | Latency | SR |
|---|---|---|---|
| Baseline | 30.8 GB | 72.9 ms | 91.0 |
| +Subgoal | 38.2 (1.24×) | 115.9 (1.59×) | 91.8 |
| +Foresight (ours) | 31.8 (1.03×) | 82.7 (1.13×) | 92.2 |
| +History frames | 63.6 (2.06×) | 229.5 (3.15×) | 90.4 |
| +Hindsight (ours) | 31.4 (1.02×) | 117.7 (1.61×) | 92.2 |
| +Hindsight+Foresight | 32.2 (1.05×) | 121.6 (1.67×) | 93.2 |
几个点:
- +History frames:堆 4 帧历史,显存翻倍、延迟 3 倍、SR 还掉了 0.6 个点。「frame stacking 不是答案」最直接的证据。
- +Subgoal vs +Foresight:subgoal 是预测未来 RGB 帧的对照,Foresight 用 MV 替代,延迟从 +59% 降到 +13%,SR 从 +0.8 提到 +1.2。官方主页那个 58.3% 延迟降幅对的就是这两行的对比。
- Hindsight 单独 +61% 延迟:比想象中大。Hindsight Encoder 本身很小,但运行时还是要读 disk 上的 MV + 3D conv 串行,没法和 VLM 完全 overlap。
- Hindsight+Foresight 合起来只 +67%:两个模块的延迟部分重叠,工程实现比较干净。
真实机器人
AgileX Piper + RealSense D435 + wrist USB camera,3 个长程任务,每任务 100 条 demo + 20 trial eval。其中 “Press Buttons in Order” 在 OpenVLA-OFT baseline 上只有 17.4%。按错顺序就是 0 分,这种任务对 temporal reasoning 极度敏感,是 motion-based 方法理论上最该出效果的场景。
七、Ablation 里两个值得说的点
Hindsight 长度 = 8:sweep (hindsight, foresight) 组合:(8,8)→96.4,(8,16)→94.6,(16,16)→95.2。8 帧大约对应 LIBERO 里一个 sub-action 的时间尺度(抓、移、放各 2–3 秒,30FPS 下 8 帧 ≈ 0.27s)。再长的历史,早期运动和当前决策的因果链已经断了。
Joint Expert depth = 6:2 / 4 / 6 / 8 sweep 是 95.2 / 95.6 / 96.4 / 95.2。8 层反而退化。Joint Expert 的作用是把 VLM 里已经 reasoning 好的 latent 翻译成动作,不是再做一次推理。和扩散策略里 denoising network 不用太深的经验一致。
八、paper 没讲透的几个点
MV 对 ego-motion 敏感。Paper limitation 里点了一句 “may be sensitive to noise in highly dynamic scenes”。LIBERO 和 CALVIN 都是桌面、固定相机、单一可动物体的场景,MV 噪声小。换到自动驾驶或者移动机器人这种相机本身在动的场景,codec MV 会把相机自身的 ego-motion 也编码进来,需要额外的 motion compensation。这是把这套方法迁出桌面操作的最大障碍。
依赖 RLDS + ffmpeg 离线预处理。
get_save_motion.py那一步要把整个数据集重新编码一遍存 MV,离线占空间、上线得有相同的 codec pipeline。streaming RL 类的数据用不了。和 optical flow 的区别就在这——RAFT 慢但可以在线算,HiF-VLA 用 MV 就得接受预处理这条 hard 依赖。没和 π0.5、RDT 最新版直接对比。LIBERO 那张表里 π0 用的是早期数字,CALVIN 同样。截稿时点摆在那不能怪作者,但读者得知道 SOTA 比拼应当在同一基线上做。
“think-while-acting” 这个叙事略大。MV 预测确实给 expert 提供了 temporal grounding 信号,但说成 “agent 在思考未来"有点过——本质上是带辅助任务的 action head,reasoning 这个词更多是营销。不影响方法价值,但看 paper 时要把宣传和实质区分开。
代码 release 和 paper 描述对不上。
HisMotionEncoder的fc_out默认走 CLS pooling,paper 主文写的是 multi-tokenM_h ∈ R^{K_h × d}。这种差异在开源 codebase 里很常见,复现时建议先跑通 LIBERO checkpoint 再回头对照 paper 微调结构。
九、和 AD planning 的连接
motion-as-condition 这条线在自动驾驶规划里也成立。nuScenes / nuPlan 这套场景的「时间近视」问题更严重——前后车的相对速度、加速度本身就是决策最重要的输入。但 AD 这边大家更倾向于用结构化的 agent track,而不是 codec MV,因为 ego-motion 那一关绕不过去。
抛开具体表征不谈,HiF-VLA 这套 design 里有两件事对 driving 也有借鉴:一是时间表征的入口放在 action head 的 modulation 端而不是 VLM input 端,避免污染 pretrained encoder;二是 AdaLN 这种 per-layer per-channel 的轻量调制,在「VLM 主干 + 小动作头」这种范式下比 cross-attention 更划算。我自己之前在 Dense Latent Predictive Supervision 那篇里也提过类似的想法,路径不同但方向是一致的。