该示例为参考算法,仅作为在J6上模型部署的设计参考,非量产算法
简介
Diffusion-Based 模型是一类基于概率扩散过程的生成式模型,通过逐步加噪与逆向去噪实现高质量轨迹生成。Diffusion-Based 模型分为正向扩散与反向生成两个阶段:正向过程对真实数据逐步添加高斯噪声,使其最终趋近于纯噪声分布;反向过程则通过神经网络学习从噪声中逐步去除扰动,还原出符合真实分布的数据。
Diffusion-Based 模型凭借强大的表达能力与稳定性,在图像、语音、序列预测等任务中表现优异。在自动驾驶轨迹规划中能够在复杂交通约束下输出平滑、安全、多样的未来轨迹,成为端到端运动规划的主流方案之一。
性能精度指标
模型信息 | 精度(PDMS) | J6M性能 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
模型 | 数据集 | future_len | diffusion_pred_steps | hidden_dim | attention_heads | Float | Calibration | HBM | FPS | Latency |
e2e_planner | NAVSIM | 8 | 5 | 256 | 8 | 0.8223 | 0.8151 | 0.8146 | 10.11 FPS | 99.14 ms |
PDMS 为 NAVSIM navtest 的规划综合评分,分数越高表现越好。
公版模型介绍

本文考虑到交通参与者对闭环规划的监督作用,基于Diffusion-based method,通过联合考虑驾驶场景中关键参与者的状态,将运动预测与闭环规划任务统一建模为未来的轨迹生成问题。在给定包含当前车辆状态、历史数据、车道信息与导航信息的条件下,为自车和相邻车辆生成未来轨迹从而提升模型处理复杂交互场景的能力。模型整体可分为两大部分,训练/加噪过程和推理/去噪过程。
训练/加噪过程:加噪过程被设计为对真实轨迹增加高斯噪声,从x(0)状态到x(t)状态(t为[0,1],t越大噪声越大,训练时t是随机的)
车辆信息融合:将自车的当前状态融合相邻车辆的当前状态,作为约束来指导模型,相邻车辆的信息特征会通过多头自注意力机制实现不同车辆信息的融合,以及对自车和相邻车辆的未来轨迹加上噪声,去学习如何还原真实轨迹。
场景信息融合:融合相邻车辆的历史状态以及车道信息,分别使用2个MLP-Mixer模型去提取全局特征表达;同时对静态信息也通过MLP做提取,最后将以上信息输入到encoder网络中得到encoder特征。
导航信息融合:本文引入导航信息,为车辆的轨迹预测提供预期行驶路线指引。模型通过MLP-Mixer提取导航特征,融合时间步特征后经过自适应的LN模块引导轨迹的生成。
推理/去噪过程:去噪过程被设计为从加噪轨迹恢复到真实轨迹,从x(t)逐步到x(0)状态,时间步按预设序列变化
推理过程为多次推理模型(step=5),从噪声轨迹恢复到真实的轨迹,输出自车和相邻车辆的未来轨迹点。
以上为公版方法原理,部署模型的输入与采样配置见地平线部署说明章节。
代码详解
encoder
获取场景约束特征,对共享 BEV 特征做提取。默认不使用独立的车辆历史、静态目标与场景车道编码分支。
输入 base_bev 为 (B,256,128,192),经残差 Adapter 和三层 stride=2 卷积下采样,得到 384 个 256 维 tokens。Adapter 为 1×1 Conv/BN/ReLU 与 3×3 Conv/BN,输出与原特征相加。
heal/models/task_modules/diffusion_planner/encoder.py
量化连接点不重复插入输入量化:当前 quantize_bev_features=False,直接接收上游 BEV。BEVFusionEncoder 内部完成特征适配、下采样和展平。
heal/models/task_modules/diffusion_planner/encoder.py
heal/models/task_modules/diffusion_planner/encoder.py
整合为 encoder 的输入,加入空间位置编码。token_num 按实际输入计算,默认为 384。单路编码时直接输出,多路编码才使用 fusion(交付版本为单路BEV输入,不需要做fusion)。
heal/models/task_modules/diffusion_planner/encoder.py
fusion 层由自注意力机制构成,配置 depth=3、num_heads=8;BEV-only 时不执行该模块(默认BEV-only )。
heal/models/task_modules/diffusion_planner/encoder.py
decoder
decoder 的输入为 encoder 的输出、导航信息、自车状态与扩散时间步。默认仅预测自车,P=1,当前状态使用 x、y、cos、sin 四维。
heal/models/task_modules/diffusion_planner/decoder.py
decoder 分为训练模式和推理模式。训练模式输入带噪轨迹与扩散时间步,输出干净轨迹;推理模式从随机噪声出发,按配置多步去噪生成轨迹,diffusion_pred_steps=5。
训练模式:调用DiT模块输出轨迹
heal/models/task_modules/diffusion_planner/decoder.py
输入是带噪轨迹而非纯噪声:sampled_trajectories 是真实轨迹加噪后的结果,含当前帧时形状为 (B,1,9,4)。
直接输出轨迹 x_start:单次前向用于计算损失,引导梯度更新,无需在训练中执行完整多步采样。
Diffusion transformer
DiT 核心功能是结合扩散时间步、导航信息(route)和场景上下文(cross_c),输出轨迹 x_start。
主要流程为:对带噪自车轨迹做特征投影 → 导航特征融合时间步编码 → 经过 attention blocks 输出轨迹特征 → final_layer 输出轨迹。
heal/models/task_modules/diffusion_planner/dit.py
推理模式:多step去噪,生成轨迹
推理过程通过 DPM-Solver 生成轨迹:
步骤 1:生成初始噪声(推理的起点)
heal/models/task_modules/diffusion_planner/decoder.py
将自车当前状态与未来段随机噪声拼接为 xT,再由 DPM-Solver 输出最终轨迹 x0。推理不读取未来真实轨迹。
步骤 2:DPM-Solver 多步去噪生成最终轨迹
去噪过程从 x(t) 到 x(0)。调用 self.sample,传入场景与导航条件、当前状态及噪声轨迹;最终反归一化并截取未来轨迹。
heal/models/task_modules/diffusion_planner/decoder.py
采样配置位于 pred_sampling.py:diffusion_steps=5、order=2、skip_type="logSNR"、method="multistep",并开启 denoise_to_zero。
heal/models/task_modules/diffusion_planner/pred_sampling.py
DPM-Solver 多次调用去噪模型完成逐步更新。model_fn 通过 ModelWrapper 的 noise_pred_fn 调用 DiT;DiT 预测 x_start,再按噪声调度换算为噪声预测。默认复用同一个 DiT,代码同时兼容 ModuleList。
heal/models/task_modules/diffusion_planner/dpm_solver.py
DPM-Solver 的多步更新循环位于 dpm_scheduler.py,基础更新公式位于 dpm_solver_core.py。保留低阶初始化与后续多步更新的两段流程。
heal/models/task_modules/diffusion_planner/dpm_scheduler.py
轨迹序列包含 1 个自车当前状态点和 8 个未来点,共 9 个点;每点为 (x,y,cos,sin) 四维,因此展平后的长度为 9×4=36。切片后实际为 36 维非324维。
heal/models/structures/e2e_planner.py
地平线部署说明
改动说明
公版Diffusion-Planner在J6上部署的改动点为(以下精度增益为 nuPlan 闭环实验记录,不作为 NAVSIM PDMS 增益):
hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192hidden_dim、attention_head数增加,hidden_dim192-->256,attention_head6256,attention_head6256,attention_head6256,attention_head6256,attention_head6256,attention_head6256,attention_head6256,attention_head6-->8,提升一个点左右,闭环可视化有提升
对静态、bevfeature等做插拔设计(通过model.py的use_static_encoder、bev_encoder参数配置),默认以 BEV 特征、自车状态和导航信息作为规划模型输入,不单独输入邻居历史、静态目标及场景车道等结构化数据。
为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25为贴合量产场景,将多车道导航改为单条道路级别,route_num改为25-->1
为贴合量产场景,去除lane_speed_limit,改为单条道路级别的route_lanes_speed_limit,数据来源于导航信息
ego_loss_weight配置为2.0,能够提高0.3个点左右
加当前帧位置监督,预测时去除当前帧限制。闭环能增加4个点左右。
heal/models/task_modules/diffusion_planner/criterion.py
heal/models/task_modules/diffusion_planner/decoder.py
未使用碰撞guidance;默认仅预测自车,future_len=8、diffusion_pred_steps=5
调优经验
以下为基于 nuPlan 闭环评测的调优经验,未在交付配置中体现,为实验性结论,可酌情参考;不代表当前 NAVSIM 评测下的收益:
noise schedule优化:推理时使logSNR空间由线性转幂次调度,靠近0处更密集,反应式闭环精度能提升两个点,非反应式持平。
学习率使用官方的5e-4最优,调高调低都会存在掉点;
带ema更高0.5个点左右;
Step 10->5不会存在掉点,不同数据集表现不一致,可以尝试降低step数。
单机训练比双机高一个点;step多的原因,双机跑更多epoch能再涨一个点。
自车扰动概率设置为0.2在反应式闭环上能提升两个点(现象不稳定),非反应式上有回退0.8;
加碰撞guidance会掉点四五个,可酌情使用;
PolyLrUpdater学习策略不行,不如CosineAnnealingLrUpdater;
量化说明
- 默认以 INT8 为基础,通过敏感算子名单配置精度保护,具体配置见 configs/e2e_planner/qconfig.py。
configs/e2e_planner/qconfig.py
BEV 连接点设置 dequantize_bev_embed=False、quantize_bev_features=False,直接传递上游 BEV 量化特征,避免在连接点显式先反量化再重新量化。
为量化部署,ModelWrapper、DPMSampler 和 DPMSolverScheduler 使用 nn.Module 封装。
总结与建议
部署建议
当前规划模型采用 BEV 场景特征、预测自车未来轨迹,使用 INT8 基础配置并对敏感算子保护精度。如果需要进一步优化性能,可以考虑以下角度:
混合精度量化调优,根据敏感度结果选择需要保护的算子;
当前默认采样步数为5,可探索进一步降低采样步数,并结合 PDMS、轨迹可视化及耗时验证。
尝试noise schedule优化,效果需在当前评测集上验证。其他调优经验可参考第五章节。
附录
模型输入输出
参考链接
- 参考算法(modellabs)官网:https://oe.horizon.auto/labs
论文:https://arxiv.org/pdf/2501.15564
公版代码:https://github.com/ZhengYinan-AIR/Diffusion-Planner
