跳转至

VLA 微调与评测

引言

视觉-语言-动作模型(Vision-Language-Action Model,VLA)的落地涉及数据、模型和控制器三套接口。损失下降只能说明模型正在拟合训练目标;机器人能否完成任务,还取决于动作语义、时序和闭环反馈。本页给出从公开数据到仿真评测的实验流程,基础概念见VLA 模型。

选择可复现的起点

实现 适合研究的内容 接入时的重点
OpenVLA 基于预训练视觉语言模型的动作预测与参数高效微调 图像预处理、动作离散化、数据集对应的反归一化统计量
openpi π₀、π₀-FAST、π₀.₅ 的训练与推理流程 对应模型的动作头、状态与相机输入、数据转换和模型配置
robomimic 从演示学习的对照实验 在相同观测、数据划分与控制接口下建立基线

openpi 中 π₀ 使用流匹配,π₀-FAST 使用基于 FAST 动作编码的自回归生成;仓库对 π₀.₅ 提供流匹配动作头。它们不能仅通过替换权重路径任意互换,需使用匹配的配置。官方实现说明

选择模型前先确认目标机器人所需的相机数量、状态输入和动作维度。权重公开也不意味着完整预训练数据都可以下载;应分别记录代码、权重和数据的来源与使用条件。

定义观测与动作契约

建议为每个数据集和部署控制器建立同一份接口说明。

字段 必须说明的语义 常见错误
图像 相机名称、RGB 顺序、裁剪、缩放、采样时间 训练时裁掉背景,部署时却保留整幅图像
本体状态 关节顺序、位置或速度、单位、夹爪状态 混用角度与弧度,交换左右臂
语言指令 原始指令、任务标签或生成描述 根据最终成功状态补写指令,泄漏未来信息
平移 绝对位置或增量、米或毫米、参考坐标系 把末端坐标系增量当作基座坐标系增量
旋转 欧拉角、轴角或四元数及分量顺序 将四元数分量当作普通向量直接平均
夹爪 位置目标、开合命令或力控制,开闭方向 把连续开度当作二值命令
时间 动作间隔、观测与动作对齐关系 把下一时刻图像配给当前动作

不同机器人的七维动作,即使形状相同,也可能具有完全不同的含义。应先进行单位与坐标变换,再计算训练统计量;归一化无法修复语义不一致。格式转换流程见开放机器人数据集实践。

从小样本检查到正式微调

数据检查

随机抽取完整 episode,连同图像播放状态和动作曲线,确认停止片段、抓取时刻与夹爪动作一致。训练集与验证集按 episode、场景或采集会话分组划分,不按相邻帧随机拆分。

归一化统计量只从训练划分计算,并随检查点保存。若使用预训练统计量,需要说明其适用的机器人和动作定义;更换数据源后不能凭字段名称沿用。模型需要分位数缩放、均值方差缩放还是其他方式,应按对应实现执行。

小规模过拟合检查

先取少量演示,检查模型能否拟合动作以及推理路径能否正确反归一化。这个步骤用于发现数据错位、掩码错误、被冻结的动作头等问题,不用于报告泛化性能。

对于预测长度为 的动作块,episode 末端不足 步的部分必须明确处理:可以裁掉不完整窗口,或填充后在损失中屏蔽。训练框架如有官方处理方式,应沿用其约定,避免让填充值成为虚假的停止行为。

正式训练

低秩适配(Low-Rank Adaptation,LoRA)可以减少可训练参数,但仍需要保存前向激活,显存需求还受相机数量、图像大小、序列长度、动作块长度和批量大小影响。先测量一个真实训练批次,再决定梯度累积或全参数微调方案。

至少保存以下内容:基础模型版本、数据版本、转换脚本版本、数据划分、归一化参数、优化器配置、随机种子,以及检查点选择规则。验证集用于选择检查点,最终测试集应保持独立。

OpenVLA 的官方仓库包含 LoRA 和数据加载说明;openpi 的官方微调流程则串联数据转换、训练配置、统计量计算、训练和策略服务。命令行接口随版本变化,复现时应固定仓库提交并使用对应文档。OpenVLA 微调入口、openpi 微调入口

训练样本如何组成

设轨迹在时刻 的观测为 ,语言指令为 ,动作块目标为 。模型可以只读取当前观测,也可以读取长度为 的历史:

这里的目标动作必须位于同一个 episode。历史不足、动作块越过末端,以及相机缺失是三类不同的掩码,不宜用一份布尔标记混合处理。将未来动作作为训练标签是正常的监督学习;把未来图像或实际完成结果作为部署时不存在的输入,才会泄漏未来信息。

下面的 NumPy 示例只展示单个 episode 的动作窗口和有效性掩码,不是 OpenVLA 或 openpi 的数据加载器。假定输入动作与观测已经按时间对齐,动作数组形状为 [T, D]。

import numpy as np


def action_window(actions, start, horizon):
    actions = np.asarray(actions, dtype=np.float32)
    if actions.ndim != 2 or actions.shape[1] == 0:
        raise ValueError("actions 必须是 [T, D],且 D 大于 0")
    if not np.isfinite(actions).all():
        raise ValueError("动作中存在 NaN 或无穷值")
    if horizon <= 0 or not 0 <= start < len(actions):
        raise ValueError("动作窗口起点或长度无效")
    valid = min(horizon, len(actions) - start)
    target = np.zeros((horizon, actions.shape[1]), dtype=np.float32)
    mask = np.zeros(horizon, dtype=bool)
    target[:valid] = actions[start:start + valid]
    mask[:valid] = True
    return target, mask


