ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

一文搞懂视觉语言动作模型VLA原理

一文搞懂视觉语言动作模型VLA原理

DeepSeek、ChatGPT 这些大语言模型不仅能检索信息,还能对话、写作、推理,甚至在一定程度上理解人的意图。但是如果把大模型放到机器人身上,新的问题就来了:它要怎么从“会说话”变成“会干活”?

比如你对机器人说:“把桌上的红色方块抓起来。”它需要看见桌面、理解指令、判断自己的夹爪和目标物体之间的关系,然后移动过去、对准、下降、闭合夹爪,最后把物体拿起来。这中间就发生了一个关键变化:模型的输出不再只是语言,而是动作。

从大语言模型到机器人具身智能,中间有一条很重要的技术路线,叫 VLA。VLA 的全称是 Vision-Language-Action,也就是“视觉-语言-动作”。如果说 ChatGPT 等大语言模型 LLM 解决的是“怎么和人对话”,视觉-语言模型 VLM 解决的是“怎么看懂图片和文字”,那么 VLA 要解决的就是:看见之后,怎么行动。

这篇文章就用一个最简单的抓取任务,讲清楚 VLA 是怎么从“会看、会说”,一步步走向“会动”的。


VLM:先让模型看懂,再让它“说出动作”

第一步,是直接借用 VLM 的能力。

VLM 是 Vision-Language Model,也就是视觉语言模型。它原本擅长的是“看图回答问题”。比如给它一张抓取场景图片,它能看懂里面有夹爪、有红色方块,也能理解“抓起红色方块”这句话是什么意思。

最直接的 VLA 想法,就是让 VLM 不只回答问题,而是直接输出动作描述。比如模型看到图像后输出:向右移动一点,向前靠近,下降,闭合夹爪。

再进一步,还可以把动作也变成 token。token 可以简单理解成模型处理信息的基本单位。文字可以是 token,动作也可以被切成 token。比如:向左、向右、向前、向后、上升、下降、打开夹爪、闭合夹爪。这样,动作就变得像文字一样,可以被模型一步一步预测出来。

这一步的好处是非常直观。原来大模型是在预测下一句话,现在它可以预测下一步动作。它看见夹爪在左边、红色方块在右边,就输出“向右”;看到夹爪接近物体,就输出“下降”和“闭合夹爪”。

但它的问题也很明显:聊天里说“向右一点”通常没问题,但机器人控制里,“一点”到底是多少?1 厘米、2 厘米,还是 0.3 厘米?这些差别在文字里不大,在真实抓取里可能就是抓住和抓空的区别。

所以,直接让 VLM 输出动作,是理解 VLA 最容易的一步,但还不够适合精细控制。


Action Head:把“看懂了”变成连续动作

第二步,是在 VLM 后面加一个 action head。

Action head 可以理解成“动作输出头”。VLM 负责看懂图像和语言,action head 负责把这种理解结果翻译成机器人能执行的动作数值。

比如 VLM 先理解到:红色方块在夹爪右前方,当前任务是把它抓起来。接下来 action head 不再输出“向右一点”这种话,而是输出一组具体数字:

[Δx, Δy, Δz, gripper]

这里的 Δx、Δy、Δz 表示机器人末端在空间里的移动量,gripper 表示夹爪开合。比如它可以表示:末端向右移动 1.2 厘米,向前移动 0.8 厘米,高度暂时不变,夹爪保持打开。真实系统里还可能加入姿态角、关节角、末端速度等信息。

所以,action head 解决的是一个更根本的接口问题:大模型原本擅长输出文字,但机器人需要的是连续动作向量。Action head 就是在大模型和机器人控制系统之间搭了一座桥。

它确实能减少动作离散化带来的误差。比如原来只能在“向右一小步”和“向右一大步”之间选,现在可以直接输出“向右 1.2 厘米”。但它真正重要的地方,是把“看懂任务”接到了“控制机器人”。

不过,只输出下一步动作仍然不够。真实抓取是一小段连续过程。中间每一步都要连贯,不能一会儿向左、一会儿向右。只预测下一步就会让机器人犹豫不决,自我否定之前的决策。


