笔记 | 从语言指令到机器人动作:OpenVLA 论文拆解及对启元开发的启发(整理分享)

刷到一个挺有意思的话题,结合自己之前的经验,整理了一下核心要点。

读 OpenVLA 时,我最想弄清楚的是:一张相机图像和一句指令,经过模型后究竟变成什么,离机器人能执行的动作还差几步?顺着模型结构、动作表示和实验条件看下来,输出 token 与机器人控制接口之间还要一层明确的适配。

OpenVLA 由 Stanford、UC Berkeley、Toyota Research Institute、Google DeepMind、MIT 等机构的研究者共同完成,论文初版发表于 2024 年 6 月,以下按 arXiv v3(2024 年 9 月 5 日更新)展开。论文和代码公开在 arXiv v3 与 GitHub。我没有实体机器人,因此不会把论文里的 WidowX、Franka、Google Robot 或 LIBERO 结果写成启元 Q1 的实测;与 Q1 的部分只讨论公开接口带来的工程启发。

图 1:Moo Jin Kim 等作者在 OpenVLA 论文 v3 中发布的 Figure 2,按 CC BY 4.0 许可用。图中的 7D Robot Action 属于论文实验定义,不是 Q1 的消息格式。

论文要解决的难题:机器人策略为什么难以迁移

很多机器人策略在训练过的任务上可以干活,换一个物体、摆放位置、背景或语言说法,表现就会明显下降。论文把原因归结为两类不足:机器人演示数据规模和多样性有限;已有通用模型往往闭源,研究者难以看到训练数据、模型结构和适配办法。

OpenVLA 的思路是把视觉语言模型的先验和大规模机器人演示结合起来。视觉语言模型已经从互联网图像和文本中学到了一部分物体、场景与语言关系,机器人数据再把这种关系约束到“下一步应该怎样移动”上。论文把机器人动作也放进语言模型的 token 预测框架中,模型输出的是动作 token,而不是先生成一段计划再交给另一个控制器。

模型训练的目标,是在特定数据表示和动作空间里预测下一组动作 token。离开这套表示,论文里的泛化结果就不能直接等同于“换一台机器人也能接上”。

模型结构:视觉特征先对齐,再让语言模型预测动作

OpenVLA 建立在 Prismatic-7B 视觉语言模型之上。论文描述的骨干由三部分组成:约 600M 参数的视觉编码器、一个两层 MLP projector,以及 Llama 2 7B 语言模型。

视觉编码器不是单一路径。输入图像会分别经过 SigLIP 和 DINOv2,两个编码器的特征按通道拼接。论文给出的解释是,SigLIP 更偏向视觉语义,DINOv2 的特征有助于保留空间信息;对机器人来说,清楚“这是一个杯子”还不够,还要判断它在画面中的位置和形状关系。拼接后的视觉特征经过 projector 映射到语言模型的输入空间,再与任务指令一起送入 Llama 2。

论文 Figure 2 的输入是一张观测图像和一条自然语言指令,例如“把茄子放进碗里”。图里的动作可以拆成末端位置变化 Δx(3 维)、姿态变化 Δθ(3 维)和夹爪量 ΔGrip(1 维),合计 7 维。它是论文操控任务采用的动作表示,不能脱离目标机器人直接解释成 Q1 的前进、横移或角速度字段。这个差异是后面讨论启元开发时最要守住的边界。

关键设计:把连续动作改写成语言模型能预测的 token

机器人动作通常是连续数值,语言模型输出的却是离散 token。OpenVLA 的处理方式是对每一个动作维度单独量化:先统计训练数据中该维度动作的第 1 和第 99 分位数,再把这个范围均匀分成 256 个 bins。这样做可以减弱少量异常大动作对量化精度的影响。每个动作维度最后变成一个 0 到 255 之间的整数。

Llama tokenizer 本身没有为 256 个动作类别预留足够的新增 token,论文采取了一个直接的工程处理:把词表中用频率最低的最后 256 个 token 改作动作 token。完成编码后,模型继续用 next-token prediction 训练,但交叉熵只在动作 token 上计算。

部署端接到 token 后还要反量化,再按目标机器人的单位、坐标系和控制周期解释动作,并执行安全限幅。动作 token 属于模型接口,机器人侧的消息格式仍要单独适配。

动作量化也把数据分布带进了模型接口。目标机器人数据范围若与训练数据差得很大,沿用原来的分位数区间可能让有效动作挤在少数 bins;大量停顿或异常值也会改变各区间的分辨率。论文在数据采集建议中提到动作频率、停顿和场景覆盖,这些都不只是训练集整理问题。

970k 条演示背后的复现成本