actions = np.arange(15, dtype=np.float32).reshape(5, 3)
target, mask = action_window(actions, start=3, horizon=4)
print(target.shape, mask.tolist())  # (4, 3) [True, True, False, False]

对于连续回归动作头,一个按有效标量元素归一化的示例损失为

分母必须非零。若不同机器人还需要屏蔽动作维度,则分子和分母都改为使用 [B, H, D] 的掩码。离散 token、扩散和流匹配模型的实际训练目标不同,应使用各自实现的损失,不能直接套用这一均方误差公式。

用消融实验判断模型学到了什么

大模型成功率提高后,需要进一步确认改进来自预训练、语言信息、更多数据还是更合适的控制设置。下面是一组可以逐步进行的对照实验,不必一次运行全部组合。

对照实验 保持一致的条件 可以回答的问题
简单行为克隆与预训练 VLA 数据划分、相机、动作接口、评测状态 预训练模型在该任务上是否带来实际收益
完整指令与空指令或打乱指令 场景、模型、动作执行方式 策略行为是否依赖语言输入
单相机与多相机 数据与训练预算口径 遮挡和深度歧义是否限制成功率
不同执行长度 检查点、控制频率、预测长度 性能是否主要受开环执行时间影响
不同演示数量 固定验证集和测试集,按组抽取训练数据 增加数据是否仍有收益,哪些任务最缺数据
原场景与单因素扰动 同一批任务及初始状态生成规则 模型对背景、目标位置或指令改写是否敏感

空指令和打乱指令可能产生训练分布之外的输入,因此它们只能提供诊断线索。更直接的语言测试是在同一个可行场景中,给出两条不同且有效的目标指令,检查目标选择是否变化。

比较数据规模时,明确是固定优化步数还是固定训练轮数:固定轮数会让大数据集获得更多参数更新。比较模型时,同时报告闭环结果与算力、训练时间和推理延迟,避免把预算差异解释为算法优势。

动作块不等于实时闭环

设控制周期为 ,模型每次预测 步,只执行前 步后重新观察,其中 。预测范围为 ,重新规划间隔为 。较大的 减少推理调用次数,但也延长了无法利用新观测纠错的时间。

例如控制频率为 20 Hz,预测 16 步、执行 4 步,则预测范围是 0.8 秒,重规划间隔是 0.2 秒。这些数字只是时序示例。异步流水线若要持续供给动作,图像处理、通信和推理的总耗时需要留在可用预算内;同步调用则会额外引入等待时间。

部署日志应记录观测采样、推理开始、推理结束和动作生效的时间。新动作块到达时,需要根据时间戳处理已经过期的动作;发生重置、人工接管或任务切换时,应清空旧队列。不要把上一个 episode 的剩余动作继续发给新场景。

同步与异步执行的选择

同步执行容易调试:采样观测、等待推理、执行 步,再进入下一轮。记录暂停期间控制器是在保持位置还是继续跟踪旧目标,这会影响实际轨迹。异步执行则允许控制器消耗旧动作时,模型预测新的动作块,但需要明确时间基准和队列替换规则。

运行时事件 建议定义的处理规则
观测比允许阈值更旧 请求新观测,记录拒绝原因,使用控制器约定的备用行为
新动作块迟到 根据时间戳与动作语义决定重新推理或衔接,不能盲目从第一步重播
动作队列耗尽 明确停止、保持目标或受控减速策略;不同动作接口需要不同处理
动作含非有限值或超出接口范围 拒绝该输出,记录原始预测与转换后的值
重置或人工接管 使旧请求失效,同时清空历史缓存和动作队列

对增量动作,跳过过期步可能丢失累计位移;对绝对目标,直接切换又可能产生不连续。异步调度不能仅靠截断数组解决,必须结合动作定义、当前状态和控制器的平滑机制验证。策略延迟较大时,先在仿真中注入同样的延迟分布,再评估部署效果。

分层评价策略能力

层次 记录什么 能发现的问题
离线预测 各动作分量误差、夹爪判断、异常值比例 单位错误、数据错位、某些维度被损失掩盖
基准闭环 每任务成功次数、完成时间、失败阶段 误差累积、恢复能力不足、多阶段任务中断
泛化测试 未见物体、位置、背景、指令改写 对场景或任务模板的记忆
运行时测试 延迟分位数、超时次数、观测年龄 平均推理速度合格但尾部延迟过大

比较语言条件策略时,可固定场景、改变指令中的目标,再观察行为是否相应变化。只在每个场景配一条固定指令上测试,无法区分模型是否真正使用语言信息。

选择 LIBERO 或 SimplerEnv 时,记录训练中是否见过相关任务和演示。对公开预训练模型,如果无法审计全部训练数据,应如实说明数据重叠未知,避免将结果称为严格的未见任务泛化。

常见故障排查

现象 优先检查
损失下降但机器人始终不动 停止片段占比、动作反归一化、控制器死区
末端持续向反方向运动 坐标系、动作正负号、绝对量与增量的区别
到达目标但夹不住 夹爪定义、动作与视频时间偏移、抓取阶段数据覆盖
训练场景成功,换背景即失败 场景划分、相机位置、背景捷径与视觉预处理
动作块边界抖动 队列切换、目标不连续、旧动作与新动作的时间对齐
单环境正常,并行评测异常 批次索引、独立历史状态、局部重置时的缓存清理

参考资料