Action Chunking:一次生成一小段动作

所以第三步,是从“预测下一步动作”,变成“预测一小段动作”。

这一小段动作就叫action chunk。chunk 可以理解成“一段动作片段”。在机器人里,它通常指模型一次预测出的未来几步到几十步的连续控制量,每一步中包括机器人末端该怎么移动、姿态该怎么变化、夹爪该什么时候闭合。比如抓取红色方块时,模型会一次给出未来一小段时间内的动作序列。我们从语义上可以把它理解成“靠近、对准、下降、闭合、抬起”,但真正交给机器人的,是一串可以连续执行的动作数值。

机器人执行时也不是把这一段动作从头到尾死板跑完。更常见的方式是滚动更新:模型先预测未来一小段动作,机器人先执行其中前几步;与此同时,相机继续观察环境,模型再根据新的图像和机器人状态,重新预测下一段动作。这样机器人就能一边执行、一边修正,而不是完全依赖一开始生成的那段动作。

为什么要这么做?因为机器人运动需要连续性。如果模型每一帧都只想“下一步”,动作可能会变得犹豫、抖动、不连贯。就像一个人走路,如果每一步都重新思考“下一只脚往哪里放”,动作会很僵硬。更自然的方式,是提前想好接下来几步怎么走,然后边走边调整。

Action chunk 的意义就在这里:它让 VLA 不再只输出孤立动作,而是输出一段更连贯的动作过程。对抓取任务来说,它更像是在生成一个小计划:靠近、对准、下降。这个计划不一定很长,但足够让机器人动作更稳定。

Flow Matching:让动作生成更自然、更连续

第四步,是用更强的生成方法来产生 action chunk。

前面说的 action chunk,只是说明模型要一次输出一小段动作。但这段动作具体怎么生成,仍然是关键问题。Flow Matching 要做的,就是学习一条从“随机动作”到“真实动作”的变化路径:训练时,模型会看到大量真实机器人操作数据,也会看到被扰动后的动作片段;模型要学会在当前图像、语言指令和机器人状态下,应该沿着什么方向,把一段不太合理的动作逐步推向真实动作。

回到抓取任务里,一开始可以先有一段比较随机的动作序列,它可能还不像一个真正的抓取过程。Flow Matching 会根据画面中夹爪和红色方块的位置关系,不断修正这段动作,让它逐渐变成“靠近目标、对准中心、下降、闭合夹爪、向上抬起”的连续轨迹,最后输出一段可以执行的 action chunk。

为什么不直接用 action head 回归这一整段动作?因为真实机器人任务往往有很多种可行做法。抓同一个红色方块,可以从左边靠近,也可以从右边靠近;可以先调整姿态再下降,也可以边靠近边微调。简单回归容易把多种可行动作“平均”在一起,生成一条看似居中、实际不好执行的轨迹。

Flow Matching 这类生成式方法的价值,就在于它更适合表达“动作有多种可能”。它在视觉、语言和机器人状态的约束下,生成一段更自然、更平滑、更接近真实操作的动作片段。换句话说,它让 VLA 输出更像人类示教、更适合机器人执行的动作。

从“看懂”到“会动”

VLA 的技术发展,基本就是按照这条主线:VLM 让模型看懂任务,action head 让模型输出动作数值,action chunking 让模型一次生成一小段动作,flow matching 让这段动作更自然、更连续。

当然,VLA 还远没有走到终点,它也不是具身智能的唯一答案。现在大家都还在探索:到底怎样的模型结构、数据方式和系统架构,才能让机器人稳定、可靠地完成真实任务。VLA 只是其中一条很有代表性的路线,而且这条路还在继续往前走。

机器人是如何理解环境的?

在上一篇里,我们讲到 VLA 可以粗略理解为三部分:看懂环境、理解任务、生成动作。机器人要完成一个任务,需要先知道自己面对的是什么。桌上有什么物体?目标物体在哪里?人类说的“把红色方块放到盒子里”到底指什么?这些问题,都属于感知和理解的范围。