OpenVLA 使用 Open X-Embodiment 数据中的多种机器人演示,最终训练集约有 970k 条真实机器人轨迹。作者对数据做了清洗和混合,目标是让输入输出空间尽量一致,同时保留不同机器人形态、任务和场景的多样性。最终训练跑了 27 个 epoch,论文记录的完整训练使用 64 张 A100 GPU 持续 14 天,总计约 21,500 A100-hours,batch size 为 2048。

这组数字放在模型效果旁边看,比较容易判断开源降低了哪一部分门槛:代码、权重和微调脚本可以拿到,从头复现预训练仍要 64 张 A100 跑两周。个人开发者更现实的入口是加载已有 checkpoint,再用目标机器人的演示数据做参数高效微调。

官方仓库提供 LoRA 微调、全量微调和远程推理服务脚本。README 建议用目标领域的演示数据微调,并提醒模型开箱表现主要落在训练数据覆盖的领域。预训练带来迁移起点,目标机器人上的数据和验证仍然要补齐。

实验结果怎样读:平均分数不能替代任务拆解

论文摘要报告,在 29 个任务和多种机器人形态上,OpenVLA 的任务成功率比 55B 参数的 RT-2-X 高 16.5 个百分点。摘要另称,在多个物体、要语言落地的多任务设置中,OpenVLA 比从头训练的 Diffusion Policy 高 20.4%;原文没有在这个数字旁标注“绝对百分点”,这里保留摘要口径,不自行换算。两组结果都来自论文指定的机器人、数据和评测协议,不能换算成启元 Q1 的成功率。

新机器人微调实验覆盖 Franka-Tabletop 与 Franka-DROID。作者为每项任务采集 10–150 条演示,再比较从头训练的 Diffusion Policy、Octo 和微调后的 OpenVLA。图中保留了任务场景和结果柱状图:Tabletop 的前三项是单指令任务,后几项需要根据语言指令从多个物体中选目标;DROID 部分是擦桌任务。

图 2:OpenVLA 论文 v3 Figure 5,比较 Franka-Tabletop 与 Franka-DROID 上的微调结果。图中统计汇总 129 次 rollout,其中 Franka-Tabletop 99 次、Franka-DROID 30 次;按 CC BY 4.0 许可使用。成功率是论文实验数据,不是启元 Q1 数据。

Figure 5 的总体均值中,微调后的 OpenVLA 是 63.8%,从头训练的 Diffusion Policy 是 43.4%;这个均值不是每个任务都领先。比如“把胡萝卜放进碗里”,Diffusion Policy 为 66.7%,OpenVLA 为 60.0%;“用毛巾盖住物体”一项,Octo 为 91.7%,OpenVLA 为 50.0%。我会把这张图读成“同一策略在任务类型间有取舍”,不会只摘平均分。Tabletop 与 DROID 也不是完全相同的控制条件:论文分别使用 5 Hz 和 15 Hz 的非阻塞控制器,平均值汇总了两种设置。

把结果按单项任务拆开后,我更想看作者如何定义“任务多样”。BridgeData V2 的图表把它拆成视觉、运动、物理、语义和语言落地五个维度,而不是只换桌面背景。OpenVLA 在这组 WidowX 评测中的平均成功率是 70.6%,语言落地一项是 90.0%;同一张图还把 RT-1-X、Octo 和 RT-2-X 放在一起,比较条件更容易核对。这里的平均值来自 170 次 rollout,和刚才 Franka 的 129 次 rollout、后面的 LIBERO 套件不是同一批实验。

图 3:OpenVLA 论文 v3 Figure 3,BridgeData V2 WidowX 任务与结果。图中柱状数据、任务照片和评测分类均来自论文原图,按 CC BY 4.0 许可使用。

这组评测用的是 WidowX 操作平台,图表按视觉、运动、物理、语义和语言落地五类任务给出结果。它和后面的 Google Robot 评测对应不同平台与任务集,数字不放进同一个平均值里比较。

图里的“泛化”不是一个单项能力。视觉维度涉及背景、干扰物和外观变化,运动维度关注物体位置与方向,语言落地则看模型能否按指令选对目标。对应到 Q1 的开发记录,我会把输入条件和控制接口也分别记下来,避免只留一列最终成功率。

从 WidowX 换到 Google Robot,平台从桌面机械臂换成移动操作机器人,场景和任务也随之改变。这组结果是在看另一种机器人设置下的表现,和前一组在 WidowX 上改变任务属性不是同一个变量。Google Robot 的分布外条件包含未见物体、背景或语义关系;OpenVLA 的平均成功率为 85.0%,分布内为 88.0%,分布外为 82.9%。论文在 12 个任务上各进行 5 次 rollout,样本量不大,读均值时我会把这组设置与 WidowX 结果分开。

