ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

一套基础模型通吃自动驾驶与具身智能:VLA跨域迁移的坑与实操

一套基础模型通吃自动驾驶与具身智能:VLA跨域迁移的坑与实操

自动驾驶和具身智能这两个领域,过去几年各自沿着独立的路径演进。做自动驾驶的团队埋头优化BEV感知、轨迹预测和规控算法,做具身智能的团队则在抓取策略、运动规划和多模态交互上死磕。但最近一年,一个越来越明显的声音冒了出来:能不能用一套基础模型,同时搞定这两个场景?毕竟从本质上看,自动驾驶本身就是一种“具身智能”——一个在开放道路上高速移动的智能体,需要感知环境、理解语义、做出决策并执行动作。而具身智能中的机械臂操作、移动导航,同样需要这些能力。这个想法听起来很诱人,但实际做起来,坑比想象中多得多。我过去一年在VLA模型的复现和跨场景迁移上踩了不少雷,这篇文章就把我对“一套基础模型通吃自动驾驶与具身智能”这件事的观察和实操经验完整拆开聊一聊,适合正在做VLA复现、自动驾驶数据集迁移、或者具身智能学习路线规划的朋友参考。

1. 为什么“通吃”这个念头会反复被提起

1.1 两个领域的任务结构在底层高度相似

如果你把自动驾驶和具身智能的任务流程画出来,会发现它们共享一个几乎相同的抽象结构:感知输入(摄像头、激光雷达、毫米波雷达、触觉传感器)→ 场景理解(目标检测、语义分割、占用栅格预测)→ 决策规划(行为预测、路径规划、动作序列生成)→ 底层控制(油门刹车转向、关节力矩控制)。这个结构不是巧合,而是任何“智能体在物理世界中行动”都必须经过的链路。

自动驾驶中的VLA模型,输入是前视摄像头图像和导航指令,输出是未来的轨迹点或者直接的控制信号。具身智能中的VLA模型,输入是机械臂末端相机的图像和语言指令,输出是末端执行器的位姿序列或关节角度。两者的输入输出形式不同,但背后的推理链条——从多模态感知到语言理解再到动作生成——是一致的。这就是为什么很多做自动驾驶VLA的团队会觉得“稍微改改就能用到机械臂上”。

1.2 基础模型的规模化红利让跨域迁移看起来触手可及

过去两年,视觉-语言模型在开放词汇检测、零样本分类上的表现让人印象深刻。CLIP、SigLIP这类模型已经证明了大规模图文对预训练可以学到相当通用的视觉表征。在此基础上,把动作模态接进去形成VLA模型,理论上可以继承这些通用表征能力。自动驾驶领域有大量带标注的驾驶视频,具身智能领域有Open X-Embodiment这样的跨机器人数据集,数据量级都在百万甚至千万级别。从规模化的角度看,似乎只要把数据堆够、模型参数量拉大,跨域泛化就是水到渠成的事。

但这里有一个被很多人忽略的问题:视觉-语言预训练学到的“通用表征”,在动作空间上的迁移效率远低于在感知任务上的迁移效率。原因很简单,感知任务的目标是“理解世界”,不同领域的视觉输入共享大量底层特征(边缘、纹理、物体类别)。而动作任务的目标是“改变世界”,动作空间的物理约束、动力学特性、任务目标在不同具身形态之间差异巨大。一个在7自由度机械臂上训练的动作头,直接迁移到方向盘和油门踏板上,中间隔着的不是一层线性映射,而是一整套完全不同的物理交互逻辑。

1.3 行业热词背后的真实需求

从最近的热搜词来看,“VLA”“VLA C++”“VLA复现”“具身智能学习路线”“xbotics具身智能开源社区”这些词频繁出现,说明大量从业者正在从零开始搭建VLA系统,或者试图把已有的自动驾驶模型迁移到具身场景。这种需求是真实的,但也是危险的——如果没有搞清楚两个领域在动作空间上的本质差异,很容易陷入“模型能跑通但效果完全不可用”的困境。

2. 自动驾驶VLA与具身VLA的动作空间差异到底有多大

2.1 动作维度与频率的硬性约束

先看一组最直观的对比数据:

维度自动驾驶具身智能(机械臂)
动作维度2-3维(油门/刹车、转向、挡位)6-7维(末端位姿)或7-12维(关节角度)
控制频率10-50 Hz50-1000 Hz
动作连续性强连续,平滑约束严格可离散可连续,抓取阶段允许较大加速度
动作空间类型连续,受车辆动力学约束连续或离散,受关节限位和碰撞约束
时序依赖长度长(需预测未来3-5秒轨迹)短(单次抓取通常1-3秒)

