
第一次调试机器人抓取任务时最让我崩溃的瞬间不是机械臂突然乱动而是模型明明认出了红色杯子也完全听懂了“把红色杯子放到托盘上”这句指令最后输出的轨迹却直接穿过杯子底部。问题不出在视觉模型也不出在语言模型而是出在整条链路被拆成了三段视觉模块给目标框语言模块解析指令规划模块再单独算运动轨迹。每一段的小误差都会在后端被无限放大联调起来非常痛苦。后来我们换了一个思路不再把感知、推理和控制做成三个独立模块而是把所有输入输出统一成一串离散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统一自回归预测”这条链路跑通。等你在小规模任务上调通了稳定输出再往更复杂、更多自由度的真机场景扩展。这条技术路线的瓶颈往往不再模型容量而在数据质量、离散化设计和工程链条的稳定程度。把基础问题先解决掉后面的扩张会顺利很多。