图 4:OpenVLA 论文 v3 Figure 4,Google Robot 的分布内与分布外评测。图中数据来自论文原文,按 CC BY 4.0 许可使用;该移动操作机器人不是启元 Q1。

这组 Google Robot 结果按 12 项任务、总计 60 次 rollout 统计。它与前面的 WidowX 170 次 rollout 不是同一种评估条件,读均值时要把平台、任务和试验次数一起带上。

LIBERO 仿真结果更适合观察不同任务类型之间的差异。论文附录 E 中,OpenVLA 微调后的成功率为:LIBERO-Spatial 84.7%±0.9%,LIBERO-Object 88.4%±0.8%,LIBERO-Goal 79.2%±1.0%,LIBERO-Long 53.7%±1.3%,平均 76.5%±0.6%。评估使用 3 个随机种子,每个套件、每个种子 500 次试验。Spatial 和 Object 的成绩较高,长时序任务 Long 明显更难,这比只引用一个平均分更能说明问题。

图 5:LIBERO 均值按论文 v3 附录 E 表 12 绘制;右侧限制据论文第 6 节整理。柱状图未绘制误差范围,具体标准误见正文数据。图中结果属于论文实验,不是启元设备数据。

论文说明训练演示经过了调整,测试时仍使用 LIBERO 原有环境配置;因此这些数字是在固定基准任务和评估设置下获得的,不代表模型对所有长时序任务都有同等表现。

论文报告的差异与任务类型有关:Diffusion Policy 在单指令任务上表现较强,OpenVLA 和 Octo 在多物体、多指令任务上表现更好。我的搞懂是,视觉语言预训练有助于把指令对应到场景中的目标,但这组结果并没有证明它同时解决了所有低层轨迹和接触控制问题。

论文附录把 BridgeData V2 的任务按视觉、运动、物理、语义和语言落地分组,并给出每项任务的初始状态与完成状态。任务照片很直观:同样是“拿起或放置”,更换物体、位置、背景或指令后,模型面对的是不同的泛化维度,而不是简单换一张图片。

图 6:OpenVLA 论文 v3 Figure 7,BridgeData V2 WidowX 的任务类别与示例。图片来自论文原文,按 CC BY 4.0 许可使用。

Figure 7 展示的是 BridgeData V2 中 WidowX 的任务样例,左右小图分别对应初始状态和示例完成状态。它能帮助搞懂评估类别怎样落到具体物体和场景上;下面的 Franka 图则是另一组新机器人微调任务。

Franka-Tabletop 的六项任务把训练分布内状态与分布外状态并排展示。前三项是单指令窄任务,后三项要求根据语言从多个物体中选目标;分布外条件会改变背景、目标物体、干扰物或物体位置。图 10 讲的是 Tabletop 这六项任务,不包含 DROID 的擦桌场景。

图 7:OpenVLA 论文 v3 Figure 10,Franka-Tabletop 微调任务。图片来自论文原文,按 CC BY 4.0 许可使用;图中机械臂和任务场景属于论文实验,不是启元 Q1 实测。

Figure 10 的六个场景仍在固定的 Tabletop 设置中评估物体移动与指令选择;Figure 11 才是 DROID 上的擦桌任务。两者的场景、平台和控制器都不同,我会分开读结果,不把一组实验的初始状态照片当作同一任务的重复试次。

擦桌任务属于 Franka-DROID,不在 Figure 10 的六项 Tabletop 任务里。论文给这项任务采集了 70 条演示,目标是用刷子把三件小物体扫进簸箕。

图 8:OpenVLA 论文 v3 Figure 11,Franka-DROID 擦桌任务的分布内与分布外初始场景。原图来自论文,按 CC BY 4.0 许可使用;任务并非启元 Q1 实测。

论文附录给擦桌任务每回合最高 2 分:三件物体全部扫入簸箕得 2 分,扫入一至两件得 1 分;分布内评估 18 次,分布外评估 12 次。因此,DROID 任务的百分比包含部分得分,和 Tabletop 的二元成功率不是完全相同的统计口径。

单张图像与推理频率,是部署时绕不开的边界

OpenVLA 当前模型只接收单张图像,没有把多路图像、本体感知状态和观测历史纳入统一输入。对于需要根据速度、接触或过去几步状态做判断的任务,这个限制会直接影响策略表达能力。

完整 OpenVLA 模型以 bfloat16 推理时约需 15GB GPU 显存;论文在未启用编译、推测解码等加速的条件下,记录到 RTX 4090 上约 6Hz。Figure 6 展示多种 GPU 与精度设置下的动作输出速度。图中速度结果对应第 5.4 节实验;论文脚注说明第 5.3、5.4 节使用了较小的数据混合和仅含 SigLIP 视觉骨干的模型变体,不能把图中每个数字都当作完整预训练模型的同配置结果。