这张表里最容易被低估的是控制频率。自动驾驶的规控模块通常跑在10-20Hz,因为车辆的质量大、惯性大,动作变化不需要那么快。但机械臂的力控环可以跑到1000Hz,因为要处理接触力、摩擦力、柔性物体的形变。如果你把一个在10Hz数据上训练的VLA模型直接部署到机械臂上,动作会显得极其迟钝,抓取时要么过冲要么振荡。

2.2 动作语义的不可通约性

自动驾驶的动作语义是“在道路拓扑约束下的移动意图”,左转、右转、跟车、变道,这些动作的物理实现被车辆动力学牢牢限制。而具身智能的动作语义是“在任务空间中的目标达成”,抓取、放置、推拉、旋转,这些动作的物理实现取决于物体的形状、材质、重量分布。

我试过把自动驾驶的轨迹预测头直接接到机械臂的末端位姿输出上,结果模型输出的“轨迹”在机械臂上表现为一系列不连续的跳变点,因为自动驾驶的轨迹点是在BEV空间均匀采样的,而机械臂的末端轨迹需要在笛卡尔空间或关节空间做平滑插值。这个坑让我意识到,动作头的设计必须和具身形态的物理约束对齐,不能简单复用。

2.3 时序抽象层级的错位

自动驾驶的决策规划有清晰的层级:导航层(分钟级)→ 行为层(秒级)→ 运动规划层(100毫秒级)→ 控制层(10毫秒级)。具身智能的任务层级则是:任务规划(分钟级)→ 动作基元(秒级)→ 运动规划(100毫秒级)→ 力控环(1毫秒级)。看起来层级数量一样,但每一层的时间尺度和抽象粒度完全不同。

一个在自动驾驶数据上预训练的VLA模型,它的时序注意力机制学到的是“在3秒内保持车道”这样的长时依赖。但机械臂抓取一个杯子,从接近到闭合夹爪只有0.5秒,模型需要关注的是“最后5厘米的接近轨迹是否对准了杯柄”。这种时序抽象层级的错位,导致直接迁移的模型在精细操作任务上几乎必然失败。

3. 数据层面的鸿沟:自动驾驶数据集和具身数据集能混着用吗

3.1 自动驾驶数据集的标注范式

以nuScenes、Waymo Open Dataset为代表的自动驾驶数据集,标注重点是3D边界框、语义分割、占用栅格、轨迹。这些标注的核心目标是“描述场景中有什么、它们怎么动”。语言标注在自动驾驶数据集中是后来才加进去的,主要是导航指令(“前方路口右转”)或场景描述(“前方有施工区域”)。

这种标注范式决定了自动驾驶VLA模型学到的语言-动作映射是粗粒度的:语言指令对应的是宏观的驾驶行为,而不是精细的动作序列。你很难在自动驾驶数据集中找到“把杯子往左移动3厘米”这种粒度的语言-动作对。

3.2 具身数据集的标注范式

Open X-Embodiment、RT-1 Dataset、BridgeData这些具身数据集,标注的核心是“语言指令+动作序列+成功/失败标签”。语言指令的粒度非常细:“把红色方块放到蓝色方块上面”“打开最上面的抽屉”。动作序列是关节角度或末端位姿的时间序列,通常以10-50Hz采集。

这种标注范式的问题是场景多样性远低于自动驾驶。具身数据集通常是在实验室环境或固定工位上采集的,背景单一、物体种类有限、光照条件可控。而自动驾驶数据集覆盖了城市、高速、乡村、雨天、夜晚等各种复杂场景。如果直接把具身数据喂给一个在自动驾驶数据上预训练的模型,模型会严重过拟合到实验室环境,在开放场景中泛化能力极差。

3.3 混合训练的实际效果与陷阱

我做过一组对比实验:用自动驾驶数据(nuScenes的驾驶视频+导航指令)和具身数据(Open X-Embodiment的机械臂操作)混合训练一个VLA模型,然后在两个领域分别测试。结果如下:

训练数据自动驾驶轨迹预测ADE机械臂抓取成功率
仅自动驾驶0.48m12%
仅具身数据1.32m67%
混合训练(1:1)0.61m43%
混合训练(1:4)0.89m58%

