news 2026/10/21 10:16:44

自回归离散化预训练:统一具身VLM推理与机器人动作生成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
自回归离散化预训练:统一具身VLM推理与机器人动作生成

第一次调试机器人抓取任务时,最让我崩溃的瞬间不是机械臂突然乱动,而是模型明明认出了红色杯子,也完全听懂了“把红色杯子放到托盘上”这句指令,最后输出的轨迹却直接穿过杯子底部。问题不出在视觉模型,也不出在语言模型,而是出在整条链路被拆成了三段:视觉模块给目标框,语言模块解析指令,规划模块再单独算运动轨迹。每一段的小误差都会在后端被无限放大,联调起来非常痛苦。

后来我们换了一个思路:不再把感知、推理和控制做成三个独立模块,而是把所有输入输出统一成一串离散Token,交给一个自回归Transformer直接从图像和文本预测动作序列。这就是“自回归离散化预训练下统一的具身VLM推理与机器人动作”这套方案的核心形态。简单说,图像变成视觉Token,指令变成文本Token,机械臂的真实动作也被离散成动作Token,三种Token拼在一起,用语言模型的预测方式去训练和推理。

这篇文章想把这些事情讲清楚:为什么动作要被离散化,为什么自回归建模能扛起具身推理和动作生成,训练该怎么做,部署时有哪些坑。适合正在做具身智能、机器人学习、多模态大模型的工程师和研究者参考。

1. 整体设计与思路拆解

1.1 模块化机器人流程的痛点

传统的机器人操作流程一般是这样的:感知模块检测目标、语言模块理解指令、状态机或运动规划模块生成轨迹、底层控制器跟踪轨迹。每个模块都有自己独立的数据格式和接口,模块之间靠坐标、置信度、语义标签这类中间表示通信。听起来合理,实际联调时你很快会发现,每个模块的误差是叠加的。

比如视觉识别误差一个像素,转换到机械臂基坐标系下可能就有几毫米偏差。语言模块对指令的解析一旦有歧义,下游规划根本无从区分。运动规划模块又很保守,遇到动态摘取场景经常找不到路径。我们在实机上反复调参,最后意识到问题出在目标函数不统一:感知的目标是“识别对”,语言的目标是“理解对”,控制的目标是“执行稳”,三者没有共同优化信号。

统一具身VLM的做法是放弃中间表示,让一个模型直接从原始传感器输入和任务指令回归到动作输出。图像编码器和语言编码器负责把信息压缩,动作解码器负责把预测结果映射成控制信号,梯度从动作误差一路回传到视觉和语言特征。这样一来,感知错误可以用执行结果来纠正,语言歧义也能通过交互信息来消解。

1.2 为什么把动作也当作“语言”来预测

拿到这个思路后,我们第一个要回答的问题是:动作信号必须变成什么形式才能和视觉、语言放进去同一个模型?视觉可以用patch级Token,文本可以用BPE Token,动作是连续高维向量,直接做回归的话,模型输出层要和分类任务打架。

解决办法是把连续动作离散成有限的类别。机械臂的一个关节角度、末端位姿的速度增量和夹爪开合状态,都可以映射到对应的离散区间。离散化后的动作序列可以和文本Token一样作为自回归的预测目标,模型每一步输出的是一个动作Token的类别分布,而不是连续的数值。这种处理让整个模型的训练目标变成一个多类别的交叉熵问题,工程上稳定很多。

自回归的好处在于它天然匹配“从感知到行动”的时间结构。模型先根据当前的图像和指令生成推理Token,再一步步预测未来的动作Token。每一步生成的Token都会作为下一帧预测的条件,相当于模型自己维护了一个关于环境和任务状态的隐式信念。相比同时输出整条轨迹的做法,这种方式更容易建模多步依赖,也更贴近机器人逐帧控制的实际节奏。

1.3 自回归离散化预训练的整体路线

整体路线分为两条主线。第一条线是按照语言模型的范式做大规模预训练:收集海量的图像文本数据,让模型学会把视觉内容和文化信息对齐。此时动作Token还没被激活,模型先掌握“看”和“说”的基本能力。第二条线是机器人数据微调:用人工遥操作、自动巡航等方式采集的机器人操作数据,将视觉、文本、动作序列统一构成训练样例,让模型把视觉语言理解转化为动作分布。

预训练阶段我们保留了视觉Token和文本Token的强表示能力,微调阶段新增动作Token,并和语言Token一样参与自回归预测。这样,机器人中间推理过程可以以自然语言Token的形式写在动作序列之前,形成一条“看到目标—推理步骤—执行动作”的完整序列。模型既具备通用视觉语言知识,又能在执行任务时用语言做显式推理,再用动作Token落地执行。