在传统机器人系统里,感知通常是一个比较工程化的模块。相机负责拍图,检测算法负责找物体,分割算法负责区分边界,位姿估计算法负责算出物体位置,然后规划和控制模块再接着往下做。这个流程很清晰,也很可靠,但它往往需要人为定义很多中间环节。

VLA 里的“多模态感知”有一点不一样。它不只是让机器人看到图像,也不只是识别物体名字,而是希望模型能把视觉、语言、空间关系和任务意图放在一起理解。这里最核心的技术基础,就是 VLM,也就是 Vision-Language Model,视觉语言模型。

VLM:让模型同时理解图像和语言

VLM 的基本目标,是让模型同时处理视觉和语言信息。

最简单地说,VLM 可以看一张图片,然后回答关于这张图片的问题。比如给它一张桌面图片,问:“红色方块在哪里?”模型可以回答:“在桌子的左侧,靠近蓝色圆柱。”再问:“哪个物体更适合被夹爪抓取?”它可能会结合物体形状、位置和可见区域,给出一个判断。

这和普通图像分类模型不同。传统图像分类模型通常回答“这张图里有什么”,比如猫、狗、杯子、键盘。目标检测模型可以进一步给出物体框,告诉你每个物体大概在哪里。VLM 则更进一步,它可以把图像内容和自然语言问题联系起来,进行更开放的理解。

在机器人任务里,这种能力非常重要。因为人类给机器人的指令,很少是严格结构化的参数。我们不会说:“抓取图像坐标 x=320, y=180 处的物体。”我们更可能说:“把桌上的红色积木拿起来。”这里面有物体类别、颜色、空间位置和任务意图,模型必须把它们连在一起。

VLM 是怎么实现看图说话的?

从工程实现上看,VLM 通常由三部分组成:视觉编码器、语言模型,以及连接视觉和语言的对齐模块。

视觉编码器负责“看图”。它会把输入图像切成很多小块,或者提取成一组视觉特征。语言模型负责“理解和生成文字”。它本来擅长处理 token,也就是一个个词或子词。中间的关键问题是:图像不是文字,怎么才能送进语言模型里?

所以 VLM 需要一个连接层,把视觉特征转换成语言模型可以理解的“视觉 token”。这些视觉 token 不一定对应真实的词,但在模型内部,它们可以和文字 token 放在同一个序列里处理。这样一来,模型看到的就不再只是“图片”和“句子”两类孤立输入,而是一串混合了视觉信息和语言信息的 token。

可以把这个过程简单理解成:

这就是很多 VLM 的基本技术路线。

第一步:把图像变成视觉 token

语言模型天然处理的是文字。比如一句话“抓起红色方块”,会被分词器变成一串 token,然后送进 Transformer。图像则不同,它本质上是像素矩阵,不能直接作为文字输入。

因此,VLM 首先要用视觉编码器处理图像。常见做法是使用 ViT,也就是 Vision Transformer。ViT 会把一张图像切成许多 patch,比如 16×16 像素的小块。每个 patch 经过编码后,会变成一个向量,表示这块图像里的视觉信息。

如果是一张桌面图片,这些视觉 token 里可能包含颜色、边缘、纹理、物体局部形状等信息。单个 token 未必对应一个完整物体,但很多 token 组合起来,就能表达“这里有一个红色方块”“那里有一个白色碗”这样的视觉结构。

在机器人场景里,图像 token 的质量很重要。因为机器人需要知道目标物体在哪里、周围有什么障碍、夹爪应该往哪个区域移动。如果视觉编码器丢掉了过多空间细节,后面的动作生成就会受到影响。

第二步:把视觉特征接到语言模型上

视觉编码器输出的是向量,语言模型内部处理的也是向量。看起来两者形式相似,但它们并不天然处在同一个语义空间里。

视觉编码器学到的是图像特征,语言模型学到的是文字语义。中间需要一个对齐模块,把视觉特征映射到语言模型可以使用的表示空间中。这个模块可以很简单,比如一个线性投影层;也可以更复杂,比如用一个小型 Transformer,专门负责从大量视觉特征中提取和语言相关的信息。

这一步非常关键。它决定了语言模型能不能把图像里的区域和文字里的概念对应起来。