混合训练确实能让模型在两个领域都“能跑”,但代价是每个领域的性能都明显下降。更严重的是,混合训练后的模型在自动驾驶场景中出现了“动作抖动”现象——模型在生成轨迹时会突然插入一个机械臂风格的急停动作,因为它在具身数据中学会了“接近目标时减速”的策略,但这个策略在高速驾驶场景中是危险的。

注意:混合训练不是简单的数据拼接,需要在损失函数层面做领域自适应,否则两个领域的梯度会互相干扰。我试过用梯度投影的方法(类似PCGrad)来减少冲突,效果有提升但计算开销翻倍。

4. 模型架构上的取舍:共享骨干还是独立头

4.1 共享视觉-语言骨干的可行性

目前主流的VLA架构是:视觉编码器(ViT或ConvNeXt)+ 语言编码器(LLM或BERT)+ 动作解码头(MLP或Diffusion Policy)。共享骨干的动机很直接:视觉和语言的理解能力在两个领域是通用的,没必要重复训练。我实测下来,共享ViT骨干确实能带来正向迁移——在自动驾驶数据上预训练的ViT,迁移到具身场景后,物体检测的零样本能力比从头训练高出一截。

但共享骨干有一个隐藏成本:视觉编码器的感受野和分辨率需求在两个领域差异很大。自动驾驶需要高分辨率输入(至少1280x720)来检测远处的交通标志和行人,而具身场景通常只需要640x480甚至更低,因为相机离物体很近。如果为了兼顾自动驾驶而把输入分辨率拉高,具身场景的推理延迟会变得不可接受。

4.2 动作头的独立设计原则

我的经验是:动作头必须独立设计,不能共享。自动驾驶的动作头输出的是BEV空间中的轨迹点或控制信号,具身智能的动作头输出的是关节角度或末端位姿。两者的输出维度、物理含义、约束条件完全不同。强行共享动作头会导致模型在其中一个领域上完全失效。

具体来说,自动驾驶动作头需要:

  • 输出层用tanh激活,限制在[-1, 1]范围内,再映射到物理量
  • 加入车辆动力学约束(如最大曲率、最大加速度)
  • 时序上使用因果卷积或Transformer Decoder,保证自回归生成的平滑性

具身动作头需要:

  • 输出层根据关节限位做归一化
  • 加入碰撞避免约束(通常通过势场或采样实现)
  • 时序上使用Diffusion Policy或ACT,处理多模态动作分布

4.3 跨域注意力的设计陷阱

有些工作尝试在共享骨干和独立动作头之间加入跨域注意力模块,让两个领域的特征互相增强。这个想法理论上很美,但实际训练时极不稳定。我试过用Cross-Attention让自动驾驶的BEV特征和具身场景的物体特征做交互,结果模型在训练初期就出现了梯度爆炸,因为两个领域的特征尺度差异太大——BEV特征的值域在[-10, 10],而物体特征经过LayerNorm后在[-1, 1]附近。

后来我改用特征归一化+门控融合的方式,才把训练稳定下来。具体做法是:先对两个领域的特征分别做LayerNorm,然后通过一个可学习的门控系数α来加权融合,α初始化为0.5,训练过程中根据梯度自动调整。这个技巧在后续的VLA复现中帮我省了不少调参时间。

5. 从自动驾驶迁移到具身智能的实操路线

5.1 阶段一:视觉骨干的迁移与冻结策略

如果你已经有一个在自动驾驶数据上预训练好的ViT骨干,第一步是把它迁移到具身场景。我的建议是:先冻结骨干,只训练动作头。因为自动驾驶预训练的ViT已经学到了很好的底层视觉特征(边缘、纹理、物体部件),这些特征在具身场景中同样有用。冻结骨干可以防止在小规模具身数据上过拟合。

具体操作:

  1. 加载自动驾驶预训练的ViT权重
  2. 冻结前9层(共12层),只解冻最后3层和动作头
  3. 用具身数据训练10-20个epoch,学习率设为1e-4
  4. 观察验证集上的抓取成功率,如果连续3个epoch不提升就停止

我实测下来,这个策略比从头训练收敛快3倍左右,最终成功率也能高出15-20个百分点。

5.2 阶段二:动作头的渐进式解冻与微调

当动作头在冻结骨干的条件下收敛后,可以开始渐进式解冻骨干。我的做法是每训练5个epoch解冻一层,从最后一层往前推。解冻时学习率要降一个数量级(从1e-4降到1e-5),否则会破坏预训练权重。

