Kaelem

机器人慢半拍,不一定要训练一个更小的模型

·20 min read
AI论文解读机器人学习VLA推理优化

机器人慢半拍,不一定要训练一个更小的模型


一句话概括:这篇论文提出 ActionCache:不改模型权重、不重新训练、不加预测器,而是在 flow-based VLA 推理时缓存过去成功生成过的中间动作;当视觉、语言和机器人状态足够相似时,模型不再从高斯噪声开始慢慢积分,而是从缓存动作附近继续 refinement。作者在 VLABench 和真实 SO-101 机械臂上验证:对 π0.5,action head 最多从 18.8ms 降到 1.6ms,速度提升 11.75×;对 GR00T-N1.6,最多从 24.1ms 降到 0.7ms,提升 34.43×。但它加速的是 action head,不是完整 VLA;效果依赖缓存质量、命中阈值和任务中是否存在可复用动作阶段。


图 1:VLA 推理的动作头瓶颈

一台机器人接到“把方块放进盒子”的指令,真正慢的地方往往不是它看不懂这句话。

论文给了一个很具体的数字:在代表性的 flow-based VLA 里,action head 占端到端推理延迟的 37% 到 66%。π0 的动作头约占 36%,DreamVLA 超过 65%;作者自己在 RTX 4090 上测的几类模型也落在这个区间。也就是说,视觉语言主干已经把图像和指令编码好了,后面那段“把理解变成一串连续机器人动作”的生成过程,反而成了实时控制的瓶颈。

这个瓶颈有点反直觉。我们习惯把大模型推理慢归因于“模型太大”,于是第一反应是剪枝、量化、蒸馏、压缩视觉 token。但在 flow-based VLA 里,动作不是一次吐出来的。模型先从一团噪声动作开始,再沿着一个速度场一步步积分,把噪声推成平滑的动作 chunk。每多一次 NFE,就多一次 action head 前向。机器人每个控制周期都要这么做,延迟自然会堆起来。

ActionCache 的问题意识很简单:机器人世界里真的每次都要从零想一遍吗?

先把几个概念放到桌面上

Vision-Language-Action model,简称 VLA,可以理解成把“看见什么、听到什么指令、身体该怎么动”接在一起的策略模型。普通语言模型生成的是 token,VLA 生成的是低层控制动作。

Flow-based action head 是这篇论文的关键对象。它不像自回归模型那样一个动作 token 一个动作 token 地吐,而是在连续动作空间里,从噪声出发,通过多步 flow matching 积分得到一段未来动作。好处是动作更平滑,也能表达多种可能轨迹;坏处是每一步 refinement 都要算一次。

NFE 是 number of function evaluations,也就是动作头被调用多少次。π0.5 的 full setting 是 10 步,GR00T-N1.6 是 4 步。NFE 越少,越快;但如果仍从噪声开始,动作质量会明显下降。

Warm start 是“别从零开始”的想法。你可以把它想成写字:如果纸上已经有一条接近正确笔画的淡线,你只要描几下;如果是一张白纸,你就要从头构造。ActionCache 做的事情,就是把过去成功生成过的淡线存起来,在相似场景中拿出来继续描。

方法:不是缓存特征,而是缓存“动作空间里的半成品”

图 2:ActionCache 从过去动作附近开始 refinement

ActionCache 的聪明之处,是它没有试图改 VLA 的内部结构。

在每个控制时刻,VLM backbone 本来就会产生一组输出 embedding,用来给 action head 提供条件。ActionCache 顺手拿这些 embedding,构造一个 compact multimodal key。论文没有训练一个新的 key encoder,而是用固定的 sparse ternary random projection:把高维 embedding 乘上一个只含 -1、0、1 的稀疏随机矩阵,投到 500 维;非零密度设为 0.01。这个矩阵创建一次后固定,不需要拟合数据。

缓存里存的也不是 KV cache、视觉 token 或 action head 的隐藏状态,而是动作 chunk 本身:某个过去成功 episode 中,在 full generation 轨迹里抽出来的中间 noisy action。这样做有两个后果。第一,它更模型无关,因为动作空间比内部表示更稳定;第二,它直接对准瓶颈,因为如果这个中间动作已经靠近当前目标动作,后续只需要 0、1 或 2 步 refinement。

检索流程也很保守。当前 key 和缓存 key 做 cosine similarity,取 Top-1。如果相似度超过命中阈值 Thit,就把对应动作拿出来作为初始动作;如果没超过,就拒绝这个候选,回退到原模型的完整 NFE,从高斯噪声重新生成。论文默认设置里,π0.5 的 Thit 是 0.85,GR00T-N1.6 是 0.65;默认缓存大小 3000 条,动作执行 horizon 设为 10。

这条回退机制很重要。ActionCache 不是声称“缓存一定对”,而是把缓存当作一个有边界的捷径:相似就复用,不相似就让原模型接管。它保留的是 pretrained policy 原本的泛化能力,而不是用一个激进的近邻检索系统替代策略网络。