比如用户输入:“红色方块在哪里?”模型需要把“红色”“方块”这两个语言概念,和图像里某一组视觉 token 对齐。如果对齐做得不好,模型可能会知道图中有方块,也知道“红色”是什么意思,但无法稳定判断哪个视觉区域对应“红色方块”。

所以,VLM 的核心能力之一,就是视觉-语言对齐,让视觉内容和自然语言描述之间建立对应关系。

第三步:语言模型负责综合推理

当视觉 token 和文本 token 一起进入大语言模型后,Transformer 会通过注意力机制在两类信息之间建立联系。

比如输入是:

图像:桌上有红色方块、蓝色圆柱、白色碗

问题:把红色方块放进碗里,应该关注哪里?

模型在处理“红色方块”这个词组时,会注意到图像中对应红色物体的视觉 token;处理“碗”时,会注意到另一个目标区域;处理“放进”时,则会把抓取目标和放置目标联系起来。

这也是 VLM 和普通视觉模型最大的不同。普通视觉模型通常输出一个固定结果,比如分类标签、检测框或者分割掩码。VLM 的输入问题不同,关注点就可以不同。同一张图像,问“红色方块在哪里”,它会关注方块;问“哪个物体可以作为容器”,它会关注碗;问“先抓哪个物体”,它又会结合任务目标给出不同判断。

VLM 是怎么训练出来的?

VLM 的训练通常是分阶段进行。

第一阶段通常是图文对齐训练。模型会看到大量图像和对应文字描述,学习图像和文本之间的匹配关系。比如一张图配一句“a red cube on the table”,模型就要把图中的红色方块和文字描述联系起来。这个阶段解决的是“图像和语言能不能对上”的问题。

第二阶段是视觉问答和指令微调。模型不仅要知道图文是否匹配,还要学会按照人的问题进行回答。比如给一张图片,问“桌上有几个物体?”“红色方块在什么位置?”“哪个物体更靠近机器人?”这些任务会让模型从图像描述走向图像理解。

第三阶段,如果要进入机器人领域,还需要机器人数据继续微调。普通互联网图像和机器人第一视角图像差异很大。机器人看到的是夹爪、桌面、物体、遮挡和运动过程,不是普通摄影图片。为了让 VLM 适应机器人任务,需要用机器人操作数据、桌面 manipulation 数据、仿真数据或人工标注数据进行训练。

这也是为什么 VLM 可以作为 VLA 的基础,但不能直接等于 VLA。通用 VLM 可能会看懂“红色方块在桌上”,但它未必知道机械臂应该从哪个角度接近,夹爪宽度是否合适,抓取之后如何避障。这些都需要机器人数据和动作学习进一步补上。

VLM 输出的是什么?

在普通视觉问答任务里,VLM 的输出通常是文字。比如:

红色方块在桌子的左侧,靠近白色碗。

但在 VLA 中,单纯输出文字还不够。机器人最终需要的是动作,而不是一句描述。所以 VLM 的输出可以有几种不同用法。

一种方式是让 VLM 输出高层任务理解。比如模型先生成:“目标物体是红色方块,放置目标是白色碗,当前应该先靠近红色方块。”这相当于把自然语言任务变成更结构化的中间表示,再交给后面的规划或控制模块。

另一种方式是直接使用 VLM 内部的隐藏特征,而不是它最终生成的文字。也就是说,模型不一定要先说出一句话,再让机器人执行;它可以把图像和语言融合后的特征向量传给 action head,由 action head 直接预测连续动作。

在很多 VLA 模型里,第二种方式更常见。因为机器人控制需要连续、快速、可微分的表示。文字描述虽然直观,但中间会损失很多细节,也可能引入不稳定性。

可以简单理解成:

这里的 VLM 不只是聊天模型,而是动作策略的感知和理解前端。

VLM 的技术链路

从技术实现上看,VLA 中的多模态感知通常是这样工作的:视觉编码器把图像变成视觉 token,对齐模块把视觉 token 接到语言模型空间里,语言模型融合图像和指令形成任务理解,最后 action head 再把这种多模态特征转换成机器人可执行的连续动作。