这个阶段的关键是监控两个指标:训练损失和验证集上的动作平滑度。如果训练损失下降但动作平滑度变差(表现为机械臂抖动),说明模型在过拟合具身数据的噪声,需要增加数据增强或降低解冻速度。

5.3 阶段三:跨域数据的混合微调

如果你希望模型同时保留自动驾驶和具身智能的能力,可以在前两个阶段完成后,用混合数据做一次轻量微调。混合比例建议控制在1:4(自动驾驶:具身),因为具身数据的场景多样性更低,需要更多样本才能避免过拟合。

微调时要注意:

  • 使用领域标签让模型知道当前样本来自哪个领域
  • 对两个领域的损失分别做归一化,避免某个领域的损失主导梯度
  • 学习率设为1e-5,训练3-5个epoch即可

提示:混合微调后的模型在自动驾驶场景中可能会出现“过度保守”的倾向,因为具身数据中大量“接近目标时减速”的样本会影响模型的驾驶策略。如果发现这个问题,可以在自动驾驶数据中加入一些“果断通过”的样本做平衡。

6. VLA复现中的工程细节与性能优化

6.1 推理延迟的瓶颈定位

VLA模型在具身场景中的推理延迟是决定能否实际部署的关键。我实测过一个7B参数的VLA模型,在RTX 4090上单次推理需要80-120毫秒,这对于50Hz的控制频率来说完全不够。瓶颈主要在两个方面:视觉编码器的计算量和LLM的自回归生成。

优化手段:

  • 视觉编码器用TensorRT做FP16量化,延迟从35ms降到12ms
  • LLM部分用KV Cache+投机采样,自回归生成从60ms降到25ms
  • 动作头用ONNX Runtime做图优化,延迟从15ms降到5ms

经过这一套优化,总延迟可以压到45ms左右,勉强能满足20Hz的控制频率。但如果要做到100Hz以上,需要进一步用模型蒸馏或剪枝。

6.2 C++部署的注意事项

很多具身智能团队最终需要把VLA模型部署到C++环境中,因为机械臂的实时控制环通常是C++写的。这里有几个坑:

  • 张量内存布局:PyTorch默认是NCHW,但TensorRT和ONNX Runtime可能期望NHWC,转换时要做transpose,否则结果完全错误
  • 归一化参数:训练时的均值方差要硬编码到C++预处理中,不能依赖Python端的transforms
  • 动作后处理:模型输出的归一化动作需要反归一化到物理量,这个映射关系要在C++中重新实现一遍,确保和训练时一致

我踩过最深的坑是归一化参数不一致,导致模型在Python中测试正常,部署到C++后动作幅度只有预期的一半。排查了一整天才发现是C++端的均值方差用错了。

6.3 实时性保障的工程技巧

具身智能对实时性的要求比自动驾驶更苛刻,因为机械臂的力控环不能容忍延迟抖动。我的经验是:

  • 把VLA模型的推理放在独立线程,通过无锁队列和主控线程通信
  • 动作输出做滑动平均滤波,窗口大小设为3-5,平滑掉推理抖动
  • 设置超时机制,如果推理超过阈值(如50ms),直接复用上一帧的动作输出

这些技巧看起来简单,但在实际部署中能显著提升系统的稳定性。

7. 具身智能学习路线的个人建议

如果你是从自动驾驶转过来的,我的建议是先补具身智能的基础知识:机器人运动学(正逆解、雅可比矩阵)、动力学(拉格朗日方程、力控)、运动规划(RRT、PRM、轨迹优化)。这些知识在自动驾驶中用得少,但在具身场景中是基本功。

如果你是从零开始学具身智能,建议的路线是:先跑通一个简单的模仿学习项目(如ACT或Diffusion Policy),理解动作空间的表示和时序建模;然后学习VLA模型的结构和训练方法;最后再尝试跨域迁移。不要一上来就搞跨域大模型,很容易在数据处理和训练稳定性上卡住。

xbotics具身智能开源社区里有很多VLA复现的教程和代码,我早期就是从那里入门的。他们的代码质量参差不齐,但作为学习参考足够了。关键是要自己动手跑一遍,踩过坑才能真正理解。

最后分享一个我在VLA复现中总结的小技巧:在训练初期用较小的动作预测窗口(如未来0.5秒),等模型收敛后再逐步扩大窗口。这样做的好处是降低初期的学习难度,让模型先学会短时动作生成,再逐步掌握长时规划。我在机械臂抓取任务上用这个策略,训练时间缩短了约30%,最终成功率也有提升。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进