引言
地面交通系统涉及信号控制、路径规划、交通仿真、事故预测等多个环节,传统基于规则或浅层学习的方法在泛化能力和上下文理解上存在明显瓶颈。将大语言模型(LLM)微调为交通领域专家,能够实现:
- 自然语言交互式交通问答:用自然语言查询路况、拥堵原因
- 交通场景仿真描述生成:根据交通态势生成仿真配置文件
- 信号控制策略推理:结合时序数据给出信号配时建议
- 事故报告自动分析与总结:从大量事故记录中提取关键信息
本文以开源 LLaMA/Qwen 系列为基座模型,介绍从零构建交通数据集到 LoRA 微调部署的完整流程。
一、数据构建:交通领域数据集
1.1 数据来源
| 数据类型 | 来源 | 说明 |
|---|---|---|
| 交通新闻/报告 | 高德/百度交通 API、各地交警公开数据 | 标注难度低,量大 |
| 交通事故描述 | 事故报告、122报警记录脱敏数据 | 需要专业标注 |
| 信号配时方案 | 交警部门或仿真平台数据 | 需结构化提取 |
| 交通仿真场景描述 | SUMO/Paramics 等仿真软件导出 | 高价值,专业性强 |
| 交通学术论文(摘要) | 交通领域会议期刊(TRR、IEEE ITS) | 可做持续预训练 |
1.2 数据清洗与标注
# 示例:使用 LLM 做初步数据清洗与标注
import json
def clean_and_label_traffic_data(raw_text: str, label_model):
"""利用 LLM 对原始交通文本进行实体和意图标注"""
prompt = f"""你是一位交通工程专家。请对以下文本进行标注,返回 JSON 格式:
{{
"entities": ["地点", "事件类型", "拥堵程度"...],
"intent": "查询/控制/分析/报告",
"summary": "一句话概括",
"traffic_terms": ["信号灯", "交叉口", "拥堵"... ]
}}
文本:{raw_text}
"""
response = label_model.chat(prompt)
return json.loads(response)
1.3 Instruction-Tuning 数据格式
推荐使用 alpaca 格式或 sharegpt 格式:
{
"instruction": "北京晚高峰东三环严重拥堵,有什么疏导建议?",
"input": "当前路况:东三环双向车速 < 15km/h,持续时间 > 40min",
"output": "根据当前态势,建议以下疏导方案:1) 将国贸桥至长虹桥段信号配时调整为..."
}
1.4 数据配比
一个有效的交通领域微调数据集通常包含:
- 通用能力保持(20%):保留部分通用 QA、摘要、翻译数据防止灾难性遗忘
- 领域知识注入(50%):交通专业知识问答、信号控制、路径规划
- 任务导向数据(30%):仿真配置生成、报告分析、交通事件推理
二、微调方法选择
2.1 全参数微调 vs 参数高效微调
| 方法 | 参数量 | 显存需求 | 效果 | 适用场景 |
|---|---|---|---|---|
| 全参数微调 (Full FT) | 100% | A100 80G × 多卡 | 最佳 | 有充足算力 |
| LoRA | 0.1%~1% | 单卡 24G 可行 | 接近全参 | 主流选择 |
| QLoRA | 0.1%~1% (4-bit) | 单卡 16G 可行 | 略低于 LoRA | 资源受限 |
| Adapter-tuning | 1%~5% | 单卡 24G | 中等 | 任务切换多 |
推荐:优先使用 QLoRA,在 16G 显存下即可完成 7B 模型的微调。
2.2 LoRA 核心原理
LoRA 在注意力层的 Q/K/V/O 矩阵旁添加低秩适配器:
# LoRA 核心公式
# W_orig: 原始预训练权重 (d × d)
# W_new = W_orig + ΔW = W_orig + BA
# B ∈ R^(d×r), A ∈ R^(r×d), r << d (低秩)
# 训练时只更新 B 和 A,冻结 W_orig
import torch
import torch.nn as nn
class LoRALinear(nn.Module):
def __init__(self, original_layer: nn.Linear, rank: int = 4, alpha: float = 1.0):
super().__init__()
d_out, d_in = original_layer.weight.shape
self.original = original_layer
self.lora_A = nn.Parameter(torch.randn(rank, d_in) * 0.01)
self.lora_B = nn.Parameter(torch.zeros(d_out, rank))
self.scaling = alpha / rank
def forward(self, x):
return self.original(x) + (x @ self.lora_A.T @ self.lora_B.T) * self.scaling
2.3 交通领域适配器设计
针对交通场景,可以重点对以下层加 LoRA:
decoder_block.attn.q_proj ← 语义理解(query 理解交通场景描述)
decoder_block.attn.k_proj ← 关键实体(key 关联交通要素)
decoder_block.attn.v_proj ← 知识记忆(value 存储交通规则)
decoder_block.mlp.gate_proj ← 领域知识凝练
三、微调实战代码
3.1 环境准备
pip install transformers peft accelerate bitsandbytes trl
# 或使用 AxT >= 0.1 的统一命令:
pip install autotorch
3.2 QLoRA 微调脚本
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
import torch
# 4-bit 量化配置
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
# 加载基座模型
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2-7B-Instruct", # 或 LLaMA-3-8B
quantization_config=bnb_config,
device_map="auto",
torch_dtype=torch.bfloat16,
)
model = prepare_model_for_kbit_training(model)
# LoRA 配置 — 针对交通领域重点调参
lora_config = LoraConfig(
r=16, # 秩,越大效果越好但显存更高
lora_alpha=32, # 缩放因子
target_modules=[ # 重点微调的模块
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"
],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 可训练参数: ~0.41% (仅 8.9M 参数)
# 训练配置
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="./checkpoints/traffic-llm",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4, # 有效 batch = 4×4=16
optim="paged_adamw_32bit",
learning_rate=2e-4,
weight_decay=0.01,
fp16=False,
bf16=True,
logging_steps=10,
save_strategy="epoch",
warmup_ratio=0.03,
lr_scheduler_type="cosine",
)
3.3 交通领域特殊词表扩展
如果交通领域有大量专业术语(如 “交织区”、“信号相位”、“绿波带”),建议先扩展词表再微调:
from transformers import Tokenizer
from sentencepiece import sentencepiece_model_pb2
# 1. 收集交通术语
traffic_terms = [
"信号相位", "绿波带", "交织区", "排队长度",
"饱和流率", "延误时间", "路口渠化", "可变车道",
"感应控制", "自适应配时", "区域协调控制"
]
# 2. 使用 sentencepiece 增量训练扩展词表
# 3. 用扩展词表重新 tokenize 数据集并微调
四、训练技巧与坑
4.1 灾难性遗忘防护
全参数微调时容易发生灾难性遗忘(模型遗忘通用能力),解决方案:
- 混入通用数据(20%):始终保留部分通用 QA 数据
- 使用
gamma调度:参考 SwissArmyKnife 的渐进式解冻 - 设置较小的学习率:通常为预训练的 1/10 ~ 1/100
4.2 交通领域幻觉问题
交通领域对事实性要求高,LLM 容易一本正经地胡说八道。应对方法:
# RAG 增强:结合交通知识库检索
def traffic_rag_query(query: str, knowledge_base, llm):
docs = knowledge_base.similarity_search(query, k=3)
context = "\n".join([d.content for d in docs])
prompt = f"""基于以下交通知识回答问题。如果信息不足,据实说明不知道。
知识:{context}
问题:{query}"""
return llm.chat(prompt)
4.3 多模态扩展
如需处理交通图片(路况照片、仿真截图),可接入 LLaVA 或 Qwen-VL 系列做多模态微调:
# 以 LLaVA 为例:图像 + 交通文本联合微调
from llava.model.builder import load_pretrained_model
model, tokenizer, image_processor = load_pretrained_model("liuhaotian/llava-v1.6-7b")
五、评估与部署
5.1 评估指标
| 任务 | 评估指标 | 说明 |
|---|---|---|
| 交通问答 | BLEU-4 / ROUGE-L | 与专家答案对比 |
| 信号配时推荐 | 自定义评分函数(延误降低率) | 需仿真环境验证 |
| 事故报告摘要 | BERTScore / G-Eval | 语义层面评估 |
| 领域知识测试 | 交通领域 benchmark(自建) | 选择题/判断题 |
5.2 典型评估问题示例
{
"question": "在某交叉口,晚高峰期间左转流量很大(280 pcu/h),对向直行流量为 600 pcu/h,
该交叉口采用两相位控制,配时为 G40-Y3-R37。建议如何优化?",
"expected": "建议增加左转专用相位或将配时调整为 G55-Y3-R32,以提高左转通行能力..."
}
5.3 部署
# 使用 vLLM 部署推理服务
from vllm import LLM, SamplingParams
llm = LLM(
model="./checkpoints/traffic-llm/checkpoint-300",
tensor_parallel_size=1, # 单卡部署
gpu_memory_utilization=0.90,
)
params = SamplingParams(temperature=0.3, max_tokens=512)
output = llm.generate(
"晚高峰北京西直门桥拥堵,分析原因并给出疏导建议",
params
)
print(output[0].outputs[0].text)
六、进阶方向
- 多智能体协作:将信号控制、路径规划、仿真调度分为多个 Agent 协作
- 时序数据融合:结合 GeoJSON/CSV 交通数据输入,实现文本+数据的混合推理
- 持续微调:定期用新数据做 SFT 保持模型时效性
有任何问题或建议,欢迎通过博客留言交流!