所以,VLM 是 VLA 理解世界的入口。没有 VLM,机器人很难自然理解“红色方块”“靠近杯子的物体”“把它放进去”这些人类语言里的开放概念;只有 VLM 也不够,因为真正让机器人动起来,还需要动作表示、机器人数据、闭环控制和真实物理约束。


机器人是如何生成动作的?

前两篇我们讲了 VLA 如何理解图像和语言。到了第三篇,就要进入最关键的一步:机器人如何把理解变成动作。

比如机器人收到了指令:把红色方块放进白色碗里。VLM 可以识别红色方块和白色碗,也可以理解“放进去”这个任务关系。但机器人真正执行时,并不需要一句自然语言回答,而是需要一串具体控制量:机械臂末端往哪里移动,夹爪什么时候闭合。这中间缺的,就是action head。

可以把 VLA 模型粗略拆成两部分:前面是理解模块,负责看图像、读语言、理解任务;后面是动作模块,负责把理解结果变成机器人可以执行的动作。这个动作模块,通常就可以叫 action head,也有人叫 action decoder 或 action expert。

action head 的作用,就是把视觉和语言理解结果,转换成机器人能够执行的动作表示。

动作到底如何表示?

设计 action head 之前,首先要定义动作是什么。

对一个机械臂来说,动作可以有很多种表示方式。最常见的是末端位姿增量,比如:

Δx, Δy, Δz, Δroll, Δpitch, Δyaw, gripper

前三个量表示末端在空间中的平移,后三个量表示姿态变化,最后一个量表示夹爪开合。这样一个 7 维向量,就可以表示机器人下一步该怎么动。

也可以直接输出关节空间动作,比如:

Δq1, Δq2, Δq3, Δq4, Δq5, Δq6, gripper

这种方式更接近底层控制,但跨机器人泛化会更困难。不同机械臂的关节数量、结构和运动范围都可能不同,同一个关节增量在不同机器人上的意义并不一样。

还有一种常见做法,是一次输出未来一小段动作,也就是 action chunk:

a_t, a_{t+1}, a_{t+2}, ..., a_{t+H}

这里的每个 a 都是一帧动作,整段动作表示未来一小段时间内机器人应该如何运动。

基于这些定义,action head 的设计有几种不同的思路。

把动作当成 token

大语言模型本来就是预测 token 的。输入一句话,模型预测下一个词;输入一段上下文,模型继续生成后面的内容。那么能不能把机器人动作也离散化,让模型像预测文字一样预测动作?

比如原本连续的动作是:

Δx = 0.012 Δy = 0.005 Δz = 0.000

可以先把每个维度离散成若干区间,再映射成 token:

MOVE_X_128 MOVE_Y_096 MOVE_Z_120

这样一来,动作就变成了模型可以处理的序列。训练时,模型看到图像、语言指令和历史状态,学习预测下一组动作 token;执行时,再把这些 token 解码回连续控制量。

这种方法的好处是统一。语言 token、图像 token、动作 token 可以放在同一个序列建模框架里,比较容易复用 VLM 或大语言模型的训练方式。但它也有问题。机器人动作本来是连续的,离散化之后会损失精度。区间太粗,动作不够细;区间太细,token 数量又会膨胀,学习难度变大。

所以,动作 token 化适合做大规模统一建模,但不一定适合所有高精度控制场景。

回归连续动作

另一种更接近传统机器人学习的方法,是让 action head 直接输出连续动作向量。

这时,前面的视觉语言模块负责提取任务相关特征,action head 接在后面,输出一个数值向量:

图像 + 语言指令 → VLM hidden state → MLP → 连续动作

如果动作是 7 维的,action head 最后一层就输出 7 个数。如果要输出未来 10 步动作,就输出 10 × 7 个数。

这种设计简单直接,动作空间天然连续,不需要离散化。对于固定机械臂、固定相机、固定工作台这类场景,连续动作回归是一个很容易落地的方案。但它也有局限。机器人动作往往不是单一答案。比如“拿起杯子”,机器人可以从左侧接近,也可以从右侧接近;可以先移动到物体上方再下降,也可以斜着靠近。多种动作路线都可能合理。

