资讯动态

LMDrive 数据集构建实战:从0到1打造高质量自动驾驶训练数据

发布时间:2026/8/16 16:42:46 来源:尧图企业网站定制
LMDrive 数据集构建实战从0到1打造高质量自动驾驶训练数据【免费下载链接】LMDrive[CVPR 2024] LMDrive: Closed-Loop End-to-End Driving with Large Language Models项目地址: https://gitcode.com/gh_mirrors/lm/LMDrive「为什么我明明照着开源项目复现了模型效果却差了一大截」这是我在折腾自动驾驶相关项目时最常见的困惑直到我亲手构建过一次数据集才明白数据集的构建质量往往比模型结构更能决定最终上限。LMDriveCVPR 2024 的闭环端到端自动驾驶系统的核心思路是让大语言模型直接接管驾驶决策而它训练的前提就是一份「看得懂、听得懂、开得动」的多模态驾驶数据。这篇文章就带你走一遍从零构建数据集的全流程讲清楚每一步到底在解决什么问题。先把话说在前面你的模型到底在吃什么很多人拿到 LMDrive 的第一反应是「赶紧跑通训练脚本」但训练脚本只是流水线的最后一环。在它之前有一整条数据链路多视角 RGB 图像 LiDAR 点云 → 视觉编码器 → 大语言模型 → 控制信号。这意味着模型同时要消化三类信息——图像里的路况、导航指令里的语义、以及车辆自身的状态。这张 LMDrive 数据处理流程图揭示了数据集的真实用途每个时间步的感知数据要和导航指令一起喂给 LLM模型判断「指令完成了吗」没有就继续迭代完成才输出控制信号。所以你的数据集里每一条「观测 指令 → 正确动作」的样本都缺一不可。搞清楚了这一点你就能理解为什么后面每个处理步骤都绕不开拼接四视角图像是为了给模型一张「全景」而不是四张割裂的照片清洗堵车片段是为了不让模型学到「原地发呆」的错误驾驶行为给数据打上导航指令标签是为了让 LLM 真的「听得懂」人在说什么。第一关三步跑通最小数据集闭环第一步先把目录骨架立起来克隆仓库并安装依赖后克隆地址https://gitcode.com/gh_mirrors/lm/LMDrive第一件要做的事不是采集而是把数据存放的「抽屉」提前做好。项目里的dataset/init_dir.py干的就是这件事python dataset/init_dir.py它会生成sub-0到sub-3四个子目录每个目录下都有一个results文件夹。为什么要四个这是为并行采集预留的——不同子目录跑不同的任务互不干扰最后再汇总。你很快会看到这个设计的用处。第二步把「路线」和「场景」配对采集数据的本质是让 CARLA 模拟器里的自动驾驶代理按照预设路线跑一遍同时记录沿途的传感器数据。而「跑哪条路、路上遇到什么事」由data_collection/generate_bashs.py里的一个字典决定routes[training_routes/routes_town01_short.xml] scenarios/town01_all_scenarios.json routes[training_routes/routes_town02_tiny.xml] scenarios/town02_all_scenarios.json左边是路线文件右边是该路线上会随机触发的交通场景。short 代表短路线、tiny 代表更短的路线long 则是完整的长路线——路线长短直接影响一次采集的时长和数据量。运行这个脚本后它会在data_collection/bashs/sub-0/到sub-3/下生成一批采集脚本每个脚本都写好了端口、种子、数据保存路径。第三步并行启动采集data_collection/generate_batch_collect.py会把这些脚本打包成一批并行任务python data_collection/generate_batch_collect.py bash batch_run/run_route_routes_town01_short.sh每个脚本内部最终调用的是leaderboard/leaderboard_evaluator.py配合leaderboard/team_code/auto_pilot.py这个自动驾驶代理来真实地「开车」。而data_collection/auto_agent.yaml里有两个参数值得你多看一眼save_skip_frames: 2 # 每2帧保存一次控制数据量 waypoint_disturb: 0.2 # 给参考路径加一点扰动让数据更真实避坑提醒采集前务必确认 CARLA 版本与 PythonAPI 路径匹配base_script.sh 里写死了carla-0.9.10-py3.7的 egg 路径。另外四个并行任务各占一个端口2000、2002、2004、2006端口被占用是采集失败的头号原因。跑完你应该看到每个sub-N目录下出现data/文件夹里面按路线分目录每个目录下有rgb_front、rgb_left、rgb_right、rgb_rear、lidar、measurements、actors_data、affordances等子文件夹——四视角图像、点云、测量数据、交通参与者、场景属性全都齐了。到这里最小闭环就跑通了你已经有一份「能用但还很粗糙」的原始数据。第二关怎样让数据从「能用」变成「够用」第一次跑通后你会发现一个问题跑十条tiny路线数据看起来都差不多——直线、右转、停车翻来覆去就那几样。而 LLM 驾驶模型最需要的恰恰是语义的丰富性左转、右转、直行、变道、环岛、跟车、红绿灯、行人、连续转弯……所以这一关的核心问题是如何低成本地让数据更丰富答案藏在generate_bashs.py的路由表里。你只需要做三件事换更多路线把routes_town01_short.xml换成 town02~town10 的路线不同城镇的布局差异本身就是最大的多样性来源换更长的路线long路线会覆盖交叉路口、环岛、多车道数据里自然涌现出「连续两次转弯」「进入环岛第 3 出口」这类复杂指令调整扰动与种子auto_agent.yaml里的waypoint_disturb越大同一条路线每次跑的轨迹差异越大配合不同随机种子一条路线能「跑出花来」。经验小结自动驾驶数据集的多样性不是靠堆数量而是靠**「路线 × 场景 × 天气 × 扰动」四个维度的组合**。同样的数据量覆盖 10 个城镇远好过反复跑同一条路。第三关如何判断采集到的数据该删还是该留数据多了问题也来了。你翻看采集结果会发现有些片段非常可疑车在路口停了几十秒周围车辆却越来越少——这不是在等红绿灯而是被别的车堵死了。如果这种「堵车」数据混进训练集模型会学到「遇到路口就停车」的错误行为。这就是数据清洗要解决的问题。项目里这一关拆成了两步逻辑非常清晰第一步先建索引。tools/data_preprocessing/get_list_file.py会把所有路线汇总成一份dataset_index.txt同时做一道门槛检查——帧数少于 32 的路线直接剔除这些多半是采集中断的残次品。第二步再统计「堵车」。batch_stat_blocked_data.py用一条很聪明的判定规则来发现堵车片段车速低于 0.1 m/s基本没在动前方没有红灯排除正常等灯刹车状态为真代理想走但走不了连续持续 10 帧以上且周围车辆在减少。满足这些条件的就是「被堵住」的片段脚本会把路线 起始帧 持续长度记进blocked_stat.txt。先统计、后删除是这一关的原则——先看清问题再动手避免误删。最后一步才是删除。batch_rm_blocked_data.py读取统计结果把阻塞段的图像、点云、测量数据一并删掉而且删的时候特意留了几帧缓冲不是从头删到尾避免把正常数据的边缘也误伤。避坑提醒清洗脚本都是批处理、会直接改文件务必先在副本数据上跑一遍确认blocked_stat.txt里的判定合理后再上正式数据。数据删了就真的没了。跑完你应该看到dataset_index.txt里的路线变短了异常路线的帧数被修正整个数据集不再包含「原地罚站」的毒样本。第四关让数据带上「导航指令」模型才能听懂人话到这里数据在物理上是干净的但还缺最关键的一环语义标签。LMDrive 的模型训练时输入是「现在看到什么 导航要我做什么」输出是「该打多少方向、该踩多少油门」。而原始传感器数据里根本没有「指令」这个概念——这是数据集构建里最容易被忽视、却也最见功夫的一步。tools/data_parsing/目录下的脚本就是干这个的。它把规则拆成了四类turn_rules.py转弯类指令左转、右转、直行、环岛第几个出口、连续转弯follow_rules.py跟车类指令沿当前车道、跟随前车、驶入某方向notice_rules.py注意类指令前方有行人、红绿灯状态other_rules.py其他场景指令。parse_instruction.py会逐条路线、逐帧读取处理好的measurements_full用这些规则类去匹配当前行驶状态一旦匹配成功就生成一条带指令的训练样本{ instruction: Turn-03-L, instruction_id: 4, town_id: 1, weather_id: 2, route_path: sub-0/data/xxx, route_frames: 1200, bad_case: False }所有样本会汇总到navigation_instruction_list.txt这就是喂给大语言模型的「说话素材」。注意字段里的town_id、weather_id、route_path——这些元信息让模型能区分「在哪个城市、什么天气下做出的决策」对泛化能力至关重要。经验小结这一步的本质是把「人类驾驶员会怎么描述这次操作」翻译成结构化标签。标签的语义是否丰富直接决定了 LLM 的输出多样性——只标「Turn-01-L」和标出「Turn-03-S-dis前方路口直行但距离较远」的模型表现力完全不同。最后一关把数据「喂」给模型并确认它真的有用数据集构建到这里终于到了验收时刻。在把数据交给模型前还需要做一次格式收尾batch_merge_measurements.py会把每条路线的逐帧测量数据合并成一个measurements_all.json方便训练时随机采样。至此数据管线全部打通原始采集 → 四视角拼接 清洗堵车 → 指令标注 → 格式合并 → 训练。模型侧你只需要关注两个入口lavis/projects/lmdrive/drivegpt.yaml训练配置文件设置数据集路径、模型参数leaderboard/team_code/lmdriver_config.py运行时配置里面sample_rate 2控制采样间隔llm_model指向语言模型权重路径。启动训练同样很直接python train.py --cfg lavis/projects/lmdrive/drivegpt.yaml python evaluate.py --cfg lavis/projects/lmdrive/drivegpt.yaml怎么判断数据「真的能用」我的建议是三步验证一看训练 loss 是否稳定下降数据格式没问题二看模型能否在训练过的路线上完成指令学到内容了三看换到新路线上表现是否还在线泛化了。如果第三步明显退化别急着调模型——回头检查你的数据集多样性是不是不够这才是最可能的根因。下一步可以怎么玩现在你已经完整走通了 LMDrive 的数据集构建闭环可以开始玩些进阶花样了自定义城镇与路线在leaderboard/data/里手写 XML 路线跑出属于你自己的路网加入注意指令lmdriver_config.py里的agent_use_notice打开后模型会额外接收「前方注意」类提示训练数据里相应要多配 notice 类标签采集你自己的数据把 CARLA 换成自己的城市路网或真实场景数据集用同一套管线清洗标注说不定能训练出更贴近你需求的驾驶模型。数据集构建从来不是「跑几个脚本」那么简单它是一条需要不断回头审视的链路——从采集、清洗到标注每一环都决定着你最终模型的驾驶水平。希望这份实战指南能让你少走些弯路更快地把数据变成一辆「会开车」的模型。【免费下载链接】LMDrive[CVPR 2024] LMDrive: Closed-Loop End-to-End Driving with Large Language Models项目地址: https://gitcode.com/gh_mirrors/lm/LMDrive创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价