以下是使用DeepSeek模型微调训练自动驾驶模型的详细步骤和代码示例。本流程假设你已有自动驾驶领域的数据集(如驾驶指令、传感器数据等),并基于PyTorch框架实现。
Step 1: 环境准备
bash
# 安装依赖库
pip install torch transformers datasets numpy pandas
Step 2: 数据准备
假设数据集格式为JSON,包含输入文本(传感器/场景描述)和输出控制指令:
json
// data/train.json
[
{
"input": "前方10米有行人,当前车速30km/h,车道居中",
"output": "减速至20km/h,保持车道"
},
// 更多样本...
]
构建数据集加载器:
python
from datasets import load_dataset
from transformers import AutoTokenizer
# 加载数据集
dataset = load_dataset('json', data_files={'train': 'data/train.json', 'val': 'data/val.json'})
# 初始化分词器
tokenizer = AutoTokenizer.from_pretrained("deepseek-ai/deepseek-base-1.3B")
tokenizer.pad_token = tokenizer.eos_token # 设置填充token
# 数据预处理函数
def preprocess_function(examples):
inputs = [f"自动驾驶指令生成: {text}" for text in examples["input"]]
model_inputs = tokenizer(
inputs,
max_length=512,
truncation=True,
padding="max_length"
)
# 处理标签
labels = tokenizer(
examples["output"],
max_length=128,
truncation=True,
padding="max_length"
)
model_inputs["labels"] = labels["input_ids"]
return model_inputs
# 应用预处理
tokenized_dataset = dataset.map(preprocess_function, batched=True)
Step 3: 模型加载与适配
python
from transformers import AutoModelForCausalLM, TrainingArguments, Trainer
# 加载预训练模型
model = AutoModelForCausalLM.from_pretrained("deepseek-ai/deepseek-base-1.3B")
# 修改模型头部(适配自动驾驶任务)
if model.config.vocab_size != len(tokenizer):
model.resize_token_embeddings(len(tokenizer))
Step 4: 训练配置
python
training_args = TrainingArguments(
output_dir="./autopilot_model",
evaluation_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=4,
per_device_eval_batch_size=4,
num_train_epochs=3,
weight_decay=0.01,
logging_steps=50,
fp16=True, # 启用混合精度训练
save_strategy="epoch",
report_to="tensorboard"
)
# 初始化Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_dataset["train"],
eval_dataset=tokenized_dataset["val"],
tokenizer=tokenizer,
)
Step 5: 模型微调
python
# 开始训练
trainer.train()
# 保存最终模型
model.save_pretrained("./autopilot_final")
tokenizer.save_pretrained("./autopilot_final")
Step 6: 推理测试
python
from transformers import pipeline
# 创建推理管道
autopilot_pipe = pipeline(
"text-generation",
model="./autopilot_final",
tokenizer=tokenizer,
device=0 if torch.cuda.is_available() else -1
)
# 测试样例
input_text = "自动驾驶指令生成: 前方100米红灯,当前车速50km/h"
generated = autopilot_pipe(
input_text,
max_length=128,
temperature=0.7,
num_return_sequences=1
)
print(generated[0]['generated_text'])
# 输出示例: "减速至停车线前,等待绿灯"
Step 7: 部署优化(可选)
- 模型量化:
python
from transformers import BitsAndBytesConfig
quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16
)
quant_model = AutoModelForCausalLM.from_pretrained("./autopilot_final", quantization_config=quant_config)
- ONNX导出:
python
from transformers.convert_graph_to_onnx import convert
convert(framework="pt", model="./autopilot_final", output="autopilot.onnx", opset=12)
关键优化技巧
-
数据增强:
- 添加噪声:模拟传感器误差
- 场景扩展:生成雨天/雾天等特殊场景描述
pythondef add_noise(text, noise_level=0.1): words = text.split() # 随机替换部分词汇 return " ".join([w if random.random() > noise_level else "[UNK]" for w in words])
-
多模态融合(如结合视觉特征):
python
# 示例:融合图像特征
vision_encoder = AutoModel.from_pretrained("google/vit-base-patch16-224")
image_features = vision_encoder(images).last_hidden_state.mean(dim=1)
# 将视觉特征注入语言模型
combined_features = torch.cat([text_embeddings, image_features.unsqueeze(1)], dim=1)
安全关键设计
- 冗余校验模块:
python
def safety_check(predicted_command):
# 实现速度限制、碰撞检测等安全逻辑
if "急加速" in predicted_command and current_speed > 60:
return "建议维持当前车速"
return predicted_command
- 实时性监控:
python
import time
start_time = time.time()
generated = autopilot_pipe(...)
if (time.time() - start_time) > 0.1: # 超过100ms触发警告
print("WARNING: 推理延迟过高!")
效果评估指标
python
from rouge import Rouge
rouge = Rouge()
def evaluate(predictions, references):
# ROUGE指标
scores = rouge.get_scores(predictions, references, avg=True)
# 自定义安全评分
safety_score = sum([1 if "危险" not in p else 0 for p in predictions])/len(predictions)
return {
"rouge": scores,
"safety": safety_score
}
通过以上流程,你可以基于DeepSeek模型构建一个针对自动驾驶场景的指令生成系统。实际应用中需注意:
- 数据质量:确保训练数据覆盖各类道路场景
- 实时性测试:在目标硬件上验证推理速度
- 安全机制:必须加入多层冗余安全检查
- 持续学习:定期用新数据更新模型
建议在实际部署前进行严格仿真测试,可使用CARLA等自动驾驶仿真平台验证模型行为。
以下是一个自动生成自动驾驶训练数据集的Python方案,包含多种典型驾驶场景的模拟数据生成逻辑。该数据集将包含文本指令、传感器数据(模拟)和对应的控制指令。
python
import json
import random
from faker import Faker
import numpy as np
from tqdm import tqdm
fake = Faker('zh_CN')
def generate_scenario(scene_type):
"""生成基础场景描述"""
base_scene = {
"weather": random.choice(["晴天", "小雨", "雾天", "夜间"]),
"road_type": random.choice(["城市道路", "高速公路", "乡村道路", "隧道"]),
"speed": random.randint(20, 120)
}
# 根据不同场景类型添加特定要素
if scene_type == "normal":
return {
**base_scene,
"event": "保持车道行驶",
"obstacles": []
}
elif scene_type == "obstacle":
return {
**base_scene,
"event": random.choice(["行人横穿", "车辆加塞", "动物闯入"]),
"distance": random.randint(5, 100),
"obstacle_speed": random.randint(0, 10) if base_scene["road_type"] != "高速公路" else 0
}
elif scene_type == "traffic_control":
return {
**base_scene,
"event": random.choice(["红灯", "施工路段", "交警指挥"]),
"distance": random.randint(10, 200)
}
elif scene_type == "emergency":
return {
**base_scene,
"event": random.choice(["爆胎", "刹车失灵", "前方事故"]),
"severity": random.choice(["轻度", "中度", "重度"])
}
def generate_sensor_data(scenario):
"""生成模拟传感器数据"""
sensor = {
"camera": {
"front": np.random.rand(256, 256, 3).tolist(), # 模拟图像数据
"left": np.random.rand(128, 128, 3).tolist(),
"right": np.random.rand(128, 128, 3).tolist()
},
"lidar": {
"points": np.random.randn(1000, 3).tolist() # 1000个三维点云
},
"radar": {
"frontal_objects": [
{
"distance": random.uniform(5.0, 150.0),
"speed": random.uniform(-10.0, 30.0),
"angle": random.uniform(-30.0, 30.0)
} for _ in range(random.randint(0, 3))
]
}
}
# 根据场景调整传感器数据
if scenario["event"] == "行人横穿":
sensor["radar"]["frontal_objects"].append({
"distance": scenario["distance"],
"speed": 1.5, # 行人步行速度
"angle": random.uniform(-15, 15)
})
return sensor
def generate_control_command(scenario):
"""生成控制指令"""
base_speed = scenario["speed"]
cmd_template = {
"normal": "保持当前车速{}km/h,车道居中",
"obstacle": {
"行人横穿": "减速至{}km/h,准备制动",
"车辆加塞": "减速至{}km/h,保持安全距离",
"动物闯入": "鸣笛警示,减速至{}km/h"
},
"traffic_control": {
"红灯": "在距离{}米处开始减速,平稳停车",
"施工路段": "减速至{}km/h,向右变道",
"交警指挥": "按指挥手势行驶,保持车速{}km/h"
},
"emergency": {
"爆胎": "紧握方向盘,缓踩刹车,车速降至{}km/h",
"刹车失灵": "启用电子手刹,车速降至{}km/h",
"前方事故": "紧急制动,车速降至{}km/h"
}
}
if scenario["event"] == "保持车道行驶":
return cmd_template["normal"].format(base_speed)
for category in ["obstacle", "traffic_control", "emergency"]:
if scenario["event"] in cmd_template[category]:
target_speed = max(base_speed * 0.5, 20) if category == "emergency" else base_speed * 0.7
return cmd_template[category][scenario["event"]].format(int(target_speed))
return "维持当前操作"
def generate_dataset(num_samples=1000):
"""生成完整数据集"""
dataset = []
scene_types = ["normal", "obstacle", "traffic_control", "emergency"]
for _ in tqdm(range(num_samples)):
scene_type = random.choices(
scene_types,
weights=[0.4, 0.3, 0.2, 0.1], # 场景类型分布
k=1
)[0]
scenario = generate_scenario(scene_type)
sensor_data = generate_sensor_data(scenario)
command = generate_control_command(scenario)
# 构建输入描述
input_desc = (
f"当前环境:{scenario['weather']},{scenario['road_type']},"
f"车速{scenario['speed']}km/h。"
)
if "distance" in scenario:
input_desc += f"检测到{scenario['distance']}米处{scenario['event']}"
# 构建数据样本
sample = {
"input": input_desc,
"output": command,
"sensor_data": sensor_data,
"metadata": {
"scene_type": scene_type,
"timestamp": fake.date_time_this_year().isoformat(),
"location": fake.city() + "模拟道路"
}
}
dataset.append(sample)
return dataset
# 生成并保存数据集
if __name__ == "__main__":
dataset = generate_dataset(num_samples=5000)
# 分割训练验证集
random.shuffle(dataset)
split_idx = int(len(dataset)*0.9)
with open("data/train.json", "w") as f:
json.dump(dataset[:split_idx], f, ensure_ascii=False, indent=2)
with open("data/val.json", "w") as f:
json.dump(dataset[split_idx:], f, ensure_ascii=False, indent=2)
print(f"数据集生成完成,共{len(dataset)}条样本(训练集:{split_idx},验证集:{len(dataset)-split_idx})")
数据集结构说明
- 输入描述示例:
json
{
"input": "当前环境:小雨,城市道路,车速45km/h。检测到28米处行人横穿",
"output": "减速至32km/h,准备制动",
"sensor_data": {
"camera": {...},
"lidar": {...},
"radar": {
"frontal_objects": [
{"distance": 28.3, "speed": 1.5, "angle": 3.2}
]
}
},
"metadata": {
"scene_type": "obstacle",
"timestamp": "2024-03-15T14:32:15",
"location": "上海模拟道路"
}
}
-
场景覆盖范围:
- 天气条件:4种
- 道路类型:4种
- 障碍物类型:3种
- 交通管制:3种
- 紧急情况:3种
-
传感器数据模拟:
- 摄像头:模拟生成前视/左右摄像头图像(随机噪声)
- 激光雷达:生成1000个三维点云
- 毫米波雷达:生成前方物体距离/速度/角度
数据增强建议
- 真实传感器融合:
python
# 使用CARLA仿真平台获取真实传感器数据
from carla import World, Sensor
def capture_real_sensor_data():
world = connect_to_carla()
camera = CameraSensor(world)
lidar = LidarSensor(world)
return {
"camera": camera.capture(),
"lidar": lidar.get_point_cloud()
}
- 物理引擎增强:
python
def add_physics_noise(data):
# 为传感器数据添加物理合理的噪声
noise_levels = {
"radar_distance": 0.1, # 10%距离噪声
"camera_brightness": 0.05
}
if "radar" in data:
for obj in data["radar"]["frontal_objects"]:
obj["distance"] *= 1 + random.uniform(-noise_levels["radar_distance"], noise_levels["radar_distance"])
if "camera" in data:
for cam in data["camera"].values():
cam = np.array(cam)
cam += np.random.normal(0, noise_levels["camera_brightness"], cam.shape)
return data
- 对抗样本生成:
python
def generate_adversarial_samples():
# 生成极端情况样本
return [
{
"input": "当前环境:暴雨,高速公路,车速120km/h。检测到5米处多车连环追尾",
"output": "紧急制动!开启双闪!车速降至30km/h"
},
{
"input": "传感器故障:摄像头失效,雷达信号丢失",
"output": "启用冗余系统,维持最低安全车速40km/h"
}
]
数据集验证
- 统计分析脚本:
python
from collections import Counter
def analyze_dataset(dataset):
scene_types = [s["metadata"]["scene_type"] for s in dataset]
print("场景类型分布:", Counter(scene_types))
cmd_lengths = [len(s["output"]) for s in dataset]
print(f"指令平均长度: {np.mean(cmd_lengths):.1f}字符")
speed_changes = [int("减速" in s["output"]) for s in dataset]
print(f"需要减速的场景占比: {np.mean(speed_changes)*100:.1f}%")
analyze_dataset(dataset)
- 可视化检查:
python
import matplotlib.pyplot as plt
def visualize_sample(sample):
plt.figure(figsize=(12, 6))
# 显示模拟摄像头图像
plt.subplot(1, 2, 1)
plt.imshow(np.array(sample["sensor_data"]["camera"]["front"]))
plt.title("前视摄像头模拟")
# 显示雷达数据
plt.subplot(1, 2, 2)
distances = [obj["distance"] for obj in sample["sensor_data"]["radar"]["frontal_objects"]]
angles = [obj["angle"] for obj in sample["sensor_data"]["radar"]["frontal_objects"]]
plt.scatter(angles, distances)
plt.title("雷达探测示意图")
plt.suptitle(f"控制指令: {sample['output']}")
plt.show()
visualize_sample(dataset[0])
该方案生成的合成数据集可用于:
- 自动驾驶决策模型的监督学习
- 强化学习的环境模拟
- 传感器融合算法的开发验证
- 异常情况处理能力的压力测试
实际应用时建议:
- 逐步替换合成数据为真实道路采集数据
- 添加车辆动力学参数(如转向角、加速度等)
- 结合高精度地图信息增强场景语义
- 增加驾驶员监控系统(DMS)的生理信号数据