这套路线最大的优势是工程复用。主干Transformer结构不变,预训练目标和微调目标几乎是同一套交叉熵损失,只是数据分布和Token词典不同。我们在实际项目中复用了一套成熟的文本生成框架,只改数据侧和处理逻辑就完成了整套具身VLM训练,这也是它非常适合团队快速上手的点。

2. 核心细节解析与实操要点

2.1 视觉编码:图像如何变成离散Token

视觉输入要进入Transformer序列,我们采用的是patch级切分加离散化。一张固定分辨率图像会被切成一堆小块,每个小块经过视觉encoder变成特征向量,再通过一个预先训练好的向量量化模块映射到离散码本。用到的量化方式和文本BPE完全不同,图像Token实际上是一组离散索引,比如196个块对应196个索引。

实操中有一点需要特别注意:预训练图像Token编码器时,不要只追求重建质量。重建质量高只能说明图像压缩得好,不代表语义信息丰富。我们在选择视觉Token的时候,会额外加入语义对齐损失,让视觉Token和对应的文本描述拉近。这个细节决定了后续模型对目标的分类能力。

部署时图像的输入分辨率需要兼顾效率和精度。分辨率太低,目标识别和空间位置估算都会变差;分辨率太高,视觉Token数量暴增,自回归推理延迟变大。我们在实机上使用的视觉Token数量大约在196到576之间,既保留了足够的空间信息,又不会让序列过长。

2.2 动作离散化:如何把连续控制信号变成Token

动作离散化是这套方案里决定成败的细节。我们最初犯过一个错误,直接对关节角度做等距分桶,每维映射到256个bin。结果模型训练很快,但实际执行时末端误差大得离谱。原因是7自由度关节角度的微小偏差在正运动学转换后会被放大,尤其靠近基座的关节角度误差对末端位置影响很严重。

更合理的做法是结合动作表征空间。一种常见方案是用一个小的动作编码器对一整段动作序列做压缩,学出一个动作码本,每个码字对应一段短时运动模式,模型预测的是运动模式索引而不是单帧关节角。另一种更轻量的方案是预测相对动作增量,同时把关节空间和笛卡尔空间分开离散化:关节角用粗粒度,笛卡尔位姿增量用更细粒度。

动作频率也要仔细选择。10Hz的控制频率下,模型要预测未来大概两秒的动作序列,就需要生成约20个动作Token。如果每个动作Token包含7个关节和1个夹爪,每个维度单独离散,序列会非常长。所以更倾向于每条动作帧用一个复合Token表示,先把多维动作编码成一个低维索引,再让模型预测索引。这样既控制了序列长度,又保留了动作维度的协同性。

2.3 统一序列的拼接与注意力掩码

统一序列是“一个模型处理所有模态”的关键。我们在实践中采用这样的拼接顺序:

图像Token放最前面,表示当前观测;随后是系统指令Token,告诉模型“你是一个机器人控制模型”;然后是用户任务指令Token;接着是推理Token,用自然语言写出执行计划和判断;最后是动作Token序列。这种排列让模型在生成动作时,可以同时看到视觉上下文、任务指令和自己刚刚生成过的推理内容,信息逐步累积。

需要特别注意的是序列中的Mask机制。我们并不需要对所有Token计算损失。图像Token只是输入条件,不需要被预测;系统指令和用户指令已经是给定的Prompt,也不需要反向传播重建。真正需要监督的只有两类Token:一是推理过程中的关键步骤Token,二是具体的动作Token。所以在计算交叉熵损失时,要把非预测位置的标签设为忽略值,只对目标位置的Token计算梯度。

注意力掩码上采用标准的因果掩码即可。当前Token位置只能看到前面的Token,看不到后面内容,这保证了推理时的行为一致性。如果是离线数据,可以通过输入右侧Padding来对齐Batch,推理时则先填完整段前缀,再自回归生成动作。

# 伪代码:统一序列拼接 seq = [] seq += visual_encoder.get_visual_tokens(image) # 视觉 Token seq += tokenizer.encode("[SYS] 你是一个机器人控制模型。") seq += tokenizer.encode("把红色杯子放到托盘上。") seq += tokenizer.encode("第一步,定位红色杯子;第二步,夹取;第三步,移动到托盘上方。") seq += action_encoder.encode(action_sequence) # 动作 Token labels = [-100] * len(prefix) labels += [token_id for token_id in action_token_ids]