缓存怎么进入主库也有过滤。论文在 miss 时会把 full generation 过程中 N - Nhit 位置的中间动作放进 pending buffer;只有 episode 成功完成,这些 pending pair 才会提交到主缓存,失败 episode 的轨迹会被丢弃。换句话说,缓存不是“模型做过什么都记”,而是优先记成功行为。

为什么少算几步不等于直接砍 NFE

图 3:命中阈值保护速度和可靠性的边界

最容易混淆的一点是:ActionCache 的加速,不等同于简单把 NFE 从 10 降到 1。

论文的 Table 1 把这个差异说得很清楚。在 VLABench 上,π0.5 full base model 的成功率是 38.8%,action-head latency 是 18.8ms。简单把 base model 降到 NFE=1,延迟降到 2.5ms,速度是 7.52×,但成功率只剩 6.8%,掉了 32 个百分点。

ActionCache 在 Nhit=1 时,延迟是 3.6ms,速度 5.22×,成功率仍有 32.4%,只比 full model 低 6.4 个百分点。Nhit=0 更激进:动作头延迟降到 1.6ms,速度 11.75×,成功率 32.9%,仍只低 5.9 个百分点。这里最关键的对比不是“1.6ms 很快”,而是同样少算甚至不算 refinement,缓存初始化和噪声初始化的动作质量完全不同。

GR00T-N1.6 上的现象类似但更复杂。full base model 成功率 34.0%,延迟 24.1ms。NFE=1 的 base model 还有 24.6% 成功率,延迟 8.5ms。ActionCache 在 Nhit=2 时成功率达到 35.7%,甚至比 full model 高 1.7 个百分点,延迟 13.4ms;Nhit=1 时成功率 29.1%,延迟 7.6ms;Nhit=0 时延迟只有 0.7ms,速度 34.43×,但成功率降到 22.3%。

这组数据说明了一个边界:ActionCache 可以把“从噪声到动作”的长路,替换成“从相似成功动作到当前动作”的短路;但如果完全不 refine,某些模型和任务仍会付出成功率代价。它不是魔法,而是在已有动作冗余足够强时,把冗余转化成延迟收益。

论文还把 key projection 和 cache lookup 的开销单独算进 ActionCache latency。作者强调,在 Nhit=0 时,π0.5 低于 2ms,GR00T-N1.6 低于 1ms,说明这部分开销相对 action head 多步积分很小。

跨任务复用:缓存命中的不是“任务名”,而是动作阶段

ActionCache 更有意思的地方,不是同一个任务里复用上一帧,而是跨 episode、甚至跨 task 复用。

作者做了一个 zero-shot cross-task 实验:先用 VLABench 的 select_fruit 填充缓存,再在 select_painting 和 select_toy 上测试 π0.5,评估时禁用缓存更新,确保所有命中都来自源任务。为了避免二元成功率过于粗糙,他们用 progress score 评价任务进度,并把 Thit 提到 0.925 来保持质量。

结果并不夸张,但很说明问题。select_painting 的 progress score 是 20.0%,base model 是 21.0%,命中率 2.7%;select_toy 是 51.7%,base model 是 50.5%,命中率 8.1%。也就是说,跨任务缓存没有显著伤害原模型进度,同时在一部分阶段确实能命中。Figure 4 进一步显示,episode 初始阶段的 hit rate 最高超过 80%。

这背后的直觉很强:很多机器人任务的开头并不“语义独特”。不管你最后要选水果、选玩具还是选画,早期都可能包含接近物体、移动到可操作区域、调整末端姿态这类共享动作。缓存复用的不是“select_fruit 这个任务”,而是这些不同任务共同拥有的动作片段。

真实机器人实验也支持这个解释。

图 4:真实轨迹里,共享阶段更容易缓存命中

作者在 SO-101 六自由度机械臂上做 pick-and-place。π0.5 用 100 条成功示范和 20 条失败恢复示范 fine-tune 5000 步,global batch size 128,训练用 4 张 H100;评估 100 个 episode,在 RTX 5090 上测 wall-clock latency。完整 base model 成功率 72%,总延迟 106.83ms,其中 action head 60.38ms。ActionCache Nhit=1 时成功率 70%,总延迟 61.76ms,action head 14.90ms;action head 加速 4.05×,端到端加速 1.73×,hit rate 84.6%。

更细的轨迹分析显示:approaching 阶段 hit rate 0.98,placing 阶段 0.88,grasping 阶段降到 0.78。这个变化非常合理。接近和放置有很多可复用的粗动作;抓取需要精细接触、位置误差容忍度低,模型就更少依赖缓存、更多回到计算。ActionCache 的价值恰好在这里:它不是平均地偷懒,而是在“看起来像过去”的阶段省算力,在更难的阶段保守一点。

缓存质量:速度旋钮背后是相似度、容量和淘汰策略

ActionCache 还有一个工程上很现实的结论:缓存不是越多越无脑,命中质量决定成功率。

