从“看懂三维场景”到“想象目标并执行动作”

从“看懂三维场景”到“想象目标并执行动作”
先用一分钟抓住核心3D-VLA 想解决的问题是机器人不应只学习一条“当前画面直接映射到动作”的捷径而应先理解三维环境再想象任务完成后的目标状态最后依据“现在在哪里”和“应该变成什么样”生成动作。可以把它记成四步看懂现在把 RGB-D / 多视角图像变成带空间位置的 3D 场景特征。用语言思考3D 大语言模型理解场景、指令、物体和空间位置。想象未来条件扩散模型生成任务完成后的 RGB、深度图或点云。规划动作把当前状态和目标状态交给 3D-VLA输出离散化的 7-DoF 机器人动作序列。当前 RGB-D / 多视角图像带坐标的 3D 场景特征语言指令3D-VLA 语言主干目标模态与目标物体描述目标生成器目标 RGB-D 或目标点云动作生成7-DoF 动作 token 序列一句话概括其创新3D-VLA 用特殊 token 把场景、物体、三维框、目标模态和机器人动作统一成一门“语言”再用扩散模型为这门语言补上生成图像和点云的能力。为什么需要 3D-VLA1.1 传统 VLA 的两个缺口很多 Vision-Language-Action 模型采用当前图像语言指令机器人动作这条路线能工作但有两个明显问题。第一只看 2D 容易丢失真实几何关系。“最远的杯子”“中间的抽屉”“从瓶子后面抓取”等指令都依赖深度、距离、遮挡和三维位置。单张 RGB 图像中的像素接近并不等于物理空间中接近。第二直接预测动作没有显式建模任务完成后的世界。人执行“打开抽屉”时脑中通常有一个目标抽屉应从关闭变为打开其他背景尽量不变。这个目标状态给规划提供了稳定的中间参照。3D-VLA 把这种能力称为 goal imagination目标想象。1.2 3D-VLA 实际学习的三个映射令当前三维状态为语言指令为目标状态为动作序列为。完整系统可以拆成理解、定位与生成意图目标状态生成动作规划其中是 3D-VLA 语言主干生成的中间语义例如open the bottom drawer loc…它同时告诉后续模块要生成哪一种模态操作意图是什么操作对象是什么物体位于哪里。这也是定位能力为什么会帮助目标生成扩散模型不再只得到一句含糊的“打开抽屉”还可以得到“打开这个位置的底层抽屉”。全局架构它不是一个单体网络论文中的完整系统由四类组件组成。组件 作用 直观类比3D 场景特征提取 把多视角视觉信息和三维坐标绑定 眼睛与空间感BLIP-2 Flan-T5 XL Q-Former 理解场景和指令生成文本、位置、模态或动作 token 语言化的思考中枢RGB/RGB-D 条件扩散模型 根据当前图像和指令生成目标图像/深度 在脑中想象完成画面Point-E 风格点云扩散模型 根据当前点云和指令生成目标点云 在脑中想象完成后的三维形状连接这些组件的关键不是共享原始输入而是两种接口特殊 token 接口让 LLM 知道某段内容代表场景、物体、位置、图像、点云或动作。Projector 接口把 LLM 的隐藏特征映射到扩散模型所需的条件特征空间。控制目标想象语言化推理三维感知多视角 RGB / RGB-D多视角视觉特征点云坐标Q-Former: 每个场景压缩为 32 个 tokenFlan-T5 XL语言指令交互 token 词表Transformer ProjectorRGB / RGB-D 扩散模型点云扩散模型目标状态3D-VLA 动作生成离散 7-DoF 动作这里有一个容易误解的点“生成式世界模型”不等于模型学会了完整、连续、可反复滚动的物理仿真器。 3D-VLA 主要生成任务完成时的目标状态而不是逐帧预测所有中间状态。因此它更接近“目标条件世界模型”。数据怎样把普通机器人视频变成 3D 指令数据模型能力的上限首先由数据决定。原始机器人数据通常只有视频、语言指令和部分动作记录3D-VLA 需要把它们加工成场景语言框目标状态动作3.1 数据来源和规模论文汇总了真实机器人、仿真机器人和人类-物体交互数据Open-X 中的多种机器人数据如 BC-Z、Bridge、Fractal/RT-1、Jaco Play、Language Table、Mutex、Roboturk、Taco Play 等带较好深度信息的 Dobb-E、RH20T仿真环境 RLBench、CALVIN人类-物体交互数据 Epic-Kitchens、HOI4D。论文统计共使用约 316K episodes加工后得到约 2M 条 3D-language-action 指令样本。一个 episode 可以派生多种任务所以指令对数量远大于 episode 数量。3.2 数据加工流水线有没有机器人/HOI 视频与指令原数据有深度吗?统一深度表示ZoeDepth 逐帧估深RAFT 光流找静止背景用静止背景校准跨帧深度尺度结合相机内参与位姿反投影为点云spaCy 提取指令中的名词短语Grounded-SAM 得到对象 2D maskmask 随深度提升到 3D得到对象 3D AABB取未来/末帧作为目标 RGB、深度、点云读取原数据的 7-DoF 动作模板 GPT-3.5 改写多任务 3D 指令微调数据下面逐步解释。第一步补深度并保持视频内尺度一致超过 95% 的来源视频没有原生 3D 信息。论文使用 ZoeDepth 为每帧估计深度。单目深度的难点是每帧尺度可能漂移同一张桌子在相邻帧里可能被预测成不同距离。为此方法使用 RAFT 光流找出相机不动时的静止背景再对每帧深度乘一个校准系数使这些背景区域在时间上尽量一致。第二步RGB-D 反投影为点云对像素、深度和相机内参相机坐标系中的三维点为若已知相机外参再把变换到统一世界坐标系。这样每个点既有位置又继承对应像素的颜色或视觉特征。第三步产生 3D 物体框用 spaCy 从指令中抽取名词短语例如 bottom drawer、red cup。用 Grounded-SAM 在图像上得到这些物体的 2D mask。把 mask 覆盖的像素借助深度提升成局部点云。对局部点云求轴对齐包围盒 AABB若同名候选很多论文会结合显著光流区域和 grounding 置信度优先选出真正被操作的物体。第四步构造目标状态视频后续帧天然描述“执行动作后世界变成什么样”。因此可把未来帧通常是任务完成附近的末帧作为目标 RGB 图目标深度图目标点云。这一步把昂贵的人工目标标注转化为从机器人演示中自动取监督信号。第五步把结构化标注写成“特殊语言”论文先用模板生成问题和答案再用 GPT-3.5-turbo-0125 配合 23 个手写示例做语言多样化。GPT 只负责改写/组织语言核心 3D 框、动作和状态仍来自前面的结构化处理。3.3 数据覆盖哪些任务能力 输入 期望输出Embodied QA 当前场景 问题 自然语言答案What-if QA 场景 假设动作 动作可能造成的结果Task Caption 初始场景 最终场景 执行了什么任务Verification 初始场景 当前场景 指令 是否已完成Localization 场景 物体名称 6 个 3D 位置 tokenDense Caption 场景 3D 框 框内物体描述Goal Generation 初始场景 指令 图像/深度/点云生成意图及目标模态Action Prediction 当前场景可选目标场景 指令 7-DoF 动作 token 序列同一个底层模型通过问题模板区分任务。例如定位The scene is . Locate: bottom drawer.Answer: loc…loc…loc…loc…loc…loc…目标生成The initial scene is . Instruction: close the bottom drawer.Answer: close the bottom drawer loc……动作预测. Close the bottom drawer. Predict key actions.Answer: aloc……arot……gripper…ACT_SEP…3.4 公开代码实际读取的数据形态3D 语言主干样本一个样本的核心字段是字段 形状/类型 含义pc_feat每个 3D 点的多视角视觉特征pc已离散到 0255 的三维坐标question 字符串 含 占位符的输入answers 字符串列表 自然语言、位置、模态或动作答案path 最多 2 个特征路径 初始/当前或初始/最终场景公开训练配置令数据类最多载入个场景。点太多时随机下采样太少时重复采样。注意仓库直接读取预计算好的 1408 维特征和点坐标从原始 RGB-D 生成这些特征的完整预处理脚本没有随当前代码一起发布。目标图像扩散样本每条 JSON 标注至少包含dataset, base_image_path, final_image_path, instruction若训练 RGB-D 模型代码约定深度文件与 RGB 同名并添加 _depth.png 后缀。缺失深度会用全零图替代。为了避免大数据集完全淹没小数据集公开实现先按数据集采样数据集的权重为这比按样本数线性采样更平衡同时仍让大数据集获得较高概率。目标点云扩散样本公开实现使用 RLBenchepisode 第一帧点云作为 start_pc最后一帧点云作为 end_pc每个点是 6 维训练默认采样 2048 个对应点起点和终点使用共同中心与共同半径归一化到单位球附近。共同归一化很重要如果起点和终点分别归一化它们之间真实的位移会被部分抹掉。统一接口交互 token 是整套方法的“插座”普通 LLM 只会输出词。3D-VLA 扩充词表让连续物理世界也能以 token 形式进入自回归建模。4.1 token 总表token 含义 示例… 中间插入一个静态 3D 场景的特征 初始状态、当前状态或目标状态… 明确标出被提及/操作的物体 bottom drawer 离散三维位置 6 个 token 表示 AABB… 请求/表示目标图像或 RGB-D 图像生成意图… 请求/表示目标点云 点云生成意图 机械臂绝对位置的离散分量 x、y、z 各一个 机械臂旋转的离散分量 3 个旋转分量gripper0/1 二值夹爪状态 闭合/打开具体编码约定依数据处理ACT_SEP 分隔连续两个动作 action 1 与 action 2 之间4.2 三维框怎样变成 6 个 token设某坐标分量的有效范围为常见的 256 桶均匀量化是于是例如一个量化后的框为答案就是重要边界论文和当前公开代码确认了 256 个桶以及 AABB 的 6-token 表示但没有公开原始数据到各桶的确切坐标范围和反量化规则。因此上式用于解释通用原理不能当作该仓库未发布预处理器的精确复现参数。4.3 7-DoF 动作怎样变成 token一个动作通常可写为其中前三维是机械臂末端绝对位置接着三维描述旋转是夹爪开合。连续六个值各量化为 256 桶夹爪保持二值aloc_qxaloc_qyaloc_qzarot_q1arot_q2arot_q3gripper_gACT_SEP这样动作预测就变成普通的下一 token 预测。优点是语言、空间框和控制命令可以由同一个 T5 解码器生成代价是量化会引入精度损失而且离散 token 本身不保证运动学可达或无碰撞。3D 语言主干场景如何进入 Flan-T5论文说模型“建立在 3D-LLM 之上”但初始化时并没有加载 3D-LLM 在室内场景/物体上的权重而是从 BLIP-2 Flan-T5 XL 开始训练因为其原训练域与机器人操作域差异较大。5.1 输入不是原始点云而是“点特征 点坐标”对每个场景公开代码接收每个 3D 点的多视角视觉特征每个点离散后的坐标。位置编码为三个一维位置编码的拼接。代码为每个坐标轴生成 469 维编码三轴共 1407 维再补到 1408 维并以 0.1 的比例加到视觉特征它的直觉是相同外观的两个抽屉不能只有相同的视觉表示还必须携带“一个在上、一个在下”的位置差异。5.2 Q-Former 把几千个点压缩成 32 个 token把 6400 个点直接作为 T5 token 成本很高。模型使用 32 个可学习 query通过 Q-Former 对点特征做交叉注意力再经线性层投影到 Flan-T5 XL 的隐藏维度 2048所以无论原场景采样 6400 还是更多点进入 T5 的每个场景始终是 32 个紧凑 token。5.3 是真正插入特征的位置输入文本先正常分词。例如The initial scene is . Close the bottom drawer.代码找到 的位置把对应场景的 32 个 Q-Former 输出紧接在它后面The initial scene is[3D_1] [3D_2] … [3D_32] .Close the bottom drawer.如果输入包含两个 就可以插入初始/最终、初始/当前等两个静态场景从而表达动态变化。这里的“动态”并不是视频 Transformer而是把多个静态 3D 快照按文本顺序交错输入。5.4 T5 生成所有类型的答案T5 的训练目标统一为 teacher-forcing 交叉熵padding token 被设为不参与损失。无论答案是自然语言、6 个位置 token、一段 …还是动作 token 序列都使用同一个损失。公开实现允许一条问题有多个去重答案collate 时会把同一输入复制到各答案上分别训练。数据中虽然计算了答案频率权重但当前 forward 没有把该权重乘入 loss。5.5 哪些参数训练哪些冻结模块 公开实现状态Flan-T5 主体 Transformer 冻结T5 输入 embedding 训练T5 输出 embedding / LM head 训练Q-Former 训练32 个 query token 训练Q-Former 到 T5 的线性投影 训练这样既保留 Flan-T5 的语言能力又让新增 token 和 3D 表示学会进入其语义空间。5.6 语言主干前向伪代码def forward_3d_vla(sample):# sample.pc_feat: [B, T, N, 1408]点的多视角视觉特征# sample.pc: [B, T, N, 3]离散到 0~255 的点坐标# sample.question: 含 T 个 占位符point_feature sample.pc_feat 0.1 * position_encode_xyz(sample.pc) # 每个场景用 32 个 query 汇聚 N 个点 scene_tokens q_former( querieslearnable_queries_32, key_valuepoint_feature ) scene_tokens linear_to_t5_dim(scene_tokens) # 768 - 2048 text_tokens t5_tokenize(sample.question) # 把每组 32 个场景 token 插到对应 scene 后 encoder_input insert_after_scene_tokens(text_tokens, scene_tokens) target t5_tokenize(sample.answer) target[target PAD] -100 # padding 不计入损失 logits flan_t5(encoder_input, labelstarget) return cross_entropy(logits, target)目标图像 / RGB-D 扩散模型