2.4 损失函数与训练目标设置

统一模型的目标可以看成是最大似然估计:给定前缀序列,最大化目标Token的条件概率。因为Token是离散的,我们用标准的交叉熵损失。不过因为只有部分位置需要计算损失,所以要在数据构造阶段就把标签序列设置好。

如果在推理前显式加入推理Token,建议对推理Token也计算损失,并且适当调大它们在总损失里的权重。否则模型会把推理当成装饰,生成一堆文字但不参与实际动作决策。我们曾经试过完全忽略推理Token损失,结果模型确实会生成类似“先抓把手”的文字,但机械臂动作却完全不管文字内容,推理和动作之间出现了明显的语义断裂。

训练中还需要处理类别不平衡问题。动作Token分布天然不平衡,比如“保持不动”这类零动作状态占比很高,如果不做处理,模型会倾向于输出默认动作。可以通过上采样接触任务数据、调整动作Token类别权重、或者在损失中加入Focal Loss机制来缓解。实践下来,最简单的有效做法是限制“零动作”样本在Batch中的比例,而不是只靠损失加权。

3. 实操过程与核心环节实现

3.1 数据准备:多源数据清洗与采样

统一模型最需要的是成对的观测、指令、动作序列。数据来源大致有三类:真实机械臂遥操作数据、仿真环境自动生成数据、以及互联网图像文本对。真实遥操作轨迹最可靠,但成本高;仿真数据可以大规模生成,但存在域差;互联网数据能提供丰富的语义理解能力,但缺少动作监督。

我们在实际项目中按比例混合数据:大约20%的真实机器人轨迹,50%的仿真操作数据,30%的互联网图像文本对。混合前必须做两件事:统一时间戳和统一坐标系。图像和动作数据如果没有严格同步,模型会在时间上产生幻觉,看到这一帧图像,却输出了上一帧的动作。为此我们在采集端加了硬件同步,并写了一个脚本对所有样本重新插值到固定频率。

采样时,每条样本的长度也要控制。上下文窗口有限,图像Token占掉了一部分,留给动作Token的空间不多。我们的策略是把一段长轨迹以固定窗口切成长度为20到30个动作帧的样本。如果任务特别长,就把前序动作作为历史信息输入进来,而不是每次都从第一帧开始。这样既保证了上下文完整,又不会把序列撑爆。

3.2 预训练阶段:先从看听说到动手

预训练阶段我们不接触动作数据,主要做的是视觉语言对齐。训练数据基本都是图像文本对:图像字幕、视觉问答、目标描述、空间关系推理。目标是让模型能够准确地把图像内容转成语言表达,同时把语义理解和空间推理能力沉淀到参数里。

这个阶段用的是标准的自回归语言建模目标,但输入里会插入视觉Token。为了让视觉Token与文本Token的位置编码兼容,我们专门设计了相对位置关系:视觉Token本身是一组二维Patch,在展开成序列后,位置编码要能保留空间邻居关系。简单做法是给视觉Token单独加一组可学习的绝对位置编码,但在性能上不如二维相对位置编码。我们选用了后者,明显提升了空间关系任务的表现。

预训练常用学习率一般在1e-4到3e-4之间,Batch Size需要根据显存调整。上下文长度建议做到1024或2048。我们发现模型在预训练阶段如果只看短序列,微调时很难适应长序列的机器人数据,所以预训练数据里要混入一定比例的长文本样本,把序列长度稳拉上去。

预训练到底需要多少步没有统一标准,但有一个可测量的指标:视觉问答准确率和目标空间位置预测误差。当这两项趋于稳定后,再去接机器人数据微调,能明显感觉到动作Token的学习起点更高。从零直接训练机器人数据则容易陷入局部最优,动作出来的成功率会低不少。

3.3 机器人数据微调:行为克隆与安全约束

微调阶段要把机器人操作信号接入预训练模型。具体做法是固定视觉encoder和大部分主干层的参数,只训练动作相关模块与顶层,前期我们还会用较低的学习率逐步激活所有层。直接用全量微调很容易遗忘预训练学到的视觉语言能力,后面再想改就很麻烦。

行为克隆的损失计算已经讲过,就是对每个动作Token位置计算分类交叉熵。数据质量对微调结果的影响比想象中大。遥操作数据里如果有一段不合格的轨迹,模型不仅能学坏,还会把错误模式泛化到其他类似场景。我们在微调前对每条轨迹做了速度平滑度检查、碰撞检测和任务完成度评分,不合格的直接丢弃。

