LingBot-VLA 2.0 方法详解:从观察到连续动作
0. 先用一张图看懂整个方法
LingBot-VLA 2.0 要学习的是一个条件生成问题:
\\\text{多视角图像} + \\text{语言指令} + \\text{机器人当前状态} \\longrightarrow \\text{未来一段连续动作} \\
它的关键不是某一个新模块,而是四件事协同:
flowchart LR A"异构数据\
20 种机器人 + 第一视角人类视频" --> B"统一表示\
55 维状态/动作槽位" B --> C"双专家 VLA\
Qwen3-VL 理解专家 + 动作专家" C --> D"稀疏 MoE\
共享专家 + Top-K 路由专家" C --> E"双查询蒸馏\
当前 + 未来" E --> F"LingBot-Depth\
几何教师" E --> G"DINO-Video\
时序语义教师" D --> H"Flow Matching\
从噪声生成动作块" F --> H G --> H
一句话概括:
先把不同机器人和人手轨迹翻译成同一种"身体语言",再让视觉语言模型负责理解场景,让稀疏 MoE 动作专家通过 Flow Matching 生成连续动作;训练时额外要求模型理解当前几何并预测未来的几何与语义变化。
0.1 输入和输出
| 项目 | 内容 | 典型形状 |
|---|---|---|
| 图像 | 头顶/主视角、左右腕部等多相机画面 | [B, N_cam, ...] |
| 指令 | 全局任务或子任务文本 | [B, L_text] |
| 状态 | 当前关节、末端、夹爪、腰、头、底盘、灵巧手状态 | [B, 55] |
| 动作目标 | 从当前时刻开始的动作块 | [B, H, 55] |
| 模型输出 | 同样长度的连续动作块 | [B, H, 55] |
公开配置中,动作块长度默认是 \(H=50\);推理时默认用 10 次去噪更新生成整块动作。
0.2 方法解决的三个现实问题
flowchart TD P"真实机器人部署的三类困难" P --> P1"数据异构\
不同机器人、相机、频率、动作定义" P --> P2"动作空间不完整\
不只是双臂和夹爪" P --> P3"只看当前不够\
动作必须考虑未来后果" P1 --> S1"大规模清洗 + 自动标注 + 统一坐标" P2 --> S2"55 维全身动作接口 + 维度掩码" P3 --> S3"当前/未来双查询 + 深度/视频教师蒸馏" S1 --> R"更强的跨任务、跨本体泛化" S2 --> R S3 --> R
1. 数据:先把"能学的数据"造出来
1.1 数据全景
论文中的预训练数据约 60,000 小时:
- 约 50,000 小时机器人轨迹,来自 20 种机器人配置;原始池约 90,000 小时。
- 约 10,000 小时第一视角人类视频;原始池约 20,000 小时。
- 机器人覆盖单臂、双臂、半人形、人形、移动操作平台,以及夹爪和灵巧手。
- 控制频率主要为 15 Hz 或 30 Hz,人类第一视角数据约 30--60 Hz。
20 种机器人本体的覆盖范围如下。Body DoF 指实际用于训练的头、腰、底盘等身体自由度:
| 类型 | 本体 | 末端 | 手/夹爪 DoF | 臂 DoF | Body DoF | 总 DoF | Hz |
|---|---|---|---|---|---|---|---|
| 单臂 | Franka | 夹爪 | 1 | 7 | 0 | 8 | 30 |
| 单臂 | Flexiv Rizon 4 | 夹爪 | 1 | 7 | 0 | 8 | 30 |
| 双臂 | AgileX | 夹爪 | 2 | 12 | 0 | 14 | 30 |
| 双臂 | ARX Lift2 | 夹爪 | 2 | 12 | 0 | 14 | 30 |
| 双臂 | UR7e | 夹爪 | 2 | 12 | 0 | 14 | 30 |
| 半人形 | AgiBot G1 | 夹爪 | 2 | 14 | 4 | 20 | 30 |
| 半人形 | Galbot G1 | 夹爪 | 2 | 14 | 6 | 22 | 30 |
| 半人形 | Moz1 | 夹爪 | 2 | 14 | 0 | 16 | 30 |
| 半人形 | Realman Rs-02 | 夹爪 | 2 | 14 | 1 | 17 | 30 |
| 半人形 | Galaxea R1Pro | 夹爪 | 2 | 14 | 7 | 23 | 15 |
| 半人形 | Galaxea R1Lite | 夹爪 | 2 | 12 | 3 | 17 | 15 |
| 半人形 | Astribot S1 | 夹爪 | 2 | 14 | 9 | 25 | 30 |
| 半人形 | Zerith H1 | 夹爪 | 2 | 14 | 7 | 23 | 30 |
| 人形 | Leju KUAVO 4 Pro | 夹爪/手 | 2/12 | 14 | 5 | 21/31 | 30 |
| 人形 | Tienkung | 夹爪 | 2 | 14 | 0 | 16 | 30 |
| 人形 | QingLong | 夹爪 | 2 | 14 | 0 | 16 | 30 |
| 人形 | MagicBot Gen1 | 夹爪 | 2 | 14 | 4 | 20 | 30 |
| 人形 | Unitree G1 | 手 | 12 | 14 | 0 | 26 | 30 |
| 人形 | Fourier GR-2 | 手 | 12 | 14 | 6 | 32 | 30 |
| 人形 | AgiBot A2 | 手 | 12 | 14 | 2 | 28 | 30 |
此外还有 Ego 人类第一视角流,以 14 维双手轨迹作为动作监督,频率约 30--60 Hz。
flowchart LR subgraph Raw"原始数据池" R1"机器人轨迹\
约 90,000 小时" R2"第一视角人类视频\
约 20,000 小时" end R1 --> C1"信号平滑性检查" R1 --> C2"视频-状态对齐检查" R1 --> C3"画面质量检查" R2 --> E1"VLM 视频预筛选" R2 --> E2"SLAM + MANO 手姿估计" R2 --> E3"轨迹与生理约束检查" C1 --> O1"高质量机器人数据\
约 50,000 小时" C2 --> O1 C3 --> O1 E1 --> O2"高质量人类数据\
约 10,000 小时" E2 --> O2 E3 --> O2 O1 --> U"统一状态、动作、语言格式" O2 --> U
1.2 机器人数据怎样清洗
A. 用运动学差分排除异常轨迹
对状态和动作序列 \(x_t\) 计算:
\v_t = \\Delta x_t,\\qquad a_t = \\Delta\^2 x_t,\\qquad j_t = \\Delta\^3 x_t \\
- \(v_t\):速度。
- \(a_t\):加速度。
- \(j_t\):jerk,加速度变化率,能暴露突然跳变、通信错误或控制异常。
- 速度和加速度还会计算 Z-score。
- jerk 或任一导数 Z-score 超过阈值,就丢弃整条 episode。
- 阈值按机器人本体分别设置,因为不同机器人量程和动力学不同。
B. 排除"几乎没动"的无效数据
如果一条 episode 中,所有状态和动作都只发生极小变化的时间占比超过 95%,整条数据被丢弃。
C. 检查视频与状态是否真的同步
sequenceDiagram participant S as 记录的机器人状态 participant U as 机器人 URDF participant P as 图像平面投影 participant V as 真实录制视频 participant H as 人工质检 S->>U: 回放各关节状态 U->>P: 投影机器人几何 V->>H: 提供真实画面 P->>H: 提供理论轮廓/姿态 H->>H: 检查是否重合 alt 不重合 H-->>S: 删除视频-状态错位样本 else 重合 H-->>S: 保留 end
人工还会过滤:模糊、严重遮挡、掉帧、多视角不同步等问题。
1.3 第一视角人类视频怎样变成"动作数据"
第一视角视频通常没有机器人 action,因此要把人手运动重建为可监督的轨迹。
flowchart TD V"候选第一视角视频" --> F"VLM 预筛选" F -->|删除| X"第三视角、只走路、无手物交互、\
无可操作物体、他人手明显出现" F -->|保留| L{"已有动作/手轨迹标签?"} L -->|是| A"整理元数据\
时间戳对齐\
坐标变换\
完整性检查" L -->|否| S"第一视角 SLAM\
估计内参和逐帧相机外参" S --> M"MANO 手姿估计\
相机坐标系中的手参数" M --> W"结合相机位姿\
提升到世界坐标系" A --> Q"轨迹质量控制" W --> Q Q --> Q1"有效手姿帧比例 \>= 20%" Q --> Q2"相机运动稳定" Q --> Q3"位移/速度/加速度/jerk 合理" Q --> Q4"手位置、双手距离、活动范围符合生理约束" Q1 --> O"世界坐标系中的连续手轨迹" Q2 --> O Q3 --> O Q4 --> O
为什么存世界坐标,训练时再转到当前相机坐标
所有有效手轨迹统一存为世界坐标 \(W\)。当采样当前帧 \(t\) 时,把未来时刻 \(\tau\) 的手位置转到当前相机坐标 \(C_t\):
\\\mathbf p_{\\tau}\^{C_t} = \\mathbf T_{C_t \\leftarrow W}\\mathbf p_{\\tau}\^{W} \\
flowchart LR H1"未来手轨迹 p_tau\^W\
稳定存储在世界坐标" --> T"乘当前帧外参\
T_Ct\<-W" C"当前相机姿态" --> T T --> H2"训练动作 p_tau\^Ct\
相对当前观察者表达" H2 --> B1"消除佩戴者走动造成的相机运动" H2 --> B2"与机器人视觉条件更一致"
直觉:模型真正需要学习的是"手相对当前看到的场景应该怎么移动",而不是"相机佩戴者在世界里走了多远"。
1.4 自动语言标注
模型同时使用任务级和子任务级语言。论文使用 Qwen3.6-27B 自动处理整段视频:
- 多相机机器人数据联合输入头顶和腕部视角。
- 把视频切成时间连续的子任务。
- 每个子任务标注原子动作、交互物体和简短指令。
- 整段视频再生成一个全局任务指令。
flowchart LR V"多视角操作视频" --> Q"Qwen3.6-27B" Q --> G"全局指令\
例如:把花插进花瓶" Q --> S1"子任务 1\
transit + 花" Q --> S2"子任务 2\
move + 花" Q --> S3"子任务 3\
attach + 花瓶"
闭集动作词表共 18 类:
- 15 个操作动作:
move, pour, push, pull, rotate, open, close, detach, fold, unfold, wipe, stir, cut, press, attach。 - 3 个辅助类别:
transit空手移动、idle静止、other词表外动作。 idle最终从训练数据中去除。
切分边界只在以下情况出现:交互物体变化、动作类型变化、或持续停顿代表新子目标。一次抓取、搬运、释放通常合并为一个子任务,避免切得过碎。
论文预训练配对了任务级和子任务级语言;数据加载器支持 global、subtask、both 三种 prompt 策略。当前公开 RoboTwin 和真实机器人后训练 YAML 使用 global,即每条样本只把全局任务文本送入策略。
1.5 55 维统一状态/动作表示
不同机器人控制量不同。LingBot-VLA 2.0 给所有本体准备同一个 55 维"插槽表":
| 槽位 | 维度 | 含义 |
|---|---|---|
| 双臂关节位置 | 14 | 每臂最多 7 维 |
| 双臂末端位姿 | 14 | 每臂 XYZ 3 维 + 四元数 4 维 |
| 双夹爪 | 2 | 每侧 1 维 |
| 双灵巧手 | 12 | 每侧 6 维 |
| 腰部 | 4 | 躯干/腰部自由度 |
| 头部 | 2 | 头部自由度 |
| 移动底盘 | 3 | 通常为平面移动信号 |
| 预留 | 4 | 未来扩展 |
| 合计 | 55 | 状态和动作使用同一布局 |
flowchart LR V55"55 维规范向量" V55 --> A"手臂 14" V55 --> E"末端位姿 14" V55 --> G"夹爪 2" V55 --> H"灵巧手 12" V55 --> W"腰 4" V55 --> N"头 2" V55 --> M"底盘 3" V55 --> R"预留 4"
这不是要求每个机器人都有 55 个真实自由度,而是"所有可能字段的并集"。缺失字段补零,并配套布尔掩码:
\\\mathbf m \\in \\{0,1\\}\^{H\\times55} \\
- 真实维度:\(m_{h,d}=1\),参与 action loss。
- 不存在或补齐的维度:\(m_{h,d}=0\),不参与 action loss。
因此单臂机器人、双臂夹爪机器人、移动人形机器人可以进入同一个模型。
一个具体映射例子
RoboTwin 原始动作是 14 维:左臂 6 + 左夹爪 1 + 右臂 6 + 右夹爪 1。公开配置把它重排为:
text
arm.position = 原始 [0:6] + [7:13] -> 12 个有效维度,补到 14
effector.position = 原始 [6:7] + [13:14] -> 2 个有效维度
其余规范字段 -> 补零并 mask 掉
最终 [55]
1.6 绝对动作、相对动作与动作空间
统一槽位只规定"字段放在哪里",不强制字段必须是绝对量还是相对量。机器人配置可以选择:
\\\Delta q_{t:t+H-1}=q_{t:t+H-1}-q_t \\
或直接预测绝对关节位置 \(q_{t:t+H-1}\)。末端位姿的相对旋转使用四元数局部变换,不能简单逐元素相减。
论文消融给出两个重要结论:
- 相对关节动作将平均成功率从 33.7% 提高到 55.0%。它把"预测全局姿态"变成"预测局部修正",方差更小。
- 关节空间与末端空间平均成功率接近,分别约 55.0% 和 56.0%,但任务偏好不同。接触密集、端点轨迹规律的任务可能更适合末端空间;受姿态和可达性约束的任务可能更适合关节空间。
所以正确理解是:55 维接口统一了容器,但每种机器人仍需合理选择容器里的动作语义。
1.7 归一化
每种数据/本体使用自己的统计量。代码支持:
\\\text{MeanStd}(x)=\\frac{x-\\mu}{\\sigma+10\^{-6}} \\
\\\text{Q01--Q99}(x)=2\\frac{x-q_{01}}{q_{99}-q_{01}+10\^{-6}}-1 \\
以及 MinMax、Q02--Q98、仅除标准差等变体,可选择裁剪或不裁剪。
flowchart TD X"真实物理量" --> N{"归一化方案"} N --> M"MeanStd\
保留较大修正动作" N --> Q"Q01-Q99\
对异常值更稳健" N --> MM"MinMax\
容易压缩中心区域" M --> Z"模型空间中的状态/动作" Q --> Z MM --> Z Z --> U"推理后逆归一化" U --> C"机器人真实控制量"
论文四个真实机器人任务的消融中,MeanStd 平均成功率 55.0%,优于 MinMax 的 47.5% 和不裁剪 Q01--Q99 的 47.4%。但公开 RoboTwin 示例使用不裁剪 Q01--Q99;公开真实机器人示例使用 MeanStd。归一化是下游可配置项,不是所有实验共享的常量。
1.8 一条训练样本最终长什么样
以当前时刻 \(t\) 为锚点:
flowchart LR T0"当前帧 t" --> I"多视角当前图像" T0 --> S"当前状态 s_t" T0 --> L"任务/子任务文本" T0 --> A"动作块 a_t ... a_t+H-1" T0 --> F"未来帧 t+H-1" I --> B"训练 batch" S --> B L --> B A --> B F --> B
代码中未来图像偏移是 \((H-1)/\text{fps}\),即动作块最后一个索引对应的帧。论文把它简写为 \(t+T\) 且 \(T\) 为 action chunk size;这是记号与数组下标的差异。
图像侧还有四个实现细节:
- 相机按配置中的固定顺序排列;缺失视角用空图补齐,并由
img_masks标记无效。 - Qwen3-VL image processor 产生视觉 patch 和
image_grid_thw,模型用 M-RoPE 保留图像网格位置。 - 每幅图像 patch 前后加入 vision start/end token;视觉主干的 DeepStack 中间特征会继续注入语言 Transformer 的浅层。
- 如启用图像增强,同一组亮度、对比度、饱和度参数会同步用于所有相机以及当前/未来帧,避免辅助教师与策略看到不一致的颜色扰动。
2. 模型结构:理解专家与动作专家协同
2.1 顶层结构
flowchart LR subgraph Prefix"条件前缀" IMG"多视角图像 token" TXT"语言 token" CQ"当前感知查询 token" FQ"未来感知查询 token" end subgraph VLM"理解专家:Qwen3-VL-4B" VV"视觉编码器" VT"36 层语言 Transformer" end subgraph AE"动作专家" ST"状态 token" AT"H 个带噪动作 token" TR"36 层动作 Transformer" MOE"每层稀疏 MoE FFN" end IMG --> VV --> VT TXT --> VT CQ --> VT FQ --> VT ST --> TR AT --> TR VT <-->|每层共享一次联合注意力| TR TR --> MOE MOE --> OUT"动作速度场 v_theta"
发布权重名为 6B。其主体可理解为:
- 理解专家:Qwen3-VL-4B,负责图像、文本和感知查询。
- 动作专家:独立的 36 层 Qwen2 风格 Transformer,隐藏维度 768。
- 两个专家层数相同,每一层都进行联合注意力,但保留各自的输入投影、输出投影、归一化和 FFN/MoE。
动作专家公开配置的关键维度:
| 项目 | 值 | 作用 |
|---|---|---|
| Transformer 层数 | 36 | 与 Qwen3-VL 文本层逐层对齐 |
| token hidden size | 768 | 状态与动作 token 的内部宽度 |
| query heads | 32 | 与 VLM 联合注意力的 query 头数 |
| key/value heads | 8 | GQA 的 KV 头数 |
| head dimension | 128 | 每个注意力头的维度 |
| 动作块长度 | 50 | 默认未来动作 token 数 |
| 最大状态/动作维度 | 55 | 统一全身接口 |
2.2 为什么不是"VLM 输出一个向量,再交给动作网络"
代码实现得更紧密。第 \(\ell\) 层中:
- VLM token 用 VLM 自己的投影产生 \(Q_v,K_v,V_v\)。
- 状态/动作 token 用动作专家自己的投影产生 \(Q_a,K_a,V_a\)。
- 沿 token 维拼接两组 Q/K/V。
- 做一次联合注意力。
- 再把注意力输出切回两个分支,各自完成残差和 FFN。
flowchart TD V"第 l 层 VLM hidden" --> VQ"VLM Q/K/V 投影" A"第 l 层动作 hidden" --> AQ"动作专家 Q/K/V 投影" VQ --> CAT"沿序列维拼接 Q/K/V" AQ --> CAT CAT --> ATT"联合注意力 + M-RoPE" ATT --> SPLIT{"按原 token 区间切分"} SPLIT --> VO"VLM 输出投影\
残差 + Dense FFN" SPLIT --> AO"动作输出投影\
残差 + 稀疏 MoE FFN" VO --> VN"第 l+1 层 VLM hidden" AO --> AN"第 l+1 层动作 hidden"
好处:动作 token 在每一层都能读取不同抽象层次的视觉语言信息,而不是只接收 VLM 最后一层的压缩结果。
2.3 Prefix 和 Suffix
整个序列分两部分:
- Prefix 条件部分:图像、文本、当前查询、未来查询。
- Suffix 生成部分 :一个状态 token + \(H\) 个带噪动作 token。
公开 V2 配置启用因果 VLM。概念上的顺序为:
text
[多视角图像] [语言] [当前查询组] [未来查询组]
[当前状态] [动作_1] ... [动作_H]
状态和动作先投影到动作专家隐藏维度:
\h_s=W_s s_t \\
\h_{a,i}=\\operatorname{MLP}\\left(\[W_a x_{t,i};\\operatorname{TimeEmb}(\\tau)\right) \]
其中 \(x_{t,i}\) 是第 \(i\) 个带噪动作,\(\tau\in0,1\) 是 Flow Matching 时间。
时间还通过 AdaRMSNorm 调制动作专家,使每层都知道当前噪声强度。
2.4 注意力可见性:既共享信息,又阻止未来标签泄漏
flowchart TD I"图像" --> L"语言" L --> C"当前查询" C --> F"未来查询" I --> S"状态/动作 suffix" L --> S C --> S F -.->|公开配置中屏蔽| S T"未来真实图像" -->|只用于构造教师 target| F T -.->|从不作为策略输入| S
关键点:
- 未来真实图像只进入冻结教师,绝不作为策略条件。
- 未来查询可以读取当前图像和语言,从当前信息中学习预测未来。
- 公开配置用 attention mask 阻止动作 suffix 直接读取未来深度/视频查询。
- 当前查询可被动作分支读取,为动作提供当前几何和语义线索。
- 即使未来查询不被动作直接读取,其蒸馏梯度仍会塑造共享 VLM 表征,使视觉语言主干学到预测性信息。
因此它不是"偷看未来",也不是在推理时把未来帧喂给模型。
2.5 稀疏 MoE 动作专家
跨本体数据混合了不同运动学、控制语义和任务分布。单个 Dense FFN 容易让这些模式互相干扰。LingBot-VLA 2.0 把动作专家每一层的 FFN 换成:
- 一个对所有 token 都执行的共享专家。
- \(N_r\) 个路由专家,每个 token 只选 Top-\(K\)。
公开配置:36 层全部使用 MoE,\(N_r=32\),\(K=4\);路由专家中间宽度 512,共享专家宽度 704。
MoE 计算
对第 \(\ell\) 层 token \(u_{\ell,t}\):
\m_\\ell(u)=E_\\ell\^{(s)}(u)+ \\lambda\\sum_{j\\in\\mathcal R(u)}g_{\\ell,j}(u)E_{\\ell,j}\^{(r)}(u) \\
每个专家都是 SwiGLU:
\E(u)=W_{down}\\left(\\operatorname{SiLU}(W_{gate}u)\\odot W_{up}u\\right) \\
公开配置的 routed scaling factor 为 \(\lambda=4\),共享专家不再使用额外 gate。
路由
\z_j=u\^\\top e_j,\\qquad s_j=\\sigma(z_j) \\
选择专家时加入负载修正偏置:
\\\mathcal R(u)=\\operatorname{TopK}_j(s_j+b_j,K) \\
真正混合输出时不用偏置,只归一化原始置信度:
\g_j=\\frac{s_j}{\\sum_{k\\in\\mathcal R(u)}s_k} \\
flowchart LR U"动作 token u" --> R"FP32 Router" R --> S"Sigmoid 分数 s" B"负载修正偏置 b" --> K"按 s+b 选 Top-K" S --> K K --> E1"路由专家 j1" K --> E2"路由专家 j2" K --> EK"... 共 K 个" S --> W"按原始 s 归一化权重" E1 --> SUM"加权求和 × lambda" E2 --> SUM EK --> SUM W --> SUM U --> SE"共享专家" SUM --> O"相加得到 MoE 输出" SE --> O
无辅助损失负载均衡
论文主方法使用修正偏置而不污染 action objective:
\b_j\\leftarrow b_j- \\gamma\\operatorname{sign}\\left(n_j-\\frac{1}{N_r}\\sum_k n_k\\right) \\
- 专家过载:\(b_j\) 减小,之后较难被选中。
- 专家欠载:\(b_j\) 增大,之后更容易被选中。
- 偏置只改变"选谁",不改变已选专家的真实混合置信度。
一个 4 专家玩具例子
假设 \(K=2\):
text
原始 Sigmoid 分数 s = [0.80, 0.70, 0.60, 0.20]
修正偏置 b = [-0.30, 0.00, +0.20, 0.00]
选择分数 s+b = [0.50, 0.70, 0.80, 0.20]
Top-2 = 专家 3、专家 2
实际混合权重 = [0.60/(0.60+0.70), 0.70/(0.60+0.70)]
专家 1 原本分数最高,但因为长期过载而暂时让位;最终权重仍来自未加偏置的 0.60 和 0.70。
论文设计与公开后训练配置的差异
| 项目 | 论文主方法 | 公开 RoboTwin/真实机器人示例 |
|---|---|---|
| 路由激活 | Sigmoid | Sigmoid |
| 修正偏置更新 | 启用,强调 loss-free | bias_update_speed: 0,不更新 |
| sequence-wise balance loss | 主方法不需要 | 系数 \(10^{-3}\) |
| router z-loss | 主方法不需要 | 系数 \(10^{-4}\) |
README 明确说明:如需复现 loss-free 路由,可关闭后两项,并把 bias_update_speed 设为约 0.00025。换言之,公开 YAML 是下游后训练稳定性配方,不应反向定义论文算法。
2.6 双查询蒸馏:让模型理解现在,并预测未来
论文把它称为 Dual-Query。这里的"两个查询"是两组功能查询:
- \(Q_t\):当前查询组。
- \(Q_{t+T}\):未来查询组。
代码中每组不是单个 token,而是公开配置里的 8 个 task tokens。投影头再用 256 个可学习输出 query,通过交叉注意力恢复 256 个教师 patch tokens。
flowchart TD CUR"当前图像 I_t" --> VLM"Qwen3-VL 因果主干" TXT"任务文本" --> VLM VLM --> QT"当前查询组 Q_t" VLM --> QF"未来查询组 Q_t+T" QT --> HD1"Cross-Attention 投影头" QT --> HV1"Cross-Attention 投影头" QF --> HD2"Cross-Attention 投影头" QF --> HV2"Cross-Attention 投影头" IT"当前真实帧" --> DT"冻结 LingBot-Depth" IF"未来真实帧" --> DF"冻结 LingBot-Depth" IT --> DV"冻结因果 DINO-Video" IF --> DV DT --> LD1"当前深度特征 loss" HD1 --> LD1 DF --> LD2"未来深度特征 loss" HD2 --> LD2 DV --> LV1"当前视频特征 loss" HV1 --> LV1 DV --> LV2"未来视频特征 loss" HV2 --> LV2
LingBot-Depth:提供几何监督
论文写作:
\\\mathcal L_{depth}= \\left\\\|\\operatorname{Proj}_{depth}(Q_t)-D_t\\right\\\|_1+ \\left\\\|\\operatorname{Proj}_{depth}(Q_{t+T})-D_{t+T}\\right\\\|_1 \\
代码实际流程:
- MoGe-2 从 RGB 估计深度。
- LingBot-Depth 的 MoRGBD 模型结合 RGB 与估计深度,输出 256 个 1024 维特征 token。
- VLA 的当前/未来查询经 Perceiver 风格 cross-attention resampler,也输出
[B, 256, 1024]。 - 使用 Smooth L1,而不是严格的绝对值 L1;target 会
detach,教师冻结。
当前公开实现只用配置中的第一个相机视角生成深度 target,并用 VLM 中第一幅图像的 token 作为投影头上下文;默认相机顺序下通常是头顶/主视角。其余相机仍参与 VLA 动作条件,只是不单独生成蒸馏 target。
DINO-Video:提供因果时序语义
\\\mathcal L_{video}= \\left\\\|\\operatorname{Proj}_{video}(Q_t)-Z_t\\right\\\|_F\^2+ \\left\\\|\\operatorname{Proj}_{video}(Q_{t+T})-Z_{t+T}\\right\\\|_F\^2 \\
DINO-Video 的特点:
- 从 DINOv3 图像模型初始化。
- 加入 block-wise causal temporal attention。
- 使用 3D-RoPE 表达空间和时间位置。
- 在 500 万视频片段上训练,数据包含互联网、人类第一视角和机器人视频。
- 教师训练时每个样本均匀取 16 帧,并用有效帧率编码真实时间跨度。
VLA 训练中,公开配置只取当前和一个未来帧,并复制当前帧作 warmup:
text
DINO-Video 输入 = [当前帧副本, 当前帧, 未来帧]
warmup t t+T
教师进行一次因果前向,得到当前和未来 patch 特征。公开配置对两者使用 MSE,并各由当前/未来查询预测。
DINO-Video target 同样取第一个配置相机。effective_fps 由数据原始 fps 和动作 horizon 换算,使教师知道当前帧到未来帧之间代表多少真实时间,而不只是"相隔一个数组位置"。
查询如何共享
公开配置让深度和视频任务共享"当前"及"未来"的功能查询,但先保留各自可学习种子,再拼接后线性融合:
flowchart LR CD"当前深度 query seed" --> CP"拼接 + Linear" CV"当前视频 query seed" --> CP CP --> CQ"共享当前查询 token" FD"未来深度 query seed" --> FP"拼接 + Linear" FV"未来视频 query seed" --> FP FP --> FQ"共享未来查询 token" CQ --> D1"深度头" CQ --> V1"视频头" FQ --> D2"未来深度头" FQ --> V2"未来视频头"
这迫使同一组查询同时保留"在哪里"的几何和"接下来会怎样"的语义动态。
3. 训练 Pipeline
3.1 Flow Matching:从动作到噪声之间学一个速度场
设真实动作块为 \(a\in\mathbb R^{H\times55}\),高斯噪声为 \(\epsilon\sim\mathcal N(0,I)\)。
从 \(\operatorname{Beta}(1.5,1.0)\) 采样时间,再缩放到 \(0.001,1\):
\\\tau\\sim\\operatorname{Beta}(1.5,1.0) \\
构造直线路径:
\x_\\tau=\\tau\\epsilon+(1-\\tau)a \\
- \(\tau\approx0\):几乎是真实动作。
- \(\tau\approx1\):几乎是纯噪声。
这条路径的真实速度恒定:
\u_\\tau=\\frac{d x_\\tau}{d\\tau}=\\epsilon-a \\
模型学习:
\v_\\theta(x_\\tau,\\tau\\mid I_t,l,s_t)\\approx\\epsilon-a \\
推理时反过来从 \(\tau=1\) 积分到 \(0\),就能把噪声搬运成动作。
flowchart LR A"真实动作 a\
tau=0" --- X1"少量噪声" --- X2"混合状态 x_tau" --- X3"大量噪声" --- N"高斯噪声 epsilon\
tau=1" X2 --> V"模型预测速度 v_theta" V --> U"监督目标 epsilon-a"
3.2 单步训练完整流程
flowchart TD D"采样当前帧、未来帧、文本、状态、动作块" --> P"字段映射、相对化、归一化、55 维补齐" P --> T"随机采样 tau 和高斯噪声 epsilon" T --> X"构造 x_tau = tau\*epsilon + 1-tau\*a" P --> TD"冻结 LingBot-Depth\
生成当前/未来几何 target" P --> TV"冻结 DINO-Video\
生成当前/未来语义 target" X --> M"VLA 前向\
图像+文本+查询+状态+带噪动作" M --> VA"动作速度预测" M --> PD"深度特征预测" M --> PV"视频特征预测" M --> RR"MoE router logits" VA --> LA"Action Flow Loss" TD --> LD"Depth Loss" PD --> LD TV --> LV"Video Loss" PV --> LV RR --> LM"可选 MoE 辅助项" LA --> SUM"总损失" LD --> SUM LV --> SUM LM --> SUM SUM --> BP"反向传播 + 梯度裁剪 + Optimizer" BP --> LB"可选:按专家负载更新修正偏置"
3.3 中文伪代码:训练
python
def train_step(batch, policy, depth_teacher, video_teacher):
# 1. batch 已完成:本体字段映射、归一化、55 维补齐和有效维度 mask
images = batch.current_images
future_images = batch.future_images
text = batch.language
state = batch.state # [B, 55]
action = batch.action_chunk # [B, H, 55]
valid = batch.joint_mask # [B, H, 55]
# 2. Flow Matching 插值;tau 越大,x_tau 越接近纯噪声
epsilon = randn_like(action)
tau = sample_beta(alpha=1.5, beta=1.0) # [B]
tau = 0.999 * tau + 0.001
x_tau = tau[:, None, None] * epsilon + (1 - tau[:, None, None]) * action
target_velocity = epsilon - action
# 3. 冻结教师只产生监督 target,不接收梯度
with no_grad():
depth_now = depth_teacher(images[:, :1])
depth_future = depth_teacher(future_images[:, :1])
video_now, video_future = video_teacher.causal_forward(
[images[:, :1], future_images[:, :1]]
)
# 4. 学生一次前向,同时预测动作速度、当前/未来感知特征
pred = policy(
images=images,
text=text,
state=state,
noisy_action=x_tau,
flow_time=tau,
)
# 5. 只在本体真实存在的动作维度上计算 action loss
action_error = l1_or_l2(pred.velocity, target_velocity)
loss_action = (action_error * valid).sum() / valid.sum().clamp(min=1)
# 6. 当前与未来的几何/语义蒸馏
loss_depth = smooth_l1(pred.depth_now, depth_now)
loss_depth_future = smooth_l1(pred.depth_future, depth_future)
loss_video = mse(pred.video_now, video_now) + mse(pred.video_future, video_future)
# 7. 公开后训练配置还可加入 sequence-wise balance 和 router z-loss
loss = (
loss_action
+ 0.004 * loss_depth
+ 0.004 * loss_depth_future
+ 0.004 * loss_video
+ loss_moe_optional
)
loss.backward()
clip_grad_norm(policy.parameters())
optimizer.step()
optimizer.zero_grad()
3.4 Loss 的完整定义
A. 动作 Flow Matching loss
代码支持 L2 和 L1:
\\\mathcal L_{action}\^{L2} =\\frac{\\sum_{h,d}m_{h,d}(v_{\\theta,h,d}-u_{h,d})\^2} {\\sum_{h,d}m_{h,d}} \\
\\\mathcal L_{action}\^{L1} =\\frac{\\sum_{h,d}m_{h,d}\|v_{\\theta,h,d}-u_{h,d}\|} {\\sum_{h,d}m_{h,d}} \\
论文消融中 L2 平均成功率 55.0%,优于 L1 的 46.4%;但公开后训练 YAML 使用 L1_fm。这是任务相关选择:
- L2 更强调高密度的小修正和精确回归。
- L1 对接触冲击和长尾动作更稳健;论文中挤番茄酱任务反而更适合 L1。
B. 深度蒸馏 loss
代码将当前和未来分别加权:
\\\mathcal L_{D} =\\alpha_D\\operatorname{SmoothL1}(\\hat D_t,D_t) +\\alpha_{FD}\\operatorname{SmoothL1}(\\hat D_{t+T},D_{t+T}) \\
公开配置 \(\alpha_D=\alpha_{FD}=0.004\)。
C. 视频蒸馏 loss
公开配置启用当前和未来 patch MSE:
\\\mathcal L_V=\\alpha_V\\left\[ \\operatorname{MSE}(\\hat Z_t,Z_t) +\\operatorname{MSE}(\\hat Z_{t+T},Z_{t+T}) \\right \]
其中 \(\alpha_V=0.004\)。代码也支持 Smooth L1、cosine loss 和 CLS token loss,但公开配置关闭这些变体。
D. 可选 sequence-wise MoE balance loss
对每条序列、每层统计专家实际命中频率 \(f_j\) 和平均路由概率 \(P_j\):
\f_j=\\frac{N_r}{K}\\cdot\\frac{\\#\\{\\text{token 选择专家 }j\\}}{N_{token}} \\
\P_j=\\frac{1}{N_{token}}\\sum_t \\frac{\\sigma(z_{t,j})}{\\sum_k\\sigma(z_{t,k})} \\
\\\mathcal L_{seq}=\\alpha_{seq}\\sum_j f_jP_j \\
公开后训练配置 \(\alpha_{seq}=10^{-3}\)。
E. 可选 router z-loss
\\\mathcal L_z=alpha_z\\cdot \\mathbb E\\left\[\\log\\sum_j e\^{z_j}\\right^2 \]
用于抑制 router logits 数值爆炸。公开配置 \(\alpha_z=10^{-4}\)。
F. 总损失
\\\boxed{ \\mathcal L_{total}= \\mathcal L_{action} +\\mathcal L_D +\\mathcal L_V +\\mathcal L_{seq} +\\mathcal L_z } \\
loss-free 论文设定中,最后两项可为 0,专家均衡改由修正偏置完成。
3.5 梯度到底流向哪里
flowchart LR ALOSS"动作 loss" --> AE"动作专家 + MoE" ALOSS --> VLM"共享注意力中的 VLM 参数" DLOSS"深度 loss" --> DH"深度投影头" DLOSS --> VLM VLOSS"视频 loss" --> VH"视频投影头" VLOSS --> VLM DT"LingBot-Depth" -.->|冻结,无梯度| DLOSS VT"DINO-Video" -.->|冻结,无梯度| VLOSS FQ"未来查询" -.->|attention mask 阻止直接泄漏给动作| AE
公开配置还会 detach 未来深度/视频分支使用的当前图像特征,减少辅助任务通过捷径干扰动作主干。
3.6 优化与大规模训练工程
这些不是方法创新核心,但决定代码怎样跑:
- FSDP2 对模型分片;MoE 专家可进一步做 expert parallel。
- 36 层动作专家支持 gradient checkpointing。
torch.compile、Flex Attention、融合 MoE kernel 用于提速。- 公共真实机器人示例:Muon optimizer,学习率 \(5\times10^{-5}\),全局 batch 4,最多 40,000 steps。
- 公共 RoboTwin 示例:Muon,学习率 \(10^{-4}\),全局 batch 3,最多 30,000 steps。
- MoE 路由专家可用 \(\sqrt{N_r/K}\) 比例的独立学习率缩放。
- 梯度裁剪后执行 optimizer step;loss-free 模式在 step 前按跨 rank 汇总负载更新路由偏置。
4. 推理:从随机噪声得到可执行动作
4.1 推理时不需要两个教师
LingBot-Depth 和 DINO-Video 只在训练时生成 target。部署时需要:
- Qwen3-VL 理解专家。
- 动作专家与 MoE。
- 当前/未来查询 token 本身。
- Flow Matching 速度预测头。
不需要运行深度模型、DINO-Video 或蒸馏投影头,因此辅助监督不会直接增加控制环中的教师推理成本。
4.2 完整推理流程
sequenceDiagram participant R as 机器人 participant P as 预处理 participant V as Qwen3-VL Prefix participant A as 动作专家 participant D as 控制端 R->>P: 当前多视角图像、状态、语言指令 P->>P: 重排字段、归一化、补齐到 55 维 P->>V: 图像/文本/查询 token V->>V: Prefix 前向一次,缓存每层 K/V P->>A: 当前状态 + 高斯噪声动作块 loop 10 次 Euler 更新,tau 从 1 到 0 A->>V: 读取缓存的 Prefix K/V A->>A: 预测速度 v_theta A->>A: x <- x - 0.1 * v_theta end A->>P: 归一化空间动作块 H,55 P->>P: 去除 padding、逆归一化、恢复原始字段 P->>D: 前若干步动作或整个动作块 D->>R: 执行动作
为什么 Prefix 只算一次
图像、文本和查询在 10 次去噪中不变。代码第一次前向缓存其每层 key/value;后续只重新计算状态、当前带噪动作和时间 embedding,并拼接缓存。这显著降低 10 步采样的重复计算。
4.3 Euler 去噪
初始化:
\x_1\\sim\\mathcal N(0,I),\\qquad \\Delta\\tau=-\\frac{1}{10}=-0.1 \\
循环:
\x_{\\tau+\\Delta\\tau}=x_\\tau+\\Delta\\tau\\cdot v_\\theta(x_\\tau,\\tau\\mid I,l,s) \\
从 \(\tau=1\) 更新到 \(0\) 后,\(x_0\) 就是动作块。
4.4 中文伪代码:推理
python
def infer_action_chunk(observation, policy, robot_adapter, num_steps=10):
# 1. 把机器人原始输入变成模型的统一格式
x = robot_adapter.map_fields(observation)
x.state = robot_adapter.normalize_state(x.state)
x.state, masks = pad_to_55(x.state)
images = preprocess_qwen_images(x.images)
text_tokens = tokenize(x.instruction)
# 2. 图像、文本、当前/未来查询固定,先算一次并缓存 K/V
prefix_cache = policy.encode_prefix_once(images, text_tokens)
# 3. 从整块高斯噪声开始
action = randn(shape=[1, policy.chunk_size, 55])
dt = -1.0 / num_steps
tau = 1.0
# 4. 沿学到的速度场从噪声积分到动作
for _ in range(num_steps):
velocity = policy.predict_velocity(
state=x.state,
noisy_action=action,
flow_time=tau,
prefix_kv=prefix_cache,
)
action = action + dt * velocity
tau = tau + dt
# 5. 回到机器人自己的控制接口
action = select_valid_dimensions(action, masks)
action = robot_adapter.unnormalize_action(action)
action = robot_adapter.relative_to_absolute_if_needed(action, observation.state)
return robot_adapter.restore_raw_fields(action)
4.5 动作块怎样执行
模型一次产生 \(H\) 步,但控制端不一定全部盲执行。部署 wrapper 支持:
chunk_ret=True:直接返回整块,交给外部控制器处理。use_length=k:每次推理只保留前 \(k\) 步,逐步执行;第 \(k\) 步后重新观察并规划。use_length=1:每执行一步就重新推理,反馈最及时但算力开销最大。- README 的真实机器人示例使用
use_length=25;一次前向约 130 ms,含 10 次去噪,测试硬件为 RTX 4090D。
flowchart LR O1"观察 1" --> P1"预测 H 步" P1 --> E1"只执行前 k 步" E1 --> O2"新观察" O2 --> P2"重新预测 H 步" P2 --> E2"再执行前 k 步"
\(k\) 是开环效率与闭环纠错能力之间的折中。
5. 一个贯穿全流程的例子
任务:双臂移动机器人执行"把桌上的水瓶放进冰箱"。设 \(H=50\)。
5.1 数据与表示
flowchart TD OBS"当前观察" --> I1"头部相机" OBS --> I2"左腕相机" OBS --> I3"右腕相机" OBS --> TXT"把水瓶放进冰箱" OBS --> ST"双臂、夹爪、腰、头、底盘状态" ST --> MAP"映射到 55 维" MAP --> MASK"不存在灵巧手等字段置 0 并 mask" MAP --> NORM"按本体统计量归一化"
动作块可能同时包含:
- 底盘向桌子移动。
- 腰/头调整以保持目标可见。
- 双臂接近水瓶。
- 夹爪闭合。
- 底盘移动到冰箱。
统一接口允许这些自由度在同一个 \(50,55\) 张量中协同出现。
5.2 模型内部
- Qwen3-VL 从多视角画面和语言中定位水瓶、冰箱和机器人手臂。
- 当前查询学习桌面、水瓶、夹爪之间的几何关系。
- 未来查询学习"成功动作后水瓶应靠近冰箱内部"的未来表征。
- 动作 token 在每层联合注意力中读取视觉语言信息。
- 不同动作 token 可路由到不同专家,例如底盘移动模式、抓取接触模式、双臂协调模式;这些语义不是人工指定,而是训练中自动形成。
5.3 一个标量上的 Flow Matching 数值例子
只看某个动作维度:真实归一化动作 \(a=0.3\),噪声 \(\epsilon=-0.7\),采样 \(\tau=0.8\)。
\x_{0.8}=0.8\\times(-0.7)+0.2\\times0.3=-0.5 \\
真实速度:
\u=\\epsilon-a=-0.7-0.3=-1.0 \\
若模型预测 \(v_\theta=-1.05\):
\L2=(-1.05+1.0)\^2=0.0025 \\
推理时从 \(-0.7\) 出发,按负时间方向积分。因为 \(\Delta\tau<0\),减去负速度会逐步把值推向 \(0.3\)。
5.4 部署闭环
模型生成 50 步,但机器人只执行前 10 步,然后重新拍照。若水瓶滑动,新观察会改变下一动作块;这就是 action chunking 与闭环控制的结合。
6. 为什么这些设计有效
flowchart TD D"更多且更干净的数据" --> G1"覆盖更多物体、任务、视角" U"统一 55 维表示" --> G2"共享跨本体动作规律" M"稀疏 MoE" --> G3"共享规律与专门模式共存" Q"当前/未来蒸馏" --> G4"几何感知 + 预测性表征" F"Flow Matching" --> G5"连续、多峰动作块生成" G1 --> R"更强的泛化和真实部署能力" G2 --> R G3 --> R G4 --> R G5 --> R
6.1 数据与表示解决"能否共同训练"
没有统一动作空间时,每个本体都像一个独立任务。55 维插槽和 mask 让相同身体部位对齐,同时不强迫不存在的自由度产生损失。
6.2 MoE 解决"容量够不够、模式会不会冲突"
共享专家学习普遍规律,路由专家提供额外容量。每个 token 只激活少数专家,因此总参数量增加而活跃计算量受控。论文在相同活跃参数预算下,MoE 的训练 loss 和 GM-100 验证 action error 都优于 Dense 模型。
6.3 双查询解决"表征是否只会识别,不会预测"
VLM 预训练擅长回答"画面里有什么",机器人还需要知道"动作之后会变成什么"。未来查询把这个要求变成可监督代理任务;深度教师约束几何,视频教师约束运动与语义,两者互补。
6.4 Flow Matching 解决"动作不是一个离散答案"
同一场景可能有多条合理轨迹。Flow Matching 学习条件速度场,从随机噪声生成整段连续动作,比逐维单点回归更适合表达多模态动作分布,也避免把连续控制离散成大量 action tokens。
7. 实验告诉了我们什么
7.1 Generalist 双臂操作
同一策略混合训练九个 GM-100 任务:
| 平台 | 指标:进度 / 成功率 | GR00T N1.7 | \(\pi_{0.5}\) | LingBot-VLA 1.0 | LingBot-VLA 2.0 |
|---|---|---|---|---|---|
| AgileX Cobot Magic | % | 36.3 / 17.8 | 59.1 / 32.2 | 58.2 / 30.0 | 66.2 / 34.4 |
| Galaxea R1 Pro | % | 16.4 / 5.6 | 27.4 / 8.9 | 32.7 / 15.6 | 34.6 / 15.6 |
提升在目标定位和目标导向动作明显的任务上更突出,但不是所有任务都提升。论文也指出精确放置、释放和最后一步完成仍是弱点,且不同平台之间仍存在较大差距。
7.2 长时移动操作
| 本体与任务 | 设置 | LingBot-VLA 2.0 | \(\pi_{0.5}\) |
|---|---|---|---|
| Astribot S1:物品放入冰箱 | ID | 77.1 / 60.0 | 65.3 / 46.7 |
| Astribot S1:物品放入冰箱 | OOD | 37.0 / 13.3 | 30.3 / 6.7 |
| Cobot Magic-ARX X5:清洁炉灶 | ID | 84.3 / 66.7 | 79.9 / 60.0 |
| Cobot Magic-ARX X5:清洁炉灶 | OOD | 67.5 / 40.0 | 62.5 / 33.3 |
这里指标仍是进度 / 成功率。OOD 包括初始位置在前后左右扰动 \(\pm10\) cm;冰箱任务还替换成未见物体类别。
7.3 应怎样解读证据
- 结果支持"系统组合有效",但没有对每个新增组件给出同等完整的成功率消融。
- MoE 有同活跃参数预算下的训练 loss 和验证 action error 对比。
- 动作目标、动作空间、归一化和 L1/L2 有真实机器人消融。
- 双查询蒸馏展示了当前/未来深度及 DINO 特征的预测可视化;论文没有提供同规模的关闭蒸馏成功率表。
- 因此不能把全部性能增益精确归因到某一个模块。
8. 它不是什么
8.1 不是显式像素世界模型
它不生成未来 RGB 视频,也不做长时 roll-out。它预测的是教师特征空间中的未来几何和语义表示,所以更准确的称呼是"预测性表征学习"。
8.2 不是人工定义专家语义的 MoE
没有规定某个专家专门负责某机器人、某身体部位或某任务。路由是逐 token 学出来的,专家语义可能混合本体、阶段、动作类型等因素。
8.3 不是把 55 维全部发给每个机器人
模型输出 55 维后,适配器用 mask 取回该本体的真实字段,再逆归一化和反向字段映射。补齐维度不会进入硬件控制接口。
8.4 不是一次预测后永久开环
动作块可以只执行前 \(k\) 步,然后重新观察和规划。模型本身提供 action chunk,闭环频率由部署策略决定。
9. 论文公式与代码实现对照
| 概念 | 论文表达 | 代码中的关键实现 |
|---|---|---|
| 统一动作空间 | 55 维 canonical vector | FeatureTransform.pad_and_concat + joint_mask |
| 人类轨迹坐标 | 世界坐标存储,当前相机坐标训练 | 数据预处理方法,公开训练代码消费标准化后的 LeRobot 数据 |
| 动作生成 | 连续动作模型 | FlowMatchingV2.forward / sample_actions |
| 时间采样 | Flow Matching 时间 | Beta(1.5,1.0),缩放到 [0.001,1] |
| 理解专家 | VLM | Qwen3-VL-4B |
| 动作专家 | 与 VLM 协同 | 36 层、hidden 768,逐层联合注意力 |
| MoE | 共享 + Top-K routed experts | 32 个路由专家、Top-4、全 36 层 |
| loss-free 均衡 | 路由修正偏置 | optimizer pre-hook 汇总专家负载并更新 bias |
| 当前/未来查询 | \(Q_t,Q_{t+T}\) | 每组 8 个 task tokens;输出 256 个教师 token |
| 深度教师 | LingBot-Depth | MoGe-2 深度 + MoRGBD/LingBot-Depth feature |
| 视频教师 | DINO-Video | 因果 DINOv3 video teacher |
| 深度 loss | 论文写 L1 | 代码用 Smooth L1 |
| 视频 loss | Frobenius squared | 公开配置用 patch MSE |
| 推理积分 | 从噪声到动作 | 10 步 Euler,\(\Delta t=-0.1\) |
| 部署 | action chunk | 整块返回或只执行前 use_length 步 |
9.1 主要源码证据位置
这部分只用于核查,不影响正文独立阅读:
| 主题 | 文件 |
|---|---|
| 论文方法与公式 | arXiv-2607.06403v1/sections/3_method.tex |
| 论文实验与消融 | arXiv-2607.06403v1/sections/4_experiments.tex |
| V2 主模型、联合注意力、Flow Matching | lingbot-vla-v2/lingbotvla/models/vla/lingbot_vla/modeling_lingbot_vla_v2.py |
| 动作专家与 MoE 路由 | lingbot-vla-v2/lingbotvla/models/vla/lingbot_vla/qwen2_action_expert.py |
| 深度/视频投影头 | lingbot-vla-v2/lingbotvla/models/vla/vision_models/align_heads/ |
| 教师构建与 target 生成 | lingbot-vla-v2/lingbotvla/models/vla/vision_models/module_utils.py |
| DINO-Video 教师封装 | lingbot-vla-v2/lingbotvla/models/vla/vision_models/dino_video/teacher.py |
| 数据字段映射、补齐和反变换 | lingbot-vla-v2/lingbotvla/data/vla_data/utils.py |
| 归一化与图像处理 | lingbot-vla-v2/lingbotvla/data/vla_data/transform.py |
| 训练主循环 | lingbot-vla-v2/tasks/vla/train_lingbotvla.py |
| 部署和动作块执行 | lingbot-vla-v2/deploy/lingbot_vla_v2_policy.py |
| 公开真实机器人配置 | lingbot-vla-v2/configs/vla/real_robot/real_robot.yaml |
10. 常见问题
Q1:未来查询在推理时从哪里得到未来信息?
得不到真实未来帧。它只读取当前图像和语言,并依靠训练时的未来教师监督学会预测。推理时未来帧不存在,也不会运行教师。
Q2:既然动作分支被禁止读取未来查询,未来蒸馏怎样帮助动作?
它通过共享 VLM 和逐层联合注意力的训练梯度改善底层表征,让主干从当前观察中提取更具预测性的特征;当前查询仍可直接为动作提供感知信息。屏蔽未来查询是为了避免辅助分支成为动作的捷径。
Q3:MoE 专家是否等于"一种机器人一个专家"?
不是。路由粒度是 token,且没有本体专家标签。一个序列中的不同动作时刻可以选不同专家,同一专家也可以服务多个本体。
Q4:55 维中的 padding 会不会学出随机动作?
模型可能在 padding 位置产生数值,但训练 loss 用 joint mask 忽略这些维度,部署反映射也不会把它们发给机器人。
Q5:为什么同时保留关节和末端位姿槽位?
不同数据源和任务的最佳控制空间不同。统一表示允许某个本体使用关节、另一个使用末端,或按配置组合;未使用字段由 mask 关闭。
Q6:为什么预测整个动作块而不是下一步?
动作块能表达时间连贯性,减少逐步调用开销,并让未来预测 horizon 与控制 horizon 对齐。部署仍可只执行前几步以保持闭环。
Q7:L1 和 L2 到底选哪个?
论文消融总体偏向 L2,公开后训练配置使用 L1。小而密集的精确修正通常适合 L2;接触冲击和长尾动作可能适合 L1。应按目标数据验证,而不是把任一配置当成普遍结论。
Q8:DINO-Video 自己怎样训练?
它从 DINOv3 初始化,加入因果时间注意力和 3D-RoPE,在 500 万混合视频片段上用视频版 DINO/iBOT 自蒸馏目标训练。VLA 训练时它已经冻结,只提供特征 target。
11. 最小记忆版
mindmap root((LingBot-VLA 2.0)) 数据 50k 小时机器人 10k 小时第一视角人类 自动任务/子任务标注 严格轨迹与视频质检 表示 55 维全身状态动作 缺失维度补零加 mask 本体级归一化 可选绝对或相对动作 模型 Qwen3-VL 理解专家 36 层动作专家 每层联合注意力 32 专家 Top-4 MoE 辅助监督 当前和未来查询 LingBot-Depth 几何 DINO-Video 时序语义 生成 Flow Matching 动作块 H 默认 50 10 步 Euler 去噪 KV Cache 加速 部署 逆归一化与字段反映射 整块返回或执行前 k 步 新观察后重规划
最终只需记住这条主线:
异构轨迹先统一成 55 维动作语言;Qwen3-VL 理解图像和指令;MoE 动作专家用 Flow Matching 生成动作块;当前/未来的深度与视频蒸馏让共享表征同时具备几何感知和预测能力;部署端再把统一动作翻译回具体机器人并闭环执行。