前言
随着机器人动作策略预测的成熟,提升泛化能力的典型途径之一是基于预训练大语言模型的广泛知识,并添加 Policy Head。早期模型如 RoboFlamingo 使用 LSTM 或 MLP,随后出现了更成熟的 VLA 模型,如 OpenVLA 和 π0。
π0 的意义在于首次用同一套策略操作不同机器人,代表了通用机器人的核心发展方向。虽然 π0 曾延期开源,但 OpenVLA 作为其重要参考,提供了开源的视觉 - 语言 - 动作模型方案。
第一部分 OpenVLA:相当于 RT-2 的开源版
1.1 OpenVLA:第一个开源的通用 VLA 模型
1.1.1 通过 Open X-Embodiment 中 97 万机器人数据微调的 7B VLA 模型
2024 年 6 月,来自斯坦福大学、UC Berkeley、Toyota Research Institute、Google DeepMind、Physical Intelligence 及 MIT 的研究者推出了 OpenVLA。
- 论文:《OpenVLA: An Open-Source Vision-Language-Action Model》
- 项目地址:https://openvla.github.io/
- GitHub 地址:https://github.com/openvla/openvla
这是一种具有 70 亿参数的开源视觉 - 语言 - 动作模型(VLA),由一个预训练的视觉条件语言模型骨干组成,在 Open-X Embodiment 数据集中的 970k 机器人操作轨迹的大型多样数据集上进行了微调。
它支持开箱即用地控制多个机器人,并且可以通过参数高效微调快速适应新的机器人领域。
1.1.2 背景
当前机器人操作中学习得到的策略存在关键弱点,即无法超越其训练数据进行泛化。现有针对单一技能或语言指令训练的策略在面对场景干扰物或新颖物体时缺乏鲁棒性。
然而,CLIP、SigLIP 和 Llama 2 等现有的视觉和语言基础模型能够实现这些类型的泛化,这得益于其基于互联网规模的预训练数据集所捕获的先验知识。尽管在机器人领域复现如此大规模的预训练仍是一个尚未解决的难题,但这种不平衡带来了机遇:可以利用现有的视觉和语言基础模型,作为训练能泛化到超出训练数据之外的物体、场景和任务的机器人策略的核心构建模块。
为实现这一目标,现有研究已探索将预训练的语言模型和视觉 - 语言模型整合用于机器人表征学习。最近,这些模型被直接用于学习视觉 - 语言 - 动作模型(VLAs)以进行控制。
依托于在互联网规模数据上训练的强大基础模型,诸如 RT-2 等 VLA 展现出令人印象深刻的鲁棒性,并具备对新颖物体和任务的泛化能力。然而,现有 VLA 尚未广泛应用,主要有两个关键原因:
- 当前模型为闭源模型,透明度有限;
- 现有研究未提供将 VLA 部署和适配至新型机器人、环境和任务的最佳实践。
为此,作者推出了 OpenVLA,能够在多个粒度层面提取视觉特征,并在 Open-X Embodiment 数据集上进行了微调。
- 由于数据多样性的提升和新模型组件的引入,OpenVLA 在 WidowX 和 Google Robot 两种机器人形态的 29 项评测任务中,绝对成功率比之前的业界领先 VLA——拥有 550 亿参数的 RT-2-X 模型高出 16.5%。
- 作者还研究了 VLA 的高效微调策略,覆盖了从物体抓取与放置到清洁桌面等 7 项多样化操作任务。结果表明,经过微调的 OpenVLA 策略明显优于如 Octo 等微调后的预训练策略。
与基于扩散策略的从零模仿学习相比,微调后的 OpenVLA 在需要将语言与行为对齐的任务上表现出显著提升。
1.2 OpenVLA 的模型架构、训练过程、训练数据
1.2.1 模型架构 (基于 Prismatic-7B VLM):SigLIP、DinoV2、Llama 2
大多数最新的 VLM 架构一般由三部分组成:
- 一个视觉编码器,用于将图像输入映射为若干'图像 patch 嵌入';
- 一个投影器,将视觉编码器输出的嵌入映射到语言模型的输入空间;
- 一个大型语言模型 LLM 骨干。
对于 OpenVLA 而言,其基于 Prismatic-7B VLM 进行构建,包含:
- 一个 600M 参数的视觉编码器:由预训练的 SigLIP 和 DinoV2 模型组成。输入图像块会分别通过这两个编码器,随后将得到的特征向量按通道拼接。与更常用的视觉编码器如 CLIP 或 SigLIP-only 编码器相比,添加 DinoV2 特征已被证明有助于改善空间推理,这对于机器人控制尤其有帮助。
- 一个两层的小型 MLP 投影器;
- 一个 70 亿参数的 Llama 2 语言模型骨干。
至于为何基于 Prismatic-7B 构建 OpenVLA?起初,作者尝试了多种 VLM 主干。除了 Prismatic,他们还测试了微调 IDEFICS-1 和 LLaVA 以预测机器人动作。他们发现 LLaVA 和 IDEFICS-1 在只有一个物体的场景任务中表现相当,但在涉及多个物体并要求策略操控正确物体的任务中,LLaVA 展示了更强的语言基础。微调的 Prismatic VLM 策略实现了进一步的改进。作者将这种性能差异归因于融合的 SigLIP-DinoV2 主干提供的改进的空间推理能力。
对于输入图像的分辨率,作者比较了 224×224 像素和 384×384 像素输入的 VLA,但在评估中未发现性能差异,而后者训练时间是前者的三倍。因此,最终选择 224×224 像素分辨率。
对于训练轮次,典型的 LLM 或 VLM 训练最多只通过其训练数据集一到两次。相比之下,发现对于 VLA 训练来说,通过训练数据集的次数要显著增加,实际机器人性能会不断提高,直到训练动作 token 准确率超过 95%。最终训练运行通过其训练数据集完成了 27 个轮次。
对于学习率,作者在多个数量级上对 VLA 训练的学习率进行了全面搜索,使用固定学习率 2e-5 取得了最佳结果。
1.2.2 微调 Prismatic-7B VLM,使其输出机器人动作
为了训练 OpenVLA,作者对预训练的 Prismatic-7B VLM 主干进行微调,以实现机器人动作预测。
作者将动作预测问题表述为一个'视觉 - 语言'任务,其中输入的观测图像和自然语言任务指令被映射为一串预测的机器人动作。
- 为了使 VLM 的语言模型主干能够预测机器人动作,作者通过将连续的机器人动作映射到语言模型的分词器使用的离散 token,将动作表示在 LLM 的输出空间中。 类似 Brohan 等人的方法,基于下一个 token 预测技术预测动作 token,作者将机器人的每个动作维度分别离散化为 256 个区间中的一个。
- 通过这种离散化方法,作者为一个 N 维的机器人动作获得了 N 个离散整数,范围为 [0...255]。然而,OpenVLA 所用的语言骨干 Llama 分词器仅为微调时新引入的 token 预留了 100 个'特殊 token',这远不足以满足动作离散化所需的 256 个 token。 因此,作者再次选择简化方案,简单地用动作 token 覆盖 Llama 分词器词表中使用频率最低的 256 个 token(即最后 256 个 token)。 一旦动作被处理为 token 序列,OpenVLA 就采用标准的下一个 token 预测目标进行训练,仅对预测的动作 token 计算交叉熵损失。
对于每个动作维度,作者设置区间宽度,使其在训练数据中动作的第 1st 和第 99th 分位数之间均匀划分。使用分位数使得能够忽略数据中的异常动作,否则这些异常值可能会极大地扩展离散化区间,并降低动作离散化的有效精度。
1.2.3 训练数据
一方面,OpenVLA 用 Open X-Embodiment 数据集(OpenX)作为基础来策划训练数据集。完整的 OpenX 数据集由超过 70 个单独的机器人数据集组成,包含超过 200 万条机器人轨迹。
为了使在这些数据上进行训练变得可行,作者对原始数据集应用了多个步骤的数据整理:
- 所有训练数据集之间的输入、输出空间一致。为了实现这个目的,可以遵循限制训练数据集仅包含至少有一个第三人称摄像机的操作数据集,并使用单臂末端执行器控制。
- 在最终训练组合中具有平衡的 embodiments。利用 Octo 的数据混合权重来处理所有通过第一轮筛选的数据集,Octo 启发式的降低或移除多样性较低的数据集,并增大任务和场景多样性比较大的数据集的权重。
此外,作者还尝试将自 Octo 发布以来添加到 OpenX 数据集中的一些额外数据集整合到 OpenVLA 的训练混合中,包括 DROID 数据集。不过考虑到在实践中,发现 DROID 上的动作 token 准确率在整个训练过程中保持较低,故为了不影响最终模型的质量,作者在最后三分之一的训练中将 DROID 从数据混合中移除。
1.2.4 训练和推理的基础设施
最终的 OpenVLA 模型在一个由 64 个 A100 GPU 组成的集群上训练了 14 天,总计 21,500 A100 小时,使用的批量大小为 2048。
且为了方便起见,实现了一个远程 VLA 推理服务器,以允许将动作预测实时远程流式传输到机器人上——消除了需要访问强大本地计算设备来控制机器人的要求。
在推理过程中,OpenVLA 在加载为 bfloat16 精度(即未量化)的情况下需要 15GB 的 GPU 内存,并在一块 NVIDIA RTX 4090 GPU 上以大约 6Hz 的速度运行(未进行编译、推测解码或其他推理加速技巧)。
值得一提的是,作者除了提供模型之外,还发布了 OpenVLA 代码库,这是一个用于训练 VLA 模型的模块化 PyTorch 代码库。该代码库可以从在单个 GPU 上微调 VLA 扩展到在多节点 GPU 集群上训练具有十亿参数的 VLA,并支持现代大型 Transformer 模型训练的技术包括自动混合精度(AMP)、FlashAttention 和完全分片数据并行(FSDP)。而且还可以做到开箱即用,OpenVLA 代码库完全支持在 Open X 数据集上进行训练,与 HuggingFace 的 AutoModel 类集成,并支持 LoRA 微调和量化模型推理。
1.3 实验:与 RT-2、Octo、Diffusion Policy 的对比,以及 LoRA 微调
1.3.1 与 RT-2 的横向对比:除了语义泛化外,均强于 RT-2
为了进一步评估 OpenVLA 的'开箱即用'性能:作者把 OpenVLA 放到以下两个平台测试:
- 一个是来自 BridgeData V2 评估的 WidowX 机器人;
- 一个是来自 RT-1 和 RT-2 评估的移动操作机器人('Google 机器人')。
这两个平台在之前的工作中已被广泛用于评估通用机器人策略。
作者在每个环境中定义了一套全面的评估任务,涵盖各种泛化轴:如视觉(未见过的背景、干扰物体、物体的颜色/外观);运动(未见过的物体位置/方向);物理(未见过的物体大小/形状);以及语义(未见过的目标物体、指令和来自互联网的概念)泛化。
总体而言,在 Google 机器人实验中进行了 60 次展开评估。所有任务的详细分类及其与训练数据的差异在附录 B。
结果显示,RT-1-X 和 Octo 在评估任务中遇到了困难;在多个任务中,它们通常无法在五次试验中取得一次成功。另一方面,RT-2-X 和 OpenVLA 表现出强劲的性能,在五次试验中至少完成每个任务两次;这两个 VLA 策略在这个特定的评估套件中表现相当。
他们在 BridgeData V2 实验中对每种方法进行了 170 次展开评估。结果显示,OpenVLA 在大多数任务中表现最强,并且在通用策略中具有最高的总体成功率。RT-2-X 也表现良好,优于 RT-1-X 和 Octo,但不如 OpenVLA。
尽管 OpenVLA 的规模小了一个数量级(7B 对 55B 参数),从质量上看,发现 RT-2-X 和 OpenVLA 都表现出明显更强的行为稳定性。
但 RT-2-X 在语义泛化任务中取得了更高的性能,这也在预料之中,因为它使用了更大规模的互联网预训练数据,并与机器人动作数据和互联网预训练数据共同微调,以更好地保留预训练知识,而不是单独微调。
尽管在 Google 机器人评估中,在一些任务上,OpenVLA 的表现与 RT-2-X 相当,然而,在 BridgeData V2 和 Google 机器人评估的全部任务里,OpenVLA 的整体表现略胜一筹。这种性能差异可归因于多种因素的结合:为 OpenVLA 策划了一个更大的训练数据集,包含 970k 个轨迹(相比之下,RT-2-X 为 350k);OpenVLA 使用了融合的视觉编码器——SigLIP-DinoV2,该编码器结合了预训练的语义和空间特征;OpenVLA 对训练数据集进行了更仔细的清理,例如,过滤掉了 Bridge 数据集中全零的动作。
因为原始版本的 BridgeData V2 数据集包含许多全零(无操作)动作的转换。例如,在每个演示中,全零动作在第一个时间步被记录为真实动作。因此,在没有任何数据预处理的情况下,在原始数据集上训练一个高度表达的 VLA 模型导致了一个频繁预测全零动作并在评估中卡住的策略。因此,在训练 OpenVLA 模型时简单地过滤掉了每个演示中的第一个转换,这在大多数情况下足以缓解冻结行为。
考虑到由于这是一个我们无法重新训练的专有模型(例如,使用预处理过的 BridgeDataV2 数据集版本),只好通过简单地查询模型的第二最可能动作来缓解这一问题,因为第一最可能动作通常全为零,而第二最可能动作不是——而这也是 RT-2-X 模型的开发者在 Open X-Embodiment 实验中报告的 BridgeData V2 评估中应用的相同变通方法,即始终查询第二可能动作。
1.3.2 与 Diffusion Policy 的对比实验
作者还将 OpenVLA 与 Diffusion Policy、Diffusion Policy(matched) 进行比较,后者是一种与 OpenVLA 输入和输出规格匹配的 Diffusion Policy 版本。
- 此外,作者评估在目标数据集上微调的 Octo,因为它目前是支持微调的最佳通用策略 (通过其推理 API 不支持 RT-2-X 的微调)。
- 且还在相同的目标数据集上微调 OpenVLA,得到的策略称为 OpenVLA。
- 最后,作为消融实验,作者与 OpenVLA(scratch)——即 OpenVLA(从头开始) 进行比较,在该实验中,作者直接在目标机器人设置上微调基础 Prismatic VLM,而不是微调 OpenX 预训练的 OpenVLA 模型,以评估大规模机器人预训练的好处。
作者在原论文的图 5 中展示了结果。
作者发现,在针对上图的这 7 个任务中 (这 7 个任务分别是:将胡萝卜放入碗中、将玉米倒入锅中、将锅翻转为直立,将物体移动到盘子上、将物体击倒、用毛巾覆盖物体,擦拭表面):
- Diffusion Policy 的两个版本在诸如'将胡萝卜放入碗中'和'将玉米倒入锅中'这样的单一指令任务中 (single instruction tasks),与或超过了通用策略 Octo 和 OpenVLA 的竞争力。如此说明,对于较狭窄但高度灵活的任务,Diffusion Policy 仍显示出更平滑和精确的轨迹;在 Diffusion Policy 中实施的动作分块和时间平滑——action chunking and temporal smoothing,可能有助于 OpenVLA 达到同样的灵活性水平,并可能成为 OpenVLA 未来改进的一个有前途的方向。
- 但在涉及场景中多个对象并需要语言调节的更为多样化的微调任务中 (见上图右侧的 multi instruction tasks),预训练的通用策略表现更佳。比如 Octo 和 OpenVLA 的 OpenX 预训练使得模型能够更好地适应这些'语言基础至关重要的更为多样化'的任务;这点从 OpenVLA(scratch) 较低的性能中便可以看出来。
1.3.3 参数高效微调:LoRA 微调效果逼近全量微调
一般的 VLM 训练方法包括:
- 全量微调:在微调过程中更新所有权重。
- 仅微调网络的最后一层 last layer only:仅微调 OpenVLA 的 transformer 骨干的最后一层和 token 嵌入矩阵。
- 冻结视觉:冻结视觉编码器,但微调所有其他权重。
- sandwich fine-tuning:解冻视觉编码器、token 嵌入矩阵和最后一层。
- LoRA 微调:使用 Hu 等人提出的流行的 low-rank adaptation,应用于模型的所有线性层。
最终发现:
- 发现仅微调网络的最后一层或冻结视觉编码器导致性能不佳,这表明视觉特征对目标场景的进一步适应是至关重要的。
- 相比之下,'sandwich fine-tuning' 通过微调视觉编码器实现了更好的性能,并且由于不需要微调完整的 LLM 主干,它消耗更少的 GPU 内存。
- 最后,LoRA 在性能和训练内存消耗之间实现了最佳平衡,优于'sandwich fine-tuning' 并且在仅微调 1.4 % 参数的情况下匹配了完整微调的性能。
且发现 LoRA 的 rank 对策略性能的影响可以忽略不计,因此建议使用默认 rank r = 32。 总之,使用 LoRA,可以在单个 A100 GPU 上在 10-15 小时内微调 OpenVLA 到新任务上——与完整微调相比,计算减少了 8x。
最终,OpenVLA 以 bfloat16 精度保存和加载用于推理(默认方法),这将内存占用减少了一半,使能够在只有 16GB 的 GPU 上提供 OpenVLA 服务。
第二部分 (选读) Prismatic VLM
2.1 Prismatic VLM
2.1.1 Prismatic VLM
在先前的工作中,新的 VLMs 采用了一种简单的方法,将预训练视觉骨干(例如 CLIP)的 patch 特征视为可以投射到语言模型(LM)输入空间的 token。
这种'patch-as-token'的方法使得训练可以采用一个简单的目标——下一个 token 预测——并允许利用强大 LMs 的生态系统,例如 Llama-2 和 Mistral,以及有效训练它们的工具(例如,FSDP)。
这种组合推动了模型的快速发展和发布,例如 LLaVa v1.5 和 PALI-3,这些模型采用相同的基本配方,同时在预训练组件、数据或优化程序的选择等个别成分上有所不同。
不过,VLM 到底该怎么设计性能更优,换言之,哪些关键设计决策会影响 VLM 的能力和下游使用?为了回答这个问题,2024 年 2 月,来自斯坦福大学和 Toyota Research Institute 的研究者发布了一个工作《Prismatic VLMs: Investigating the Design Space of Visually-Conditioned Language Models》。
这项工作探索了开发 VLM 的四个关键设计轴:1)优化过程,2)图像处理和预训练视觉表示,3)语言模型,以及 4)围绕训练时间和数据的扩展属性。
具体而言:
- 首先,为了提供对 VLM 能力的细粒度洞察,他们编制了一个标准化的评估套件,包括来自视觉与语言文献的十二个基准。
- 其次,他们开发了一个优化的模块化代码库用于 VLM 训练,强调灵活性,使用户可以轻松替换预训练组件、优化程序、数据等。
- 第三,他们利用这些资源贡献进行有针对性的实验,探索四个关键设计轴。
且作者识别出了一些洞察;例如,发现现有工作采用的多阶段训练程序可以在不影响性能的情况下消除,从而减少 20-25 % 的计算成本。还发现融合来自不同骨干的特征的视觉骨干,如 CLIP 和 DINOv2,在各方面都能导致更高性能的 VLM。
最后,他们整合了他们的发现,并在 7B/13B 规模上训练了一系列模型 PRISMs,其严格优于最新的开放 VLM,如 InstructBLIP 和 LLaVav1.5。
2.1.2 模型架构
在模型架构上,他们采用了许多近期 VLM(如 LLaVa、Qwen-VL 和 PaLI-3)使用的通用架构。
这些架构使用一个(预训练的)视觉骨干网络将输入图像映射为一系列 patch 特征,然后将这些特征单独投影到 LM 的嵌入空间中。
形式上,一个 VLM 接收输入图像和任意序列长度 K 的文本 prompt 标记。这些输入然后被送入以下组件:
- 语言模型:最后,将序列与文本提示嵌入连接,将结果传递给语言模型。语言模型生成输出文本。
- 视觉 - 语言投影器 Vision-Language Projector:接下来,通过一个学习到的投影器将图像特征映射到一个嵌入序列。
- 视觉表示骨干:首先处理输入图像,通过视觉表示骨干网络输出一系列特征。
组合后定义一个 VLM。在训练过程中给定一个三元组,通过梯度下降最小化损失。
2.1.3 预训练数据集及训练实施
对于预训练数据集,具体使用 LLaVa v1.5 数据混合,其中包含两个用于多阶段训练管道的子集:
- 第一个子集由来自各种字幕数据集的 558K 样本混合组成。
- 而第二个子集由 665K 多模态指令调优示例组成,这些示例包括合成数据,以及来自现有视觉 - 语言训练集的示例,特别是来自 ShareGPT 的语言仅数据样本。
对于训练实施,为了得到高效且灵活的 VLM 训练代码,且能够轻松更换视觉和语言模型的骨干网络,并处理任意优化过程。
基于这些要求,作者在 PyTorch 中实现了 Prismatic VLM 的训练代码库,使用了完全分片数据并行(FSDP)和 BF16 混合精度。
- FSDP 使我们能够为单个模型组件指定精度(例如,视觉骨干网络使用 FP16,语言模型使用 BF16),实现不同硬件的可移植性,并提供最小的实现开销。
- 且遵循先前工作的可重复性实践,在训练期间固定初始化随机性和批次顺序,以及利用 TIMM 和 Hugging Face Transformers 来提供预训练模型。
为了验证 Prismatic VLM 的代码,作者在 7B 和 13B 参数规模上进行了一次 LLaVa v1.5 的同类重现。
发现 Prismatic VLM 的实现比参考的 LLaVav1.5 训练实现效率高得多:在相同硬件上进行基准测试时,观察到使用我们基于 FSDP 的实现步长时间快了 20%,这在 LLaVa 利用了优化良好的 DeepSpeed ZeRO 库的情况下是一个显著的提升。
且与其他开源代码库不同,提供了一个模块化且富有表现力的接口,可以轻松指定或添加模型组件、优化过程和数据,只需进行最少的代码更改。
2.2 实验:4 个关键设计的考量点
2.2.1 多阶段训练
许多 VLM 采用的一种普遍设计选择是包含一个两阶段的训练流程:
- 微调阶段,此时只有视觉表示被冻结,同时训练投影和 LM。
- 对齐阶段,通过单独训练随机初始化的投影器来对齐视觉和语言特征,冻结所有其他组件。
此外,现有 VLMs 中利用预训练视觉表示的另一个流行设计选择是在整个训练过程中保持视觉骨干不变。这种选择限制了在训练过程中学习改进的视觉表示以促进语言生成的潜力。
那通过微调包括视觉骨干在内的完整模型,是否有可能提高 VLM 性能?
最终发现情况并非如此,微调视觉骨干显著降低了性能,尤其是在需要细粒度空间推理的任务上,如 RefCOCO 和 OCID-Ref。
2.2.2 图像处理与视觉表示
首先,对于预训练视觉表示的选择问题上,尽管有大量在不同数据源上训练的视觉表示,CLIP 已成为几乎所有 VLM 的默认视觉表示选择。在这个实验中,作者对 CLIP、SigLIP、DINOv2 和一个标准的用于分类的预训练视觉 Transformer 进行逐一比较。
为了公平比较,使用 ViT-Large 模型变体,作者发现使用视觉 - 语言对比目标训练的骨干网络(即 CLIP, SigLIP)的性能显著优于其他选择。
虽然视觉 - 语言对比目标是解释 CLIP 和 SigLIP 优势的一个原因,另一种可能的解释是训练图像分布。CLIP 和 SigLIP 都包含来源于互联网的图像,这些图像不在 ImageNet 或 DINOv2 的预训练数据中。
其次,对于跨视觉骨干网的图像处理问题上,大多数图像的分辨率和纵横比差异很大,但大多数视觉骨干网期望固定大小的方形图像;为了解决这个问题,普遍的默认做法是将图像'调整大小并裁剪'到合适的大小。虽然这对于分类等应用通常效果良好,但对于需要全场景推理的任务来说,裁剪掉图像的一部分尤其有害。
在本次实验中,作者评估了三种不同的图像处理方案:
- 默认的'resize & crop' 方案;
- LLaVa v1.5 使用的'letterbox padding' 方案(将非正方形图像填充为正方形);
- 以及'naive resize' 方案(扭曲原始图像的纵横比,将图像压缩或拉伸为正方形)。
可以发现,虽然裁剪显然不是最佳选择,但对于 CLIP 而言,'naive resize' 方案表现最佳。对于 SigLIP,'naive resize' 和'letterbox padding' 的表现相似。总体而言,实验结果更偏向于'naive resizing'而非'letterbox padding'。
值得一提的是,关于在填充图像时天真地调整图像大小的两个推测性论点是最小化'无效像素'和分布偏移。一个 16:9 长宽比的图像被填充为正方形时,会引入大量无信息像素;改变长宽比的变形可能导致较小的偏移。结合 Vision Transformer 的固有补丁维度,天真地调整图像大小可能会保留足够的信息,使下游 LM 能够提取下游任务所需的属性。
再其次,对于缩放图像分辨率的问题上,近期 VLMs 的另一个趋势是增加输入图像分辨率,希望捕捉到细粒度的细节以提高下游性能。而作者的研究结果证实了这一假设,缩放到 336px 或 384px 带来了显著的改进,当然代价是带来计算复杂度的显著提升。
最后,对于不同视觉表示的结合问题上,在视觉领域,大量的先前研究表明,不同归纳偏差训练的不同类型的视觉表示可以提高广泛应用的性能。
受此启发,作者疑问这种趋势是否同样适用于 VLM 训练——特别是结合 DINOv2 特征与来自 CLIP 和 SigLIP 的视觉 - 语言对比特征是否能提高性能。
为了高效实现这一点,作者简单地将不同骨干网络的 patch 特征沿通道维度连接在一起,从而为每个 patch 生成相同数量的输入 patch 嵌入——只是特征维度加倍。
为此调整,作者只需将投影器(一个 2 层 MLP)的输入维度增加,几乎没有成本。且发现融合 DINOv2 和 SigLIP 特征在整体上提供了显著的提升,但 DINOv2 + CLIP 模型是一个显著的例外,其中结合 DINOv2 特征在 TextVQA 上似乎特别有害。
通过查看其余结果,还看到在定位和挑战任务上有 5-10 % 的显著提升;总体而言,DINOv2 + SigLIP 融合表示是作者尝试过的性能最佳的视觉表示,几乎没有增加参数。
根据 Kerr 等人和类似工作的假设,作者相信 DINOv2 特征提供了捕捉图像低级空间属性的特征,增强了视觉语言对比模型所捕捉的高级'语义'属性。
2.2.3 整合语言模型:是整合微调过的,还是不微调过的呢
基础模型与指令微调。指令微调(或聊天微调)是一种将基础语言模型(为下一个词预测训练的)微调为对话代理的方法,为广泛的应用提供自然的输入/输出接口。
因此,像 Vicuña 这样的指令微调模型已经成为视觉语言模型的默认骨干。不幸的是,指令微调有其缺点,会引入偏差并导致性能回退。
因此,在这个实验中,作者通过基础语言模型(Llama-2)与指令微调变体(Vicuña v1.5)的正面对比,评估指令微调语言模型骨干对下游视觉语言模型性能的影响。
发现指令微调语言模型在性能上并没有比基础语言模型带来统计上显著的改善,但在定性性能上有所不同。
具体而言,观察到指令微调语言模型导致的视觉语言模型更加冗长,易出现幻觉,并且其响应通常不够具体。
更好的语言模型是否会导致更好的视觉语言模型?
作者研究了语言模型在仅语言基准上的性能如何转化为下游视觉语言模型的性能,训练了从 Mistral v1 7B 和 Mistral Instruct v1 7B 得到的视觉语言模型,这些是最近在语言和代码基准上表现优于 Llama-2 的语言模型。
可以发现这些视觉语言模型并没有显著更高的性能——比起从 Llama-2 训练的 VLMs,这是一个更为重要的因素,故未来工作的一个令人兴奋的方向是研究语言模型预训练组合如何与 VLM 性能相关联。
仅使用语言的安全数据共同训练。
比如用于训练的 LLaVa v1.5 预训练数据集由 40 K 个来自 ShareGPT 的语言数据示例组成;这些数据由用户上传的与 OpenAI 的 ChatGPT 的多样化对话构成;关键是,该数据集中的许多示例包含有毒、不当或其他不安全的输入,以及 ChatGPT 对应的'保护'响应。
在此实验中,作者分析了在下游性能上共同训练这种仅语言数据的影响,目的是了解添加与视觉推理无关的仅语言数据是否会相对于仅在多模态数据上训练而损害性能。
最终发现去除仅语言数据仅略微提高了性能。
2.2.4 扩展属性:训练时间与数据
作者还探讨了训练时间作为训练轮数的函数的影响。与现有的 VLMs 如 PaLI 或 LLaVa 最多只进行一个轮次训练不同,作者比较了在不同轮数下训练的性能。发现单轮训练存在严重欠拟合的证据,随着训练到两轮,性能稳步提升(特别是对于需要结构化输出的任务如 RefCOCO),之后性能趋于平稳。
从而也就发现了进行两轮训练比进行一轮训练有显著的改进。
最后总结一下一系列能够简化 VLM 训练并提高下游性能的独特见解:
- 优化过程:单阶段训练在不影响下游性能的情况下减少计算成本。
- 图像处理和视觉表示:融合了 DINOv2 和 SigLIP 主干网络,通过高分辨率图像和简单的图像调整尺寸实现了强大的性能。
- 语言模型:基础语言模型(如 Llama-2)的性能与指令调优语言模型相当或更好,联合训练语言数据对于安全性非常重要。
- 扩展属性:增加多样化的数据和延长训练时间显著提升性能。
第三部分 OpenVLA 的源码剖析
整个代码仓库主要包含:
- LICENSE— 所有代码均依据 MIT 许可证发布;尽情编程。
- Makefile— 主要的 Makefile(默认情况下支持 lint 检查与自动修复);根据需求扩展。
- pyproject.toml— 完整的项目配置详情(包含依赖项),以及工具配置。
vla-scripts/— 训练、微调及部署视觉语言动作 (VLA) 的核心脚本。
prismatic — 包源;为模型加载、训练、数据预处理等方面提供核心工具。
3.1 prismatic/models
3.1.1 models/vlms/prismatic.py
// 待更
3.1.2 models/vlas/openvla.py
// 待更
3.3 prismatic/vla:动作预测
3.3.1 prismatic/vla/action_tokenizer.py
ActionTokenizer 类的主要功能是将连续的机器人动作离散化为多个维度上的 N 个区间,并将其映射到最少使用的 token 上。
decode_token_ids_to_actions 方法的主要功能是将离散的动作 token ID 转换回连续的动作值。该方法接受一个 action_token_ids 的 numpy 数组作为输入,并返回一个 numpy 数组,包含对应的连续动作值。
首先,方法通过从 self.tokenizer.vocab_size 中减去 action_token_ids 来计算离散化的动作值。这一步的目的是将 token ID 映射到一个新的索引范围内。
def decode_token_ids_to_actions(self, action_token_ids: np.ndarray) -> np.ndarray:
discretized_actions = self.tokenizer.vocab_size - action_token_ids
接下来,使用 np.clip 函数将这些离散化的动作值限制在有效的区间范围内,即 [0, self.bin_centers.shape[0] - 1]——具体而言,将小于最小值的元素设置为最小值,将大于最大值的元素设置为最大值,从而确保所有的索引都在有效范围内。
discretized_actions = np.clip(discretized_actions - 1, a_min=0, a_max=self.bin_centers.shape[0] - 1)
最后,方法返回 self.bin_centers 中对应索引的值。
return self.bin_centers[discretized_actions]
self.bin_centers 是在初始化时计算的区间中心值数组,因此返回的数组包含了对应于输入 token ID 的连续动作值。这种方法有效地将离散的记 ID 转换回了连续的动作值,便于进一步的处理和使用。
call 方法 用于将动作裁剪并离散化为词汇表中最后的 n_bins 个 token。
该方法首先将动作值裁剪到指定的最小和最大动作值之间。
def __call__(self, action: np.ndarray) -> Union[str, List[str]]:
"""Clip & bin actions to *the last `n_bins` tokens* of the vocabulary (e.g., tokenizer.vocab[-256:])."""
action = np.clip(action, a_min=float(self.min_action), a_max=float(self.max_action))
然后使用 np.digitize 方法将动作值离散化。
discretized_action = np.digitize(action, self.bins)
如果输入是单个元素,则返回解码后的 token 字符串;如果是批量输入,则返回解码后的 token 字符串列表。
# Handle single element vs. batch
if len(discretized_action.shape) == 1:
return self.tokenizer.decode(list(self.tokenizer.vocab_size - discretized_action))
else:
return self.tokenizer.batch_decode((self.tokenizer.vocab_size - discretized_action).tolist())
构造函数 init 接受一个基础的 LLM/VLM token 器、区间数量、最小动作值和最大动作值作为参数。 默认情况下,假设使用的是类似于 LlamaTokenizer 的 BPE 风格 token 器,其中最少使用的 token 出现在词汇表的末尾。构造函数中还创建了均匀分布的区间,并计算了区间中心。
具体而言,init 方法是 接受四个参数:tokenizer、bins、min_action 和 max_action。其中,tokenizer 是一个基础的 LLM/VLM token 器,bins 是每个连续值的区间数量,min_action 和 max_action 分别是最小和最大动作值。
class ActionTokenizer:
def __init__(
self,
tokenizer: PreTrainedTokenizerBase,
bins: int = 256,
min_action: int = -1,
max_action: int = 1
) -> None:
该方法的主要功能是将连续的机器人动作离散化为多个维度上的 N 个区间,并将其映射到最少使用的 token 上。默认情况下,假设使用的是类似于 LlamaTokenizer 的 BPE 风格 token 器,其中最少使用的 token 出现在词汇表的末尾。
在构造函数中,首先将传入的参数赋值给实例变量。
self.tokenizer, self.n_bins, self.min_action, self.max_action = tokenizer, bins, min_action, max_action
然后,使用 np.linspace 方法创建均匀分布的区间,并计算区间中心。
# Create Uniform Bins + Compute Bin Centers
self.bins = np.linspace(min_action, max_action, self.n_bins)
self.bin_centers = (self.bins[:-1] + self.bins[1:]) / 2.0
最后,设置 action_token_begin_idx,它基于 self.tokenizer.vocab_size - (self.n_bins + 1) 计算,假设总是覆盖词汇表的最后 n_bins 个 token。
# [Contract] Set "action_token_begin_idx" based on `self.tokenizer.vocab_size - (self.n_bins + 1)`
# =>> Assumes we're always overwriting the final `n_bins` tokens of the vocabulary!
self.action_token_begin_idx: int = int(self.tokenizer.vocab_size - (self.n_bins + 1))
// 待更