安全约束方面,模型预测的动作Token不一定都安全。我们在动作Token解码后增加了一个安全滤波器:判断目标位置是否超出工作空间、关节角度是否超限、夹爪是否碰到环境。滤波器拦截异常动作后,会退回到上一个安全动作或者进入保位模式。这个机制必须放在推理服务层,不能只靠训练数据隐含的安全倾向。

微调阶段的另一个技巧是保持混合预训练数据。我们发现如果样本里只放机器人数据,模型对指令的响应会越来越机械化,稍微换一种措辞就不执行了。所以每个Batch中会混入大约30%的图像文本任务数据,让模型维持语言和视觉的泛化能力。这个比例可以根据实际表现调整,但不要低于20%。

3.4 推理部署:从Token生成到真实动作

部署时我们不是直接把整个动作轨迹一次性生成,而是采用滚动预测方式。先采集当前图像,拼接固定指令前缀,让模型生成一小段推理Token和动作Token,然后解码出第一个动作帧并发送给底层控制器。机械臂执行该动作的同时,下一帧图像到达,再进行下一轮预测。

这样做的好处是能实时响应环境变化。如果目标是移动的,模型每一轮都能根据最新的图像调整动作。但代价是推理延迟必须足够低,整个流水线得在第二个动作帧准备好之前完成。通常我们给视觉编码、模型推理、动作解码和安全检查总计留出100毫秒左右,才能和底层控制器配合好。

推理时的Token解码策略也会直接影响实际动作质量。贪心解码最稳定,适合精确控制;采样解码会增加随机性,但有时能探索出更多可行路径。我们最终采用的是低温度采样,温度设在0.1到0.3之间,既保住了稳定性,又保留了少量多样性。动作Token解码后还要做个低通滤波,把相邻两步之间的突变平滑掉,避免机械臂出现抖动。

推理服务端到端的延迟优化也是一块硬骨头。视觉Token推理可以提前做KV Cache缓存,指令前缀Token也可以提前预处理,只有动作Token生成和下一帧图像Token更新需要逐帧计算。我们在实际系统中用了提前批推理和异步IO,将整体单次推理延迟压到了70毫秒左右。

3.5 训练与部署的关键参数

阶段学习率批大小上下文长度损失权重主要数据
视觉语言预训练2e-42562048文本Token: 1.0图像文本对
机器人数据微调1e-5641024推理Token: 0.6, 动作Token: 1.0机器人轨迹混合数据
策略微调5e-632512动作Token: 1.2目标任务数据

参数选择没有绝对标准。上面这组参数是我们在某个机械臂平台上反复调出来的,如果你的模型规模和数据量不同,学习率可以按比例调整。总的原则是:预训练阶段用大学习率快速收敛,微调阶段用小学习率保护已有能力,策略微调阶段再进一步缩小学习率提升稳定性。

4. 常见问题与排查技巧实录

4.1 动作离散化粒度不合适导致精度不足

这是最常遇到的问题。动作Token的离散bin数设少了,模型学得快但精度不够;bin数设多了,分类难度上升,模型容易在相邻bin之间反复横跳。我们第一次用每维256个bin,末端执行时误差超过两厘米,抓取小物体直接失败。

后来改成每维1024个bin,精度明显提升,但训练难度也上去了。折中方案是先用256个bin做预训练,再用1024个bin在目标数据集上做短期微调,相当于用低分辨率学宏观行为,再用高分辨率精调局部细节。另外可以尝试只对末端位姿使用高分辨率离散化,对关节角使用低分辨率,重点关注最终执行效果。

4.2 模型输出动作抖动与乱跳

动作Token序列在时间上如果频繁在相邻bin之间切换,解码出来的连续动作就会抖动。即使低通滤波能压制一部分,机器人任务里高频抖动依然会导致夹爪定位不稳。

检查思路是先区分是数据问题还是模型问题。我们把训练数据里的动作序列做了差分统计,发现不少遥操作数据本身就存在高频抖动,这会在训练时被模型原样学走。所以先对训练数据做平滑处理,再检查模型输出。推理侧还可以把温度调低,减少随机采样导致的bin跳变。

4.3 微调后视觉语言能力明显退化

全量微调会让模型过度拟合机器人任务,忘记预训练时学会的通用视觉语言能力。典型表现是换个场景、换种指令措辞后,模型动作成功率和语义理解明显变差。

建议采用LoRA或Adapter方式微调,只更新一部分低秩参数。我们在真实项目里用LoRA微调后,机器人动作成功率提升了约12%,同时视觉问答能力几乎没有退化。还有一个很有效的技巧是分层解冻:第一步只训练动作Token相关模块,第二步再解冻部分Transformer层,最后再全量训练一小段时间。每一步都要评估视觉语言基准指标,发现掉点就退回上一步。