论文用缓存大小从 50 条到 5000 条做分析,对应约 164KB 到 16.4MB。Figure 5a 显示,Top-1 cosine similarity 足够高时,不同 Nhit 都能接近 full-step success rate;但如果相似度不够,高命中只会把错误动作拿来复用。Thit 因此成了一个关键旋钮:阈值越高,接受的检索质量越高;但命中率可能下降,延迟收益也会变少。

容量也影响命中率。缓存越大,越容易在当前上下文附近找到合适动作,Figure 5c 中 cache size 增大带来更高 hit rate。这里有个有趣的量级感:5000 条 key-action entry 也只是十几 MB 级别。相比一次大模型推理的显存成本,这个外部缓存并不夸张。

淘汰策略也不是小事。在限制缓存大小为 100 的实验里,作者比较 Random、FIFO、LRU、LFU 和 oracle。结果 LFU 在不同 hit threshold 下给出最高 hit rate。论文的解释是,LRU 容易被 one-hit wonder 污染:某些特别具体、难以复用的抓取动作刚发生过,会挤掉更通用的动作;LFU 更倾向保留跨任务、跨 episode 反复出现的动作原语。FIFO 的表现不比随机好,说明“只复用最近动作”的传统 temporal warm start,在 plug-and-play 设置里漏掉了很多远距离但语义相似的机会。

Key 来源也被验证过。Table 3 比较 VLM input embedding 和 VLM output embedding。使用 VLM output 作为 key source,在近似 hit rate 下成功率最高可高出 29.1 个百分点。原因并不神秘:VLM 输出已经融合了视觉和语言,并更接近 action head 真正使用的条件;输入 embedding 还停留在更原始的感知层面。

这篇论文证明了什么,也没有证明什么

论文证明的第一件事,是 flow-based VLA 的 action head 确实是一个可被直接攻击的推理瓶颈。Figure 1 和 Table 1 给出的 37–66%、18.8ms、24.1ms 等数字,说明瓶颈不是抽象存在,而是足以影响实时控制的工程成本。

第二,过去动作中存在可复用计算。否则 ActionCache 不可能在 π0.5 上把 Nhit 降到 0 还保持 32.9% 成功率,也不可能在真实 pick-and-place 里以 84.6% hit rate 把总延迟从 106.83ms 降到 61.76ms。

第三,复用可以跨越相邻时间步。cross-task 实验虽然命中率不高,但在禁用缓存更新的情况下仍能保持 progress score,并在 episode 初始阶段达到超过 80% hit rate,说明“动作阶段相似性”比“任务标签相同”更底层。

但论文没有证明三件事。

第一,它没有证明端到端 VLA 已经被整体加速到同等倍率。最高 11.75× 和 34.43× 都是 action-head acceleration;真实实验里 action head 是 4.05×,但端到端只有 1.73×。VLM backbone、视觉编码、embedding 计算仍然在。

第二,它没有证明所有任务都适合缓存。LIBERO 附录反而给了一个边界:π0.5 baseline 在 LIBERO 上 NFE=1 已经有 89.0% 平均成功率,NFE=10 是 90.0%;ActionCache NFE=1 是 88.0%,NFE=0 是 84.0%。也就是说,对某些简单 benchmark,直接减少 NFE 已经足够,缓存的相对收益没那么大。

第三,它没有解决缓存策略的最优设计。作者只比较了常见 replacement policies,并明确把更接近 oracle 的淘汰策略、超参数优化、以及与 VLM 加速方法结合留给未来工作。

Big Picture:VLA 推理优化可能从“压模型”转向“记行为”

这篇论文真正值得注意的地方,是它把 VLA 推理优化从模型内部拉到了行为层。

过去我们谈机器人大模型加速,通常想到的是减少 token、压缩层、剪枝、量化,或者训练一个更便宜的 head。ActionCache 的路径不同:它承认原模型已经会做,只是每次都从噪声开始太浪费。于是它把成功行为当作外部记忆,把“生成动作”部分改写成“检索一个相似动作,再小幅修正”。

这对机器人尤其自然。语言任务的上下文变化很大,但家庭、工厂、实验台里的机器人动作有大量重复结构:接近、对齐、伸手、避障、放置、撤回。很多任务的语义不同,身体运动却共享。ActionCache 把这种共享性显式变成缓存命中率和延迟收益。

它也提醒我们,具身智能的“记忆”不一定只存在于长上下文、地图或语义状态里。动作空间本身也可以记忆。一个成功抓取前的中间动作、一个接近物体的轨迹片段、一个放置阶段的末端姿态,都可能是未来推理的捷径。

当然,这条路要进入真实部署,还需要更强的安全边界。缓存动作如果在错误场景中被误用,机器人不是生成一句错话,而是可能撞到物体或人。论文的 conservative fallback 是第一层保护,但实际系统还需要碰撞检测、力控约束、任务级验证和更谨慎的缓存写入策略。

所以 ActionCache 的意义不是“让 VLA 免费加速几十倍”。更准确地说,它证明了一件以前没有被充分利用的事:在 flow-based VLA 中,过去成功动作不是日志,而是可复用的计算。只要检索质量足够高,机器人就不必每一次都从噪声中重新发明同一段动作。