VLA模型升级:历史感知模块让机器人摆脱单帧失忆

📅 发布时间:2026/10/19 20:07:34
VLA模型升级:历史感知模块让机器人摆脱单帧失忆
最近在啃VLAVision-Language-Action模型相关的论文读到一篇思路很直接、但又特别容易被忽略的工作题目叫“HAMLET: SWITCH YOUR VISION-LANGUAGE-ACTION MODEL INTO A HISTORY-AWARE POLICY”。翻译成人话就是把VLA模型从“只看当前这一帧就下决定”升级成“看完前面几步再下决定”。这个方向太贴近实际部署了。我在多个机器人操作实验里反复撞到同一个问题VLA模型的推理是基于单帧图像和单条指令的也就是说模型每次“看世界”都是失忆状态——上一秒发生了什么、手已经移动到了哪里、上一步动作是对是错模型一概不知。这导致长程任务里动作链条越跑越歪而且没有任何自纠错能力。而HAMLET这篇论文给的解法不是重新训练一个大模型而是在现有VLA外面挂一个轻量的历史感知模块把过去的帧、语言指令、动作序列打包成条件信息引导VLA输出更合理的动作。这篇文章我不会复述论文全文那不是我的风格。我更想把自己读完之后的架构理解、训练细节、实验设计逻辑以及我在自己的模拟项目里复现类似思路时踩过的坑一起整理出来。无论你是想跟读这篇论文还是打算把历史感知这个能力加到自己的VLA方案里这篇文章应该都能让你少走几段弯路。1. 论文在解决什么痛点1.1 VLA模型的“单帧失忆”问题先聊清楚VLA模型的原罪在哪里。现在主流的视觉-语言-动作模型本质上就是一个“多模态条件生成模型”。你给它一张当前摄像头图像、一段自然语言指令它输出一串离散的动作token。整个过程跟多轮对话最明显的区别在于语言模型在对话时会保留前面几轮对话作为上下文而大多数VLA模型在每一步推理时只把当前帧和当前指令拼进模型历史信息完全不进入条件空间。表面上看这没什么问题因为很多机器人任务被看作马尔可夫决策过程理论上只需要当前观测和当前目标就可以决定动作。但现实世界不是这样的原因有三个。第一单帧图像存在严重的遮挡和歧义。比如机械臂在抓取一个物体时物体一开始在视野里等你手伸过去物体可能在镜头里被机械臂自己挡住。这时候只看当前帧模型根本不知道目标物体在哪更别说判断“自己是不是已经抓稳了”。第二动作连续性被撕裂。同一段任务里如果你让模型看连续的几帧你会发现每个中间动作都依赖前一个动作的结果。比如“先推开门再拿杯子”模型在第50帧时如果不知道第49帧自己已经推开门了就会反复尝试执行“推门”动作。单帧推理在这种多阶段任务里几乎必然导致抖动和重复。第三错误不可恢复。开环执行时只要某一步动作错了——比如抓取时手指差了1厘米——后续所有动作都会在错误的状态上继续推导。没有历史信息模型无法发现自己已经偏离了预期轨迹更不会主动纠正。我在自己的仿真环境里做过一个很简单的实验让一个开环VLA模型执行“拿起红色方块放到蓝色托盘里”。模型在第一步定位红色方块时出了一个小错手指碰到方块但没抓紧。结果后面所有步骤都按照“已经抓起来了”继续执行最后视觉看起来像在完成一个完全不存在的过程。这个现象在真实机器人上更显著因为真实世界还有物理扰动、物体滑落、外部干扰等不可控因素。HAMLET这篇论文的核心出发点就是要把这些“被丢掉的历史”捡回来。1.2 为什么HAMLET是“切换”而不是“重训”这篇论文标题里用了“SWITCH”这个词我觉得选得很准确。它的意思是不需要为带历史感知的任务重新训练一个VLA模型而是把现有的VLA模型当作一个“动作生成器”在外面加一个轻量历史融合模块就能把模型切换到历史感知模式。为什么要这么做直接原因是性价比。现在一个可用的VLA底座模型参数量动辄几十亿到上百亿如果想让它支持时间序列输入需要把模型架构改成能处理多帧输入的形式意味着从头预训练或者全参微调。普通团队根本背不动这个成本一个完整的预训练流程少说也要上千张卡跑几周。间接原因是模态差异。VLA模型通常采用视觉tokenizer、语言tokenizer分别编码图像和指令再把两种token拼在一起进Transformer。如果要在输入端加入历史信息不是单纯把历史帧的像素拼接起来就行还需要把历史动作序列、时间戳、任务进度等异构信息统一编码。这就涉及模型内部的跨模态对齐问题直接在原模型上改会破坏原有知识。HAMLET的做法是借鉴了条件生成模型里常见的“控制模块”思路也就是把VLA当成冻结的主干网络历史信息经过一个小型编码器变成一组“任务条件特征”再通过加权融合的方式注入当前观测的embedding空间。这样VLA自带的视觉语义能力和动作生成能力全部保留新增的历史感知能力相当于一个辅助的外挂模块。这个设计在工业落地时特别友好。你可以今天先部署一个标准的VLA推理服务明天在不变更主线模型的情况下加上历史模块两者可以平滑切换。如果你把整个VLA模型当作一个成熟的专家HAMLET做的事情就是给这位专家配上一个记事本。2. HAMLET的架构设计与模块拆解2.1 历史信息从哪几种渠道进来论文里的历史感知模块并不是简单的“把前K帧图像拼成一排”而是把三类历史信息同时编码再融合。我自己整理下来这三路分别是第一路是历史视觉帧序列。即过去若干时刻的RGB图像通常是固定间隔采样比如每秒取3帧总计取最近6到8帧。这路信息的作用是让模型知道“环境前一刻长什么样”用于捕捉物体移动、手臂位置变化、遮挡恢复等视觉上下文。第二路是语言指令和任务描述。注意这里说的不是当前这一步的指令而是整条指令序列包括中间阶段的目标描述。比如任务“把盘子里的苹果拿起来放到桌子左边”在中间某个时刻模型需要知道“已经完成了拿苹果这半段接下来是放”。HAMLET把这类信息按时间顺序编码给模型提供一种“任务进度感”。第三路是历史动作序列。这里指的是模型自己过去输出过的动作token或者实际采集到的电机控制信号。机器人动作空间通常是一个多维向量比如六轴末端位姿、夹爪开合度等。把动作序列喂给模型相当于模型能看到自己的“运动轨迹”和“行为惯性”它才知道自己刚才的手势姿势和位置。这三路信息有各自的编码方式在进入融合之前不会直接拼接到一起。原因很简单图像特征是1024维的视觉embedding语言特征是512维的文本embedding动作序列则是连续数值三种数据分布差异极大直接拼接会导致梯度震荡和表征失衡。论文采用的方式是各做一个轻量特征投影层先把三类信息映射到统一维度再进入下一步处理。2.2 历史编码器与信息压缩策略历史编码器在论文里接手的输入是一个“时间段”而不是“单帧”。实际操作中它会把时间序列里的每一帧逐帧编码成特征向量然后做一个加权平均或者用一个小型Transformer做时序聚合。我在复现时发现直接用平均池化会丢失关键事件信息比如“第5秒时物体被碰翻”这个瞬间如果被平均掉就完全失效了。更合理的做法是用一个可学习的注意力聚合层。具体来说给序列中每一帧的特征计算一个重要性权重然后按权重求和。比如某帧中机械臂刚碰到物体说明抓取事件正在发生这帧的重要性就会更高。这个注意力权重是通过一个小型MLP从当前观测里学出来的推理时动态调整。历史动作序列的处理相对麻烦一点。动作token是离散的不同任务的token长度不一样。如果直接输入TransformerGPU显存开销会随历史长度线性上涨。HAMLET的解决方案是把动作序列压缩成一个“行为摘要向量”大概思路是将整段动作序列当作一个序列编码任务输出一个定长向量代表“过去一段时间内动作风格的浓缩”。这么设计的好处是无论历史有多长最终进入融合分支的向量维度都是固定的不会造成上下文长度爆炸。语言指令的处理在论文里不算复杂直接用VLA模型自带的语言编码器对当前指令编码再额外存一个“历史指令列表”编码。我在对照实验中发现把历史指令拆开处理比整段拼接效果更好因为机器人任务往往在一轮对话里包含多个子目标拆开后模型能区分不同阶段的目标边界。2.3 门控融合机制给每个时刻的“记忆”加权这是整篇论文里我个人认为最巧妙的部分。HAMLET不把所有历史信息无差别地注入当前决策而是用一个门控机制动态决定“此刻应该参考多少历史”。门控的物理含义可以类比人的注意力有些任务里当前帧信息已经足够比如一个静态抓取任务模型完全可以只看当前画面过多历史反而引入噪声但有些任务里当前帧是模糊的比如物体被遮挡就必须更多依赖之前的记忆。门控融合层的输入是当前观测embedding和历史上下文embedding输出是一个介于0到1的权重标量。这个标量会作用在历史embedding上然后与当前观测embedding相加。具体公式写出来大致是( h_{fused} \lambda \cdot h_{history} (1 - \lambda) \cdot h_{current} )其中 (\lambda) 就是门控权重。极端情况下如果 (\lambda) 趋近于0HAMLET就退化成标准的无历史VLA模型。这个设计在任务切换时特别好用——执行静态任务时模型会自动降低历史权重执行动态任务时权重升高相当于自动判断任务对记忆的依赖程度。我在具体实现时选用了sigmoid输出代替硬编码阈值让权重可以更平滑地变化。训练初期门控权重会偏向0也就是模型先学会了基于当前帧做预测训练后期再慢慢学习如何利用历史信息。这个课程式训练节奏让整个模块的收敛稳定了不少。3. 训练范式与数据组织方式3.1 数据格式改造从单帧样本到时间序列样本想要训练HAMLET最根本的变化是数据格式。标准VLA的数据集一般存成“{图像, 指令, 动作}”三元组每个样本相互独立。HAMLET需要的则是“{历史帧序列, 历史动作序列, 当前帧, 指令, 动作}”这样的时间块样本。我在整理训练数据时用了一个标准的滑动窗口策略。假设任务总长是120步窗口长度是8步那么我会从第9步开始逐帧切窗每个窗口内包含前8步的历史信息以及当前步。这相当于把一个长任务拆成很多个重叠的子序列数据量会比原来放大好几倍。这里有一个必须注意的问题独立采样会造成严重的偏置。如果每个窗口都是从任务中间随机截出来的模型会看到大量“任务进行到一半”的场景反而缺少从零开始的经验。我后来采用了一个混合采样策略前30%的窗口从任务开头切让模型多学开局状态后70%均匀分布在任务各阶段保证中间状态覆盖。数据增强也是这个阶段的重头戏。我在图像通道加了亮度扰动和随机遮挡用来模拟真实环境中传感器噪声。动作通道加了小幅高斯噪声避免模型对历史动作过度迷信。这一步虽然简单但在后续实验里的收益非常直接模型的鲁棒性提升了一个档位。3.2 训练三阶段预训练、微调与冻结策略HAMLET的训练分成三个明确的阶段阶段之间切换时要特别注意学习率和优化器状态的清扫。第一阶段是“预热对齐”。这个阶段冻结VLA主干只训练历史编码器和门控融合层。目的是让新增模块先学会把历史信息映射到和当前观测一致的embedding空间里。这个阶段损失函数可以直接用VLA动作预测的交叉熵不需要额外改。学习率可以调大一点我用的是3e-4跑一万步左右就基本能看到历史分支的输出不再是一团乱噪声。第二阶段是“联合微调”。把VLA主干里靠近输出端的最后几层Transformer解锁和历史模块一起微调。这个阶段的意图是让动作生成头适应带历史条件的特征表示。注意这里不是全参微调只解锁最后三分之一的层否则历史模块刚学到的表征会被主干的大规模梯度变化冲掉。学习率要降一个数量级我用的是3e-5。第三阶段是“任务适配”。如果要在特定真机任务上部署可以把任务演示的轨迹数据混合进训练集用1e-5的学习率跑几百步。这一步主要是让模型熟悉目标环境的物理特性和物体布局不需要大动干戈。我自己的习惯是在第二阶段结束后做一次快速的回放评估拿旧任务样本重新评测一遍确认VLA原有能力没有被破坏。这个检查特别重要因为历史模块加入后当前观测的embedding会被融合分支污染如果门控权重分配不当可能会出现“原始能力退化”的问题表现为简单任务反而做不好了。3.3 轻量训练路线的成本对比这部分有很多人问过到底值不值得为了历史感知专门训这样一个模块。我按自己的实际配置算一笔账假设VLA底座是几十亿参数的开源模型历史编码器只是一个几千万参数的小型Transformer。如果走全量微调路线需要的显存至少是80GB级别乘以8卡训练周期在两周以上。而HAMLET的轻量路线在第一阶段只用训练历史模块参数占全部参数的比例不到5%冻结模式下对显存的需求大约只是全量微调的40%普通双卡3090级别的配置勉强能跑起来。如果只做单任务部署整个训练周期可以压缩到一到两天。这个成本差异决定了HAMLET这种方案更适合谁预算有限的人、需要在多场景快速迭代的人、以及希望把同一个VLA复用在多个不同任务上的工程团队。不需要为了一个历史感知能力就推倒重来这是它最大的现实价值。4. 实验设计逻辑与关键结论解读4.1 长程任务效果历史长度怎么影响成功率论文里最核心的一组实验是在长程操作任务上对比不同历史窗口长度下线塔效果。这里的长程指的是超过30步的序列任务比如先码放、再抓取、再转移、再堆叠这一套连续动作。实验结论可以概括成一个短语“够用就好”。历史长度从0增加到8时任务成功率显著提升原因很简单模型开始能感知自己的动作轨迹规避了重复和振荡但是继续增加到16或更高成功率的提升就非常有限了某些任务甚至出现轻微下降。这个现象的解释是过长的历史里包含了大量无关阶段的信息比如任务早期探索阶段的无效动作这些噪声干扰了当前决策。我在复现时发现一个官方实验里没有细讲的细节历史窗口的采样间隔比窗口长度更重要。如果历史帧来自均匀的每秒3帧那么在快速运动场景下相邻帧之间差异太小提供的信息量很低。更好的做法是根据动作幅度自适应采样动作变化快的时间段多采样几帧动作平缓的时间段少采样几帧。我在一个托盘操作项目里用这个自适应采样方法成功率比固定采样高了接近一成。4.2 语言条件恢复历史模块与语言指令的协作论文有一个让我印象深刻的实验叫做“语言条件恢复”。场景大概是这样的机器人执行一个任务中途有一个物体被外力碰倒然后操作员在语言通道里发出一个新指令“红色物体倒了把它扶起来再继续”。作者展示了HAMLET能正确处理这个中途切换而基线VLA模型会无视新指令继续执行原来的计划。这里起作用的是历史动作序列与语言指令的交叉信息。模型看到历史里夹爪已经离开红色物体、当前图像里物体是倒下的再结合新指令中的“扶起来”判断出当前任务状态和语言指令的目标不匹配于是重新生成新的动作序列。而基线模型只看到“当前画面里物体倒下”加上“继续执行原计划”完全无法把两段信息联想到一起。我在自己的仿真实验里也尝试了类似场景把“到达某位置”改成“如果有人推了物体就重试”这类条件性指令。HAMLET架构在语义理解上有一个天然优势语言编码器的表征在融合过程中被历史信息增强了模型对指令的理解更接近“上下文相关的意图推断”而不是简单的关键词匹配。4.3 自适应历史权重门控机制的泛化能力论文作者在实验里单独评估了门控权重在不同任务上的分布情况结论是门控确实学出了一些“可解释的偏好”。比如在“移动物体到目标点”这类任务里门控权重在中后期明显升高因为此时判断是否到达目标需要结合历史轨迹而在“原地旋转”这类任务里门控权重始终很低因为这类动作只依赖当前朝向。这说明门控机制的成功不是偶然的它实际上学了一个隐式的“任务状态分类器”。我试过把门控权重可视化输出发现它在任务快要结束时有一个明显的峰值——因为此时模型需要回忆整个轨迹来判断“是否完成了全部步骤”。这个发现对调试特别有用如果某个任务里门控权重一直在高位徘徊说明任务本身设计得过于依赖记忆可能需要重新设计部分动作序列。5. 复现与实操经验总结5.1 数据准备与训练环境配置清单如果你打算自己复现HAMLET的思路我把整个环境的配置清单整理成了一张表格方便直接对照配置项推荐选择说明VLA底座模型开源视觉-语言-动作模型必须带语言编码器和动作解码器训练框架PyTorch DeepSpeed冻结合并参数时节省显存历史编码器小型Transformer4层左右参数量控制在千万级门控融合层单层MLP sigmoid直接在embedding维度上计算采样策略动作自适应采样动作幅度大时加密采样训练数据长任务轨迹 单步混合采样前30%窗口从任务开头切学习率策略预热后阶梯下降冻结阶段3e-4到3e-5评估环境仿真环境 真机各一组仿真调参真机验证训练时我的显存配置是四张24GB显卡冻结VLA主干后历史模块加融合层的参数量在几千万实际占用的显存大头其实是输入端的视觉特征缓存。如果想进一步压缩显存可以把历史帧的图像分辨率降低到224x224只在当前帧上保留较高分辨率。我测过之后发现对最终成功率的影响很小。5.2 部署推理时的窗口管理与状态维护训练完成后落地部署时有一个容易被忽略的问题推理阶段怎么维护历史窗口。训练时每个样本是预先从完整轨迹里截好的但推理时是实时生成只能靠不断往滑动窗口里追加数据。我的做法是维护一个环形缓存每步推理完当前帧和动作把它们写入缓存下一轮再从缓存里取出最近K帧作为历史输入。这里有一个耗时风险点如果用PyTorch的拼接操作把历史帧和当前帧拼在一起每次都会触发一次新的内存分配推理延迟会增加不少。我最后改用显存预分配策略把窗口区域的张量在启动时一次性分配好后续只用索引填充更新延迟降了下来。还需要注意历史窗口的更新频率策略。如果每一帧都更新并重新推理机器人会频繁抖动我设为每3帧滚动更新一次相邻推理之间动作输出保持一致性更强。尤其是抓取类任务里关节角度突变会导致夹爪抖动降低成功率。5.3 常见复现问题与排查技巧实录我把复现期间遇到的高频问题直接整理成一个速查表每个问题都附了排查思路现象可能原因排查方法历史模块加进去后任务成功率反而下降门控权重初始值太大噪声注入过多把sigmoid输出初始偏置设为-2让初始权重接近0训练时历史分支梯度消失历史编码器输入范围不对图像未归一化检查历史图像通道的顺序和数值范围长窗口推理时显存溢出历史帧缓存未复用每次推理都重新拼接使用预分配环形缓冲避免缓存Tensor反复创建简单任务被复杂化动作出现多余的摆动门控未正确学到低权重将简单任务样本的比例增加到30%以上语言条件恢复指令无效历史动作序列编码丢失了动作顺序检查动作序列编码器是否带有位置信息排查时有一个技巧我几乎每次都用把门控权重打印出来可视化。如果任务执行中大部分时间门控权重接近1说明历史信息太容易被接纳模型可能产生了记忆依赖正常情况应该是一段时间内权重在0.3到0.6之间波动只在关键阶段升高。如果权重曲线完全没有起伏多半是门控层的梯度消失需要检查融合层后的激活函数是否饱和。5.4 几个值得后续尝试的改进方向论文本身的方案已经闭环但在实际工程项目里还有一些可以继续扩展的点。第一是引入更细粒度的多模态时间对齐。历史视觉序列和历史动作序列本来就是同步采集的但HAMLET把它们分开编码后再融合丢掉了“哪个时刻的视觉对应当前动作状态”这种细粒度对齐信息。后续可以尝试在历史编码器里加一个跨模态注意力层让视觉特征和动作特征在时间维度上显式对齐理论上能提升长程操作的连贯性。第二是把门控权重做成任务级可学习的条件输入。目前门控权重完全由当前观测和历史表征决定如果能在输入里显式加入“当前任务类型”的编码模型可以更快收敛到与任务匹配的记忆策略。第三是把历史模块扩展到多机器人协作场景。目前的历史信息都来自单个机器人自身的传感器如果能加入其他机器人传递过来的交互状态那么协作任务里的预测会更准确。这部分需要硬件支持和通信协议设计但架构上HAMLET的融合框架可以自然扩展。我在实际项目里最想尝试的是把HAMLET的历史感知能力用于在线失败检测。既然模型能感知历史动作序列和任务进度那么自然可以从中挖掘出“动作偏离预期”的信号。如果把门控权重的异常变化当作一个检测特征再配一个异常分类头理论上可以实现部署阶段的实时失败预警。这个功能一旦成熟对实际产线的价值会非常大。写在最后的一个经验读HAMLET过程中我最大的体会是想提升VLA模型的实际表现不一定非得把精力花在扩大模型规模和堆积训练数据上。很多问题出在决策过程没有记忆、没有上下文一个设计得当的历史感知模块就能带来可观的性能提升。这种“小而稳”的改动往往比盲目堆算力更值得优先尝试。如果你准备在自己的项目里应用这个思路我的建议是先把门控机制的收敛状况作为第一优先级检查项不要急着调模型结构。只要门控能学出合理的权重分布后续历史编码器、数据采样和部署优化都会顺很多。如果门控权重一直是平的或者始终偏向一端多半是数据本身的历史信息与动作关联太弱先回数据层面修正再继续往后调。