4.4 长序列训练时的内存与速度问题

统一序列不长,但一张图加一句话加几十个动作Token,总量也能轻松突破一千多Token。如果还用标准多头自注意力,显存消耗非常快,训练速度更是惨不忍睹。

我们在训练和推理两端都做了优化。训练端开启梯度检查点、混合精度和Flash Attention,把每样本显存占用降了差不多一半。推理端利用KV Cache缓存之前计算的Key和Value,避免每次生成动作Token都重新计算前面的注意力。另外把图像Token数量动态裁剪,在不影响任务成功率的前提下,该省的空间都要省。

4.5 失败案例速查表

现象可能原因快速处理
动作精度差离散化bin数太少增大bin数,或细化末端位姿
输出抖动数据本身有高频噪声训练数据先平滑,推理降低温度
不执行指令微调数据里指令风格太单一混合多样指令,减少过拟合
视觉语义退化全量微调覆盖预训练知识使用LoRA或冻结底层参数
训练显存爆掉序列过长且未开优化开启梯度检查点和Flash Attention
动作总是同一个默认值零动作样本比例过高上采样接触类任务,限制零动作比例
推理延迟过高动作Token生成太慢缓存前缀KV,滚动推理,缩短视觉Token

最后再分享一个小技巧。如果你刚开始做这个方向,不要急着上复杂数据集和全尺寸模型。先用一个自由度较少的机械臂,比如四轴的模拟环境,把“图像Token、指令Token、动作Token统一自回归预测”这条链路跑通。等你在小规模任务上调通了稳定输出,再往更复杂、更多自由度的真机场景扩展。这条技术路线的瓶颈往往不再模型容量,而在数据质量、离散化设计和工程链条的稳定程度。把基础问题先解决掉,后面的扩张会顺利很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 10:16:44

agent-skills:打造可复用技能库,破解Agent开发效率难题

做Agent开发做了差不多一年,我发现自己反复在做同一件很蠢的事情:换一个项目,就把上一个项目里写过的工具函数、调用流程和提示词重新敲一遍。直到我把这些散落的东西整理成一个叫“agent-skills”的可复用技能库之后,开发效率和效…

作者头像 李华
网站建设 2026/10/21 10:16:30

YOLOv5端侧部署实战:torch转ONNX再转ncnn全流程与避坑指南

1. 为什么要在 YOLOv5 上折腾 torch→onnx→ncnn 这条链路 做过端侧部署的朋友大概率都经历过这个场景:模型在服务器上用 PyTorch 训练得好好的,mAP 也漂亮,但一到手机、嵌入式板子或者边缘设备上就抓瞎——PyTorch 那套运行时太重&#xff0…

作者头像 李华
网站建设 2026/10/21 10:15:15

ArtCraft手作进阶:从材料工具到创作流程的完整方法论

开头第一段我已经想好了,就围绕这个项目的定位和受众来写。开头需要自然融入ArtCraft,讲清楚它是什么、能做什么、适合谁。接下来按五个大章节展开,一个章节大约1500到2000字,全文预计在九千字左右,这样才能保证信息密…

作者头像 李华
网站建设 2026/10/21 10:14:19

SDFoam:用可微光栅化替代NeRF体渲染,实现快速三维重建与网格提取

老读者应该知道我最近一直在折腾多视角三维重建这条线。手头有一组固定相机位拍的物件照片,想把它变成能直接进渲染引擎的三角网格。按常规流程走一遍之后,最大的感受是:NeRF家族在新视角合成上确实惊艳,可一旦你要的是“能拖进Bl…

作者头像 李华
网站建设 2026/10/21 10:14:06

前端可视化设计器从零拆解:Canvas 交互、坐标变换与撤销重做

搞了那么多年的前端,我最怕听到的一句话就是“帮我在系统里加个画流程图的功能”。刚开始我以为这就是个简单的页面,真正做进去才发现,diagram-design这件事,往小里说是画几个方框几条线,往大里说,它牵扯到…

作者头像 李华
网站建设 2026/10/21 10:13:44

智能数字营销平台架构:隐私合规与增强技术实战解析

2024年做智能数字营销平台的架构,说实话,最头疼的早就不再是并发量、响应延迟或者推荐算法准不准这类经典性能问题了。合规和数据隐私,才是真正能让你半夜从床上弹起来的压力源。你可能花三个月精心设计的用户画像模型,因为一个地…

作者头像 李华