自动驾驶-VLA-训练数据格式统一【202505】:Impromptu VLA:多数据集统一与处理流程详解
Impromptu VLA(NeurIPS 2025):多数据集统一与处理流程详解
Impromptu VLA 的核心做法是:先对 8 个自动驾驶数据集进行时间频率统一和场景筛选,再将不同来源的视觉数据、车辆状态和规划信息转换为统一的问答式训练数据,最终用于 VLA 模型训练。
但有一个关键区别:
它不是将所有自动驾驶数据完整转换为统一的原始传感器数据库,而是针对 VLA 训练任务,构建统一的视觉—语言—动作监督数据。
论文:Impromptu VLA: Open Weights and Open Data for Driving Vision-Language-Action Models
- urlarXiv 论文https://arxiv.org/abs/2505.23757
- url论文 PDFhttps://arxiv.org/pdf/2505.23757
- url官方 GitHub 代码https://github.com/ahydchh/Impromptu-VLA
- urlHugging Face 数据集https://huggingface.co/datasets/aaaaaap/ImpromptuVLAData
一、原始数据来自哪些数据集?
论文整合了 8 个公开数据集,从约 200 万个候选片段中筛选出约 8 万个片段。turn832232view3
| 原始数据集 | 原始频率 | 相机数量 | 最终标注片段 |
|---|---|---|---|
| Mapillary | 2 Hz(假定) | 1 | 22,062 |
| ONCE | 2 Hz | 7 | 18,093 |
| NAVSIM | 2 Hz | 8 | 18,600 |
| nuScenes | 2 Hz | 6 | 11,370 |
| Waymo | 10 Hz | 5 | 7,530 |
| Argoverse 2 | 20 Hz | 7 | 2,490 |
| KITTI | 10 Hz | 1 | 930 |
| IDD | 15 Hz | 1 | 930 |
| 合计 | — | — | 约 80,000 |
数据来自论文 Table 1。表中频率是作者使用的数据源频率,其中 Mapillary 的 2 Hz 是论文假设值,不应理解为其所有原始数据都以该频率采集。
这意味着:
- 原始相机数量不一致。
- 图像分辨率不一致。
- 时间采样频率不一致。
- 各数据集可用的车辆状态、轨迹和语义标注不一致。
因此,作者首先解决的是 时间对齐(Temporal Alignment) 与 场景级数据标准化(Scene-level Standardization),而不是要求所有数据集具有完全相同的传感器配置。
链接更正:上文的 Hugging Face 数据集地址应为 urlaaaaaap/unstructedhttps://huggingface.co/datasets/aaaaaap/unstructed,这是官方 GitHub README 实际指向的仓库。turn832232view1
二、完整的数据处理流程

依据论文 Section 2.2、2.3、Appendix C 及官方脚本整理。
步骤 1:非结构化场景挖掘(Unstructured Scenario Mining)
作者先从汇总的数据中按固定间隔抽取约 10% 的片段,让 Qwen2.5-VL-72B 生成开放式场景描述。
接着利用 VLM 将常规与非常规场景分开,并在约 1,000 条人工独立标注的场景描述上迭代改进分类提示词,最终得到四种主要类别。turn943329view1
| 场景类别 | 典型示例 |
|---|---|
| 道路边界不清晰(Roads with Unclear Boundaries) | 无车道线、乡村土路 |
| 临时交通规则变化(Temporary Traffic Rule Changes) | 道路施工、临时交通标志 |
| 非常规动态障碍物(Unconventional Dynamic Obstacles) | 动物穿越、异常移动的车辆 |
| 恶劣道路条件(Challenging Road Conditions) | 积雪、坑洼、浓雾、强光眩目 |
因此,它不是对全部原始场景进行等比例训练,而是主动提高困难场景的比重。
步骤 2:统一时间频率和轨迹窗口
全部来源统一到 2 Hz,即每 0.5 秒取一个采样时刻。
每个关键时刻的时间窗口定义为:

H=1.5 s,F=5.0 s,Δt=0.5 sH=1.5\,\mathrm{s},\qquad F=5.0\,\mathrm{s},\qquad \Delta t=0.5\,\mathrm{s}H=1.5s,F=5.0s,Δt=0.5s
对应过去 3 个采样点和未来 10 个目标轨迹点。
作者还把相邻片段组织成最长约 15 秒的 局部筛选组(Local-filter Pack)。只有某种场景特征在这个时间范围内持续出现,才保留该类别判断,以降低偶发误检的影响。最终数据主要保存独立的关键片段,而不是整个 15 秒筛选组。turn138791view2
步骤 3:统一为七种问答任务
这是最重要的部分。
作者没有将不同数据集直接映射成完全一致的底层传感器字段,而是将可获得的信息转换为七种 任务问答对(Task Q&A Pairs):
| 任务 | 任务名称 | 训练目标 |
|---|---|---|
| Q1 | 弱势交通参与者识别(VRU Identification) | 识别行人、骑行者等 |
| Q2 | 运动意图预测(Motion Intention Prediction) | 预测其他车辆的速度和路径意图 |
| Q3 | 规划解释(Planning Explanation) | 解释为什么采取某种驾驶决策 |
| Q4 | 交通信号识别(Traffic Signal Detection) | 判断红灯、绿灯、黄灯或无信号 |
| Q5 | 场景描述(Scene Description) | 描述交通环境及影响规划的要素 |
| Q6 | 高层动作规划(Meta-action Planning) | 输出加速、减速、直行、变道等决策 |
| Q7 | 端到端轨迹预测(End-to-End Trajectory Prediction) | 输出自车未来的连续轨迹点 |
这些任务的监督来源并不完全一样。例如,VRU 信息依赖原始真实标注,Q6 的动作类别可由轨迹规则生成,而场景描述、规划解释等任务可利用 VLM 生成并进行人工审核。turn282347view0turn138791view1
关键限制:并不是每个数据样本都具备 Q1~Q7 的全部标注。 论文附录 C 明确指出,任务可用性取决于源数据集本身的标注丰富程度。
三、统一之后的数据究竟长什么样?
官方代码中,整理后的训练样本采用以下消息形式:
{
"id": "sample_00001",
"images": [
"path/to/front.png",
"path/to/front_right.png",
"path/to/front_left.png"
],
"messages": [
{
"role": "user",
"content": "Question text with <image> placeholders"
},
{
"role": "assistant",
"content": "Answer text"
}
]
}
这里的 id、images 和 messages 是从官方 data_organize.py 提取出的实际字段。turn906176view1
Q7:一个完整的轨迹训练样本示例
下面是依据官方 q7_navsim.py 和 format.py 代码构造的示意记录,不是从真实数据集中复制的原始样本。为了保持与实际训练提示词一致,示例中的模型输入输出使用英文。
{
"id": "navsim_example_001",
"images": [
"navsim/images/front.png",
"navsim/images/front_right.png",
"navsim/images/front_left.png"
],
"messages": [
{
"role": "user",
"content": "You are an autonomous driving agent. You have access to multi-view camera images: front <image>, front right <image>, front left <image>. Your task is to do your best to predict future waypoints for the vehicle over the next 10 timesteps. Previous ego states over the last 1.5 seconds (0.5s intervals), with x forward and y left:\n(t-1.5s) [-9.0, 0.0], Acceleration: X 0.0, Y 0.0 m/s^2, Velocity: X 6.0, Y 0.0 m/s\n(t-1.0s) [-6.0, 0.0], Acceleration: X 0.0, Y 0.0 m/s^2, Velocity: X 6.0, Y 0.0 m/s\n(t-0.5s) [-3.0, 0.0], Acceleration: X 0.0, Y 0.0 m/s^2, Velocity: X 6.0, Y 0.0 m/s"
},
{
"role": "assistant",
"content": "<PLANNING>Predicted future movement for the next 5 seconds, sampled at 0.5-second intervals, in ego-centric coordinates [x, y] (meters):\n[3.0, 0.0],\n[6.0, 0.0],\n[9.0, 0.0],\n[12.0, 0.0],\n[15.0, 0.0],\n[18.0, 0.0],\n[21.0, 0.0],\n[24.0, 0.0],\n[27.0, 0.0],\n[30.0, 0.0]</PLANNING>"
}
]
}
样本中,images 是视觉输入,user.content 给出历史状态与规划问题,assistant.content 通过文本输出轨迹标签。轨迹采用以当前自车为参考的坐标表示,$x$ 轴向前,$y$ 轴向左。
特别值得注意的是:它并非使用一个独立的连续动作回归头输出所有轨迹,而是将轨迹坐标表示为语言模型可生成的文本序列。
为了防止模型混淆不同任务,format.py 会针对任务输出添加专用标记:
| 任务 | 任务标记 |
|---|---|
| Q2 | <DYNAMIC OBJECTS> |
| Q6 | <SPEED PATH PLAN> |
| Q7 | <PLANNING> |
这些是实际代码中的标记写法。turn138791view2
四、官方代码如何实现数据统一?
项目将原始数据解析和后续训练格式转换分成两个阶段。
第一阶段:从原始数据生成问答数据。
代码主要位于:
data_qa_generate/
例如,NAVSIM 相关文件包括:
data_engine/datasets/navsim/navsim_qa.pydata_engine/datasets/navsim/q7_navsim.py
这里负责从 NAVSIM 场景对象提取相机图像、自车速度、加速度和轨迹,进一步生成问题及答案。turn138791view2
第二阶段:将已发布的问答数据统一为训练 JSON。
这部分使用三个脚本:
| 脚本 | 具体作用 |
|---|---|
scripts/data_organize.py | 将图片、问题和答案整理为 id/images/messages 结构,并按来源和 Q1~Q7 分类 |
scripts/format.py | 检查图片数量与文本中的 <image> 标记是否对应,并补充任务标签 |
scripts/merge_data.py | 跨数据集合并同类问答数据,生成总训练集 |
按默认路径,可执行:
python scripts/data_organize.py --split train
python scripts/format.py --split train
python scripts/merge_data.py --split train
python scripts/data_organize.py --split val
python scripts/format.py --split val
python scripts/merge_data.py --split val
原始文件位于 ./ImpromptuData 下,并须预先整理为代码预期的分数据集、分训练/验证集目录。
最终数据目录如下:
data/
├── train/
│ ├── navsim/
│ │ ├── q1.json
│ │ ├── ...
│ │ └── q7.json
│ ├── waymo/
│ └── ...
├── val/
│ ├── navsim/
│ └── ...
└── jsons/
├── train/
│ ├── q1.json
│ ├── ...
│ ├── q7.json
│ └── train.json
└── val/
├── q1.json
├── ...
├── q7.json
└── val.json
这里采用脚本当前默认的 jsons 目录名称,和 README 中笼统描述的输出目录略有不同。turn906176view1turn906176view2
五、对于 nuPlan → VLA,有哪些可以直接借鉴的部分?
这篇论文主要使用的是 NAVSIM 数据入口,而不是将完整 nuPlan SQLite 日志原样并入训练。因此,准备利用原始 nuPlan 进行 VLA 训练时,需要自己实现类似的场景解析与样本转换接口。
| 处理环节 | Impromptu VLA 已有实现 | 对 nuPlan 的适用性 |
|---|---|---|
| 多数据集统一频率 | 2 Hz | 可以直接参考 |
| 统一时间窗口 | 历史 1.5 秒、未来 5 秒 | 可以直接参考 |
| 统一坐标表达 | 自车相对坐标 | 可以参考坐标转换 |
| 困难场景筛选 | VLM + 四类场景分类 | 可以参考 |
| 语言监督生成 | 多种 Q&A 和人工验证 | 可以参考 |
| 专家轨迹提取 | NAVSIM 等数据适配代码 | 原始 nuPlan 需自行适配 |
| 缺失模态处理 | 按可用任务生成 Q&A | 可以参考,但不能假定所有来源均有轨迹 |
| 统一训练样本 | images + messages | 可以直接采用 |
还应注意,论文所述的全量数据构建方法,并不等于公开代码可以一键完整重现。例如,仓库中有用户反馈部分 Q3/Q4/Q5 的原始生成答案为空,以及困难场景筛选代码的复现问题,因此应将已发布数据集和从零重建标注视为两种不同的工作流程。
六、最终结论
Impromptu VLA 实际完成了三种统一:
- 时间层统一(Temporal Unification):2 Hz,历史 1.5 秒,未来 5 秒。
- 语义层统一(Semantic Unification):将多数据源转成七类驾驶问答任务。
- 训练接口统一(Training Interface Unification):通过
images和messages构建统一的 VLM/VLA 训练接口。
但它 没有证明八个数据集的全部样本均具有相同的视觉模态和真实动作标签。
针对你前面关注的 nuPlan 原始数据格式问题,最值得直接阅读和复用的文件是:
urlq7_navsim.py:NAVSIM 自车轨迹转 VLA 监督数据的实现https://github.com/ahydchh/Impromptu-VLA/blob/main/data_qa_generate/data_engine/datasets/navsim/q7_navsim.py
这个脚本具体展示了从场景帧读取 历史自车状态(Ego History),构造 自车坐标系(Ego-centric Coordinates) 下的未来 10 个轨迹点,并最终生成 VLA 训练问答数据的过程。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)