如果只用简单回归,模型可能学到几种动作的平均值,而这个平均动作反而不一定可执行。这也是很多方法转向生成式动作建模的原因。

生成一段动作

真实机器人控制里,一个重要经验是:只预测下一步动作,容易抖动;预测未来一段动作,执行会更稳定。这就是 action chunk 的思路。

模型不再只输出当前时刻的一个动作:

a_t

而是输出未来一小段时间的动作序列:

a_t, a_{t+1}, a_{t+2}, ..., a_{t+H}

比如抓取红色方块时,模型可以一次生成未来 1 秒内的动作趋势:先向目标靠近,再微调高度,再闭合夹爪。不过,机器人通常不会把整段动作一次性执行到底,而是采用滚动更新的方式:先执行前几步,然后重新观察环境,重新生成下一段动作。

这有点像滚动规划。模型每次根据当前图像和状态预测未来一小段轨迹,真正执行时只执行开头部分,再根据新状态继续修正。这样做动作更平滑,短期意图更清楚,也更容易在执行过程中纠偏。

扩散 / flow matching

如果 action head 只是一个 MLP,它输出的通常是一个确定动作。输入同样的图像和语言,输出基本就是同一个结果。

但机器人操作经常存在多种合理解。比如抓一个方块,可以从正面抓,也可以从侧面抓;可以绕开障碍物,也可以直接接近。只输出一个确定结果,有时会限制模型表达能力。

扩散模型和 flow matching 的引入,就是为了解决这类问题。可以简单理解为:模型不是直接一步算出动作,而是从一个随机动作序列开始,逐步把它变成一个合理的动作序列。

随机动作轨迹 → 逐步修正 → 可执行动作轨迹

这个生成过程会受到图像、语言指令和机器人状态的约束。也就是说,动作不是凭空生成的,而是根据当前任务上下文生成的。

这类方法的优势是能表达更复杂的动作分布。它不是简单给出一个平均动作,而是可以学习人类示教中多样化的动作模式。对于灵巧操作、双臂协作、接触丰富的任务,这一点尤其重要。

action head 具体要输入什么?

一般来说,至少有四类输入。

第一类是视觉特征。机器人需要知道目标物体在哪里,障碍物在哪里,场景发生了什么变化。

第二类是语言特征。语言指令决定任务目标。同样是桌面上的方块和碗,“放进碗里”和“推到碗旁边”对应完全不同的动作。

第三类是本体状态,也就是 proprioception。包括关节角度、末端位置、夹爪状态、速度等。机器人不仅要知道外部世界,还要知道自己当前在哪里。

第四类是历史信息。有些任务只看当前一帧图像并不够。比如夹爪现在闭合了,是已经抓住物体,还是刚准备抓?这需要结合过去几帧状态判断。

所以,一个完整的 action head 可以写成:

action_head( visual_features, language_features, robot_state, history ) → actions

这里的 actions 可以是下一步动作,也可以是一段未来动作;可以是离散 token,也可以是连续向量;可以由 MLP 直接输出,也可以由扩散模型或 flow matching 生成。

设计一个简单的 action head

任务是桌面机械臂抓取。输入是相机图像、语言指令和机器人当前状态。输出是末端执行器未来 10 步动作,每一步包含 7 个维度:

Δx, Δy, Δz, Δroll, Δpitch, Δyaw, gripper

一个简化设计可以是:

图像 → Vision Encoder

语言 → Language Encoder

机器人状态 → State Encoder

三类特征融合 → Transformer / MLP

输出未来 10 步动作 → 10 × 7

训练数据来自人类遥操作或脚本生成的示教轨迹。每条数据包括当前图像、语言指令、机器人状态,以及接下来一段时间的真实动作。训练目标就是让模型预测的动作序列尽量接近示教动作。

执行时,机器人先观察当前场景,模型生成未来 10 步动作。控制器只执行前几步,然后重新拍图、重新读取状态、重新生成下一段动作。这样就形成了一个闭环过程。也就完成了 action head 的功能。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进