LMDrive 项目架构与核心算法组件
一、项目概述
LMDrive 是一个基于大型语言模型(LLM)和多模态视觉编码器的端到端自动驾驶系统。它能够理解自然语言指令,并从多视角摄像头和 LiDAR 传感器输入中生成驾驶控制信号。
核心特性:
- 自然语言指令理解
- 多模态传感器数据融合(RGB + LiDAR)
- 端到端闭环驾驶
- CARLA 模拟器集成
二、文件夹与文件目录架构
2.1 项目根目录
LMDrive/
├── LAVIS/ # 视觉-语言模型库(基于 BLIP2/LLaVA)
├── vision_encoder/ # 视觉特征提取与多模态融合模块
├── leaderboard/ # CARLA Leaderboard 评估框架
├── scenario_runner/ # 场景管理与交通事件模拟
├── data_collection/ # 自动化数据收集脚本
├── dataset/ # 数据集初始化与管理
├── langauto/ # 语言指令基准测试
├── assets/ # 资源文件(架构图等)
├── environment.yml # Conda 环境配置
├── LICENSE
└── README.md
2.2 LAVIS/ - 视觉-语言模型库
LAVIS/
├── app/ # 应用程序(推理演示)
│ ├── caption.py # 图像描述
│ ├── vqa.py # 视觉问答
│ ├── classification.py # 分类任务
│ └── main.py # 主入口
├── lavis/ # 核心库代码
│ ├── common/ # 通用工具
│ │ ├── config.py # 配置管理
│ │ ├── dist_utils.py # 分布式训练工具
│ │ ├── registry.py # 注册机制
│ │ └── utils.py # 工具函数
│ ├── configs/ # 配置文件
│ │ ├── datasets/ # 数据集配置
│ │ │ └── carla/ # CARLA 数据集配置
│ │ └── models/ # 模型配置
│ ├── datasets/ # 数据集定义
│ │ ├── builders/ # 数据集构建器
│ │ └── datasets/ # 具体数据集实现
│ └── models/ # 模型定义
│ ├── albef_models/ # ALBEF 模型
│ ├── alpro_models/ # ALPRO 模型
│ └── blip2_models/ # BLIP2 模型
│ ├── blip2.py # BLIP2 基础模型
│ ├── Qformer.py # Q-Former 编码器
│ ├── memfuser.py # Memfuser 融合模型
│ └── modeling_llama.py # LLaMA 模型封装
├── examples/ # Jupyter 示例
├── docs/ # 文档
└── evaluate.py # 评估脚本
2.3 vision_encoder/ - 视觉特征提取模块
vision_encoder/
├── timm/ # 视觉模型库(基于 PyTorch Image Models)
│ ├── data/ # 数据处理
│ │ ├── carla_dataset.py # CARLA 数据集
│ │ ├── carla_loader.py # CARLA 数据加载器
│ │ └── parsers/ # 数据解析器
│ └── models/ # 视觉模型定义
│ ├── layers/ # 基础层
│ │ ├── activations.py # 激活函数
│ │ ├── attention.py # 注意力机制
│ │ ├── mlp.py # MLP 层
│ │ ├── norm.py # 归一化层
│ │ └── patch_embed.py # Patch Embedding
│ ├── memfuser.py # Memfuser 多模态融合模型(核心)
│ ├── interfuser.py # Interfuser 多模态融合模型
│ ├── pointpillar.py # PointPillar LiDAR 处理
│ ├── resnet.py # ResNet 骨干网络
│ ├── vision_transformer.py # Vision Transformer
│ └── factory.py # 模型创建工厂
├── scripts/ # 训练脚本
├── distributed_pretrain.sh # 分布式预训练脚本
└── hubconf.py # PyTorch Hub 配置
2.4 leaderboard/ - CARLA 评估框架
leaderboard/
├── leaderboard/ # 评估核心代码
│ ├── autoagents/ # 代理接口
│ │ ├── autonomous_agent.py # 自主代理基类
│ │ └── dummy_agent.py # 示例代理
│ ├── envs/ # 环境接口
│ │ ├── sensor_interface.py # 传感器接口
│ │ └── instruction_dict.json # 指令字典
│ ├── scenarios/ # 场景管理
│ │ ├── scenario_manager.py # 场景管理器
│ │ └── route_scenario.py # 路线场景
│ ├── utils/ # 工具函数
│ │ ├── route_parser.py # 路线解析
│ │ ├── result_writer.py # 结果写入
│ │ └── statistics_manager.py # 统计管理
│ └── leaderboard_evaluator.py # 评估器
├── team_code/ # 参赛队伍代码(LMDrive 核心)
│ ├── lmdriver_agent.py # LMDrive 代理实现(核心)
│ ├── lmdriver_config.py # 配置文件
│ ├── planner.py # 路线规划器
│ ├── pid_controller.py # PID 控制器
│ ├── controller.py # 控制器基类
│ ├── auto_pilot.py # 自动驾驶控制
│ └── utils.py # 工具函数
├── data/ # 评估数据
│ ├── 42routes/ # 42 条评估路线
│ ├── training_routes/ # 训练路线
│ ├── validation_routes/ # 验证路线
│ ├── scenarios/ # 场景配置
│ └── official/ # 官方数据
├── scripts/ # 评估脚本
│ ├── run_evaluation.sh # 运行评估
│ └── eval.sh # 评估命令
└── requirements.txt # 依赖列表
2.5 scenario_runner/ - 场景运行器
scenario_runner/
├── srunner/ # 场景运行器核心
│ ├── autoagents/ # 代理接口
│ ├── scenarioconfigs/ # 场景配置
│ ├── scenariomanager/ # 场景管理器
│ │ ├── scenario_manager.py # 场景管理核心
│ │ ├── actorcontrols/ # 角色控制
│ │ ├── scenarioatomics/ # 原子行为/条件
│ │ └── traffic_events.py # 交通事件
│ ├── scenarios/ # 场景定义
│ │ ├── follow_leading_vehicle.py # 跟车场景
│ │ ├── change_lane.py # 变道场景
│ │ ├── junction_crossing_route.py # 路口穿越
│ │ └── signalized_junction_left_turn.py # 信号灯左转
│ ├── tools/ # 工具函数
│ └── metrics/ # 指标计算
├── examples/ # 场景示例
├── Docs/ # 文档
└── scenario_runner.py # 主入口
三、框架架构
3.1 整体架构图
┌─────────────────────────────────────────────────────────────────────┐
│ CARLA Simulator │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │
│ │ RGB Front │ │ RGB Left │ │ RGB Right │ │ RGB Rear │ │
│ │ (1200x900) │ │ (400x300) │ │ (400x300) │ │ (400x300) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └─────┬─────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ LiDAR │ │ GPS/IMU/Speed│ │
│ │ (Ray-Cast) │ │ Sensors │ │
│ └──────┬──────┘ └──────┬──────┘ │
└─────────┼────────────────┼───────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ LMDrive Agent │
│ │
│ ┌────────────────── 传感器数据预处理 ───────────────────┐ │
│ │ 图像变换 → CenterCrop → Normalize → Tensor │ │
│ │ LiDAR → PointPillar → BEV Feature Map │ │
│ └───────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌─────────────────── 视觉编码器 ──────────────────────┐ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ ResNet Backbone (r26/r50) → HybridEmbed │ │ │
│ │ │ → PositionEmbeddingSine → View Embedding │ │ │
│ │ └───────────────────┬───────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────────▼───────────────────────────┐ │ │
│ │ │ Transformer Encoder (enc_depth layers) │ │ │
│ │ │ - Multi-View Feature Fusion │ │ │
│ │ │ - Cross-Modal Attention │ │ │
│ │ └───────────────────┬───────────────────────────┘ │ │
│ └───────────────────────┼──────────────────────────────┘ │
│ │ │
│ ┌─────────────────── LLM 融合 ───────────────────────┐ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Q-Former → LLaVA/Vicuna LLM │ │ │
│ │ │ - Instruction Understanding │ │ │
│ │ │ - Visual-Language Alignment │ │ │
│ │ └───────────────────┬───────────────────────────┘ │ │
│ └───────────────────────┼──────────────────────────────┘ │
│ │ │
│ ┌─────────────────── 决策输出 ───────────────────────┐ │
│ │ ┌───────────────────────────────────────────────┐ │ │
│ │ │ Transformer Decoder → Waypoints Predictor │ │ │
│ │ │ - GRUWaypointsPredictor │ │ │
│ │ │ - 5 waypoints (x, y) │ │ │
│ │ └───────────────────┬───────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────────▼───────────────────────────┐ │ │
│ │ │ PID Controller → Steering/Throttle/Brake │ │ │
│ │ └───────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
3.2 数据流
- 传感器输入:CARLA 模拟器提供多视角图像、LiDAR 点云、GPS、IMU 和速度数据
- 数据预处理:图像裁剪、归一化;LiDAR 点云转换为 BEV 特征图
- 视觉编码:ResNet 提取特征 → Transformer Encoder 融合多视图特征
- 语言理解:Q-Former 将视觉特征与 LLM 对齐,理解自然语言指令
- 决策生成:Transformer Decoder 生成轨迹点(waypoints)
- 控制输出:PID 控制器将轨迹点转换为驾驶控制信号
四、核心算法组件
4.1 Memfuser 多模态融合模型
文件路径 :vision_encoder/timm/models/memfuser.py
Memfuser 是 LMDrive 的核心多模态融合模型,采用 Transformer Encoder-Decoder 架构。
4.1.1 模型结构
python
class Memfuser(nn.Module):
def __init__(
self,
img_size=224, # 主视角图像尺寸
multi_view_img_size=112, # 侧视角图像尺寸
embed_dim=768, # 嵌入维度
enc_depth=6, # Encoder 层数
dec_depth=6, # Decoder 层数
num_heads=8, # 注意力头数
rgb_backbone_name="r26", # RGB 骨干网络
with_lidar=True, # 是否使用 LiDAR
with_right_left_sensors=True, # 是否使用左右摄像头
with_rear_sensor=True, # 是否使用后摄像头
waypoints_pred_head="gru", # 轨迹预测头类型
):
4.1.2 关键组件
| 组件 | 功能 |
|---|---|
| HybridEmbed | 将 ResNet 特征转换为 Transformer 可处理的 token |
| PositionEmbeddingSine | 正弦位置编码 |
| View Embedding | 区分不同视角的嵌入向量 |
| LidarModel | 基于 PointPillar 的 LiDAR 处理 |
| TransformerEncoder | 融合多视图视觉特征 |
| TransformerDecoder | 生成轨迹点和交通预测 |
| GRUWaypointsPredictor | GRU 轨迹点预测器 |
| TrafficPredHead | 交通参与者预测头 |
4.1.3 前向传播流程
python
def forward_features(self, front_image, left_image, right_image, rear_image,
front_center_image, lidar, num_points):
# 1. 多视角图像特征提取
front_image_token, front_image_token_global = self.rgb_patch_embed(front_image)
left_image_token, left_image_token_global = self.rgb_patch_embed(left_image)
right_image_token, right_image_token_global = self.rgb_patch_embed(right_image)
rear_image_token, rear_image_token_global = self.rgb_patch_embed(rear_image)
front_center_image_token, front_center_image_token_global = self.rgb_patch_embed(front_center_image)
# 2. LiDAR 特征提取
lidar_token = self.lidar_backbone(lidar, num_points)
# 3. 拼接所有特征
features = torch.cat([front_image_token, front_image_token_global, ...], 0)
return features, lidar_token
python
def forward(self, x):
# 1. 提取特征
features, lidar_token = self.forward_features(...)
# 2. Encoder 编码
memory = self.encoder(features, mask=self.attn_mask)
# 3. Decoder 解码
query = torch.cat([lidar_token, query_embed], 0)
hs = self.decoder(query, memory, query_pos=tgt)[0]
# 4. 输出预测
waypoints = self.waypoints_generator(waypoints_feature, target_point)
traffic = self.traffic_pred_head(traffic_feature_with_vel)
traffic_light_state = self.traffic_light_pred_head(traffic_light_state_feature)
stop_sign = self.stop_sign_head(stop_sign_feature)
return traffic, waypoints, traffic_light_state, stop_sign, traffic_feature
4.2 Interfuser 多模态融合模型
文件路径 :vision_encoder/timm/models/interfuser.py
Interfuser 是另一种多模态融合模型,与 Memfuser 类似但采用不同的注意力机制策略。
4.2.1 主要区别
| 特性 | Memfuser | Interfuser |
|---|---|---|
| LiDAR 处理 | PointPillar | ResNet 骨干 |
| 注意力掩码 | None | 支持分离视图注意力 |
| 轨迹预测头 | GRU | 多种(GRU/Linear/Heatmap) |
| 额外输出 | 交通灯/停车标志 | 路口检测/交通灯/停车标志 |
4.2.2 支持的轨迹预测头
gru:GRU 序列预测gru-command:带指令的 GRU 预测linear:线性预测linear-sum:线性累加预测heatmap:热力图预测(MultiPath)
4.3 LMDrive Agent
文件路径 :leaderboard/team_code/lmdriver_agent.py
LMDriveAgent 是 CARLA Leaderboard 的代理实现,负责与模拟器交互并执行驾驶决策。
4.3.1 传感器配置
python
def sensors(self):
return [
{"type": "sensor.camera.rgb", "id": "rgb_front", ...}, # 前视摄像头
{"type": "sensor.camera.rgb", "id": "rgb_left", ...}, # 左视摄像头
{"type": "sensor.camera.rgb", "id": "rgb_right", ...}, # 右视摄像头
{"type": "sensor.camera.rgb", "id": "rgb_rear", ...}, # 后视摄像头
{"type": "sensor.lidar.ray_cast", "id": "lidar", ...}, # LiDAR
{"type": "sensor.other.imu", "id": "imu", ...}, # IMU
{"type": "sensor.other.gnss", "id": "gps", ...}, # GPS
{"type": "sensor.speedometer", "id": "speed", ...}, # 速度计
]
4.3.2 核心方法
| 方法 | 功能 |
|---|---|
setup() |
初始化模型、控制器和传感器变换 |
tick() |
处理传感器数据,计算车辆状态 |
run_step() |
执行单步驾驶决策(核心) |
control_pid() |
PID 控制器生成控制信号 |
4.3.3 驾驶决策流程
python
@torch.no_grad()
def run_step(self, input_data, timestamp):
# 1. 数据预处理
tick_data = self.tick(input_data)
# 2. 图像变换
rgb_front = self.rgb_front_transform(Image.fromarray(tick_data["rgb_front"])).cuda()
rgb_left = self.rgb_left_transform(Image.fromarray(tick_data["rgb_left"])).cuda()
rgb_right = self.rgb_right_transform(Image.fromarray(tick_data["rgb_right"])).cuda()
rgb_rear = self.rgb_right_transform(Image.fromarray(tick_data["rgb_rear"])).cuda()
rgb_center = self.rgb_center_transform(Image.fromarray(cv2.resize(...))).cuda()
# 3. 获取自然语言指令
last_instruction = self._instruction_planner.command2instruct(...)
# 4. 视觉编码
image_embeds = self.net.visual_encoder(input_data)
# 5. LLM 推理生成轨迹点
waypoints, is_end = self.net(input_data, inference_mode=True, image_embeds=image_embeds)
# 6. PID 控制生成驾驶信号
steer, throttle, brake, metadata = self.control_pid(waypoints, velocity)
# 7. 返回控制指令
control = carla.VehicleControl()
control.steer = float(steer) * 0.8
control.throttle = float(throttle)
control.brake = float(brake)
return control
4.4 PID 控制器
文件路径 :leaderboard/team_code/pid_controller.py
PID 控制器将预测的轨迹点转换为车辆控制信号。
python
def control_pid(self, waypoints, velocity):
# 计算期望速度
desired_speed = np.linalg.norm(waypoints[0] - waypoints[1]) * 2.0
# 计算转向角
aim = (waypoints[1] + waypoints[0]) / 2.0
angle = np.degrees(np.pi / 2 - np.arctan2(aim[1], aim[0])) / 90
# PID 控制
steer = self.turn_controller.step(angle)
throttle = self.speed_controller.step(desired_speed - speed)
# 刹车判断
brake = desired_speed < self.config.brake_speed or (speed / desired_speed) > self.config.brake_ratio
return steer, throttle, brake, metadata
4.5 路线规划器
文件路径 :leaderboard/team_code/planner.py
包含两个规划器:
| 规划器 | 功能 |
|---|---|
| RoutePlanner | 基于 GPS 的路线规划,生成下一个目标点和命令 |
| InstructionPlanner | 将驾驶命令转换为自然语言指令 |
4.6 视觉-语言模型集成
文件路径 :LAVIS/lavis/models/blip2_models/memfuser.py
将 Memfuser 视觉编码器与 LLM(LLaVA/Vicuna)集成。
python
class Memfuser(nn.Module):
def __init__(self, preception_model, llm_model, ...):
self.visual_encoder = create_model(preception_model) # 视觉编码器
self.llm = load_llm_model(llm_model) # LLM 模型
self.qformer = Qformer(...) # Q-Former 桥接层
五、关键技术点
5.1 多模态特征融合
- 图像特征:ResNet + HybridEmbed → 图像 Token
- LiDAR 特征:PointPillar → BEV 特征图 → LiDAR Token
- 位置编码:正弦位置编码(PositionEmbeddingSine)
- 视图编码:可学习的 View Embedding 区分不同视角
5.2 指令理解
- 使用 LLaVA/Vicuna 作为语言模型
- Q-Former 作为视觉-语言桥接
- 支持自然语言指令如:"Turn left at the next intersection"
5.3 端到端闭环
- 从传感器输入直接到控制输出
- 无需手工设计的感知模块
- 支持实时推理(约 20Hz)
5.4 分布式训练
- 使用 PyTorch Distributed Data Parallel
- 支持多 GPU 训练
- 预训练 + 指令微调两阶段
六、数据流程总结
CARLA Simulator
│
▼
┌─────────────────┐
│ 传感器数据采集 │ RGB(5视角) + LiDAR + GPS/IMU/Speed
└────────┬────────┘
│
▼
┌─────────────────┐
│ 数据预处理 │ 图像裁剪/归一化 + LiDAR点云处理
└────────┬────────┘
│
▼
┌─────────────────┐
│ 视觉特征提取 │ ResNet + HybridEmbed + Position Encoding
└────────┬────────┘
│
▼
┌─────────────────┐
│ 多模态特征融合 │ Transformer Encoder (多视图注意力)
└────────┬────────┘
│
▼
┌─────────────────┐
│ 语言指令理解 │ Q-Former + LLaVA/Vicuna
└────────┬────────┘
│
▼
┌─────────────────┐
│ 轨迹点预测 │ Transformer Decoder + GRU
└────────┬────────┘
│
▼
┌─────────────────┐
│ 控制信号生成 │ PID Controller → Steering/Throttle/Brake
└────────┬────────┘
│
▼
CARLA Simulator (执行控制)
七、模型配置与变体
7.1 Memfuser 模型变体
| 模型名称 | Encoder Depth | Decoder Depth | Backbone | 用途 |
|---|---|---|---|---|
memfuser_baseline |
2 | 4 | ResNet50 | 基础版本 |
memfuser_baseline_e3d3 |
3 | 3 | ResNet50 | 平衡版本 |
memfuser_baseline_e1d3 |
1 | 3 | ResNet50 | 轻量版本 |
memfuser_baseline_e1d3_r26 |
1 | 3 | ResNet26 | 更轻量版本 |
memfuser_baseline_return_feature |
2 | 4 | ResNet50 | 返回中间特征 |
7.2 Interfuser 模型变体
| 模型名称 | Encoder Depth | Decoder Depth | 注意力策略 |
|---|---|---|---|
interfuser_baseline |
3 | 3 | 全注意力 |
interfuser_baseline_seperate_all |
6 | 6 | 分离视图注意力 |
interfuser_baseline_wolidar |
6 | 6 | 无 LiDAR |
八、评估与数据集
8.1 评估路线
- 42routes:官方评估路线
- training_routes:训练路线(Town01-Town10)
- validation_routes:验证路线(Town05)
- evaluation_routes:评估路线
8.2 场景配置
- 交通场景(红绿灯、停车标志)
- 路口场景(左转、右转、直行)
- 变道场景
- 跟车场景
8.3 评估指标
- 路线完成率
- 时间效率
- 安全性(碰撞次数)
- 交通规则遵守
九、部署与运行
9.1 环境依赖
yaml
conda env create -f environment.yml
conda activate lmdrive
9.2 模型训练
bash
# 视觉编码器预训练
cd vision_encoder
bash distributed_pretrain.sh
# 指令微调
cd LAVIS
python train.py --cfg-path configs/models/blip2/blip2_coco.yaml
9.3 评估运行
bash
cd leaderboard
bash scripts/run_evaluation.sh
9.4 关键环境变量
| 变量 | 说明 |
|---|---|
CARLA_ROOT |
CARLA 模拟器路径 |
ROUTES |
评估路线文件 |
SCENARIOS |
场景配置文件 |
TEAM_AGENT |
代理代码路径 |
TEAM_CONFIG |
代理配置文件 |
SAVE_PATH |
结果保存路径 |
十、核心文件清单
| 文件路径 | 功能描述 |
|---|---|
vision_encoder/timm/models/memfuser.py |
Memfuser 多模态融合模型 |
vision_encoder/timm/models/interfuser.py |
Interfuser 多模态融合模型 |
vision_encoder/timm/models/pointpillar.py |
PointPillar LiDAR 处理 |
leaderboard/team_code/lmdriver_agent.py |
LMDrive CARLA 代理 |
leaderboard/team_code/pid_controller.py |
PID 控制器 |
leaderboard/team_code/planner.py |
路线规划器 |
leaderboard/team_code/lmdriver_config.py |
代理配置 |
LAVIS/lavis/models/blip2_models/memfuser.py |
BLIP2 + Memfuser 集成 |
LAVIS/lavis/models/blip2_models/Qformer.py |
Q-Former 编码器 |
vision_encoder/timm/data/carla_dataset.py |
CARLA 数据集 |
vision_encoder/timm/data/carla_loader.py |
CARLA 数据加载器 |