图 9:OpenVLA 论文 v3 Figure 6,横轴为 GPU 型号,纵轴为每秒动作输出数;图中比较 bfloat16、8 bit 与 4 bit。原图来自论文,按 CC BY 4.0 许可使用。

量化结果也需要连着任务分数看。第 5.4 节 Table 2 报告,在 8 项 BridgeData V2 任务、每种方案 80 次 rollout 的评估中,4-bit 的显存占用为 7.0 GB,bfloat16 为 16.8 GB;平均成绩分别为 71.9%±4.7% 和 71.3%±4.8%。这是该节模型变体和指定评测集上的结果,换到不同 GPU、模型版本或控制周期,仍需重新测量。论文也指出,OpenVLA 没有采用动作分块,高频控制数据(例如 50 Hz)会带来适配压力,数据采集建议约为 5–10 Hz。

论文讨论部分还指出,测试任务成功率通常低于 90%,不少 VLA 设计问题仍待研究。对我来说,这比单看一条最高分更能说明当前阶段:模型输出、目标平台接口和评测办法都需要分开记录。

对启元 Q1 开发的启发:先把接口边界画清楚

启元当前公开的 Q1 SDK 资料写明:Q1 SDK 指南推荐 Ubuntu 22.04、ROS 2 Humble 和 FastDDS;当前指南把 RESTful/gRPC 标为暂未支持,公开开发方式以 ROS 2 Topic 和 Service 为主。截至 2026-10-21,下载页列出的 Q1 SDK 压缩包版本为 1.0.0.0,AtomGit 指南标签为 v1.0.0。Q1 的走跑接口是 /aima/mc/locomotion/velocity,消息类型为 McLocomotionVelocity;输入源管理和当前输入源查询使用 Service。这里核对的是公开接口文档,没有用该版本 SDK 连接 Q1 实机验证。资料入口是 启元开发者社区下载页 和 Q1 SDK AtomGit 仓库。

OpenVLA 的 7D action 和 Q1 的速度消息属于不同接口。接入前至少要逐项确认动作字段与单位、坐标系、输出频率、速度限幅,以及发送端如何取得和保持输入源控制权。Q1 文档里的具体字段、频率建议和门限还要结合目标 SDK 包与固件核对。

图 10:依据 OpenVLA 论文和启元 Q1 SDK 公开资料整理的接口边界。适配层是我结合两份公开资料提出的开发建议,不代表启元已经提供 OpenVLA 插件。

没有真机时,我会先固定几组离线图像和指令,记录 token、反量化数值和动作范围;随后只做 Q1 消息层校验,检查字段、单位和序列化。适配层还要包含限幅、超时、异常值拒绝和显式急停状态,模型没有新输出时不能无限重发旧动作。等这些条件在仿真或安全状态下逐项验证后,再考虑接入真实控制链路。

Q1 的 ROS 2 Topic/Service 资料能说明动作怎样进入系统、谁拥有控制权,以及异常时可以调用哪些接口。把这些约束和模型输出一起记录,才能判断适配器是否按预期干活。

对启元开发的实际启发

OpenVLA 的 7D action 和 Q1 的走跑速度消息不是同一种控制量。接入前要逐项核对动作语义、单位、坐标系、频率、限幅和控制权,不能把模型输出直接塞进 /aima/mc/locomotion/velocity。适配层还应明确处理超时、异常值与停止状态,避免模型没有新动作时沿用旧命令。

我之前在 Ubuntu 虚拟机里构建了 Q1 SDK 的 aimdk_msgs,并运行了本地 Mock,验证 Set/Get Service 与速度 Topic 的 ROS 2 通信。这个结果只证明本机消息链路可用,Mock 日志也明确写着它不连接 Q1。它正好适合作为适配前的一道检查:先验证字段、类型和收发逻辑,再把仿真状态或模型输出接进来;至于运控板仲裁和真机安全效果,还要由设备与目标固件验证。复现代码在 AtomGit:q1-interface-mock-demo。

对我来说,这篇论文最有用的部分是动作编码、数据、微调和评测条件都能逐项追问。它提供了设计验证问题的材料,但没有替 Q1 完成模型适配或实机测试。没有实体 Q1 时,我能做的是把接口映射、安全分支和仿真验证设计清楚,不把论文 benchmark 当作设备结果。

参考资料

OpenVLA 论文(arXiv:2406.09246v3)。OpenVLA 官方 GitHub 仓库。OpenVLA 项目主页。启元机器人开发者社区下载页。启元 Q1 SDK AtomGit 仓库。
Q1 SDK、仿真资源和开发实践可访问启元机器人开发者社区。

本次分享就到这里。技术这东西越研究越有意思,后续有新的收获我也会继续更新。

评论 (0)

暂无评论