整体架构概览
四模块流水线
SparseDriveV2 的端到端数据流:
6 × RGB (1920×1080)
│
▼
┌──────────────────┐
│ Image Encoder │ ResNet-34 + FPN,提取多尺度图像特征
└──────────────────┘
│
▼
┌──────────────────┐
│ Symmetric Sparse │ Detection + Tracking(实例 query)
│ Perception │ Online Mapping(地图 query)
└──────────────────┘
│
▼
┌──────────────────┐
│ Scoring-Based │ 在 262K 候选轨迹中打分,选最优
│ Planner │
└──────────────────┘
│
▼
规划轨迹 τ*
为什么是这四块
这四块对应端到端驾驶的四个本质子任务:
- 看(Image Encoder):把原始像素变成模型能用的特征。
- 理解场景(Sparse Perception):找出”有什么、在哪、地图长什么样”。
- 规划(Scoring Planner):在理解的基础上决定怎么走。
SparseDriveV2 的设计哲学是”每块都稀疏”——Image Encoder 输出多尺度特征图是稠密的(这是唯一稠密的环节),但后续所有操作都在少数 query 上完成。
整个链路端到端可微
这是端到端的核心。从图像到规划轨迹,整条链路全是可微操作:
- ResNet、FPN、attention、MLP 都是可微的。
- 投影(3D→2D)用可微的矩阵乘。
- Scoring 是连续的 score 函数。
所以规划 loss 可以一路回传到 Image Encoder 的卷积核:
∂θResNet∂Lplan=0
这是 SparseDriveV2 联合优化的数学保证——感知层(包括最底层卷积)都为规划质量负责。
三个模块共享 query 表示
感知的 detection query、map query 和规划用的 ego query 共享同一套 attention 机制(Spatial-Temporal Interaction,详见 B10)。这意味着规划模块可以”看到”感知模块维护的所有动态目标和地图元素,规划决策直接建立在感知结果上,不需要中间序列化。
参数规模
整个模型约 5000 万参数,其中:
- ResNet-34 backbone:2180 万(占近一半)。
- FPN、Decoder、attention heads、scoring MLPs:约 2800 万。
对比 UniAD(ResNet-101 + 多个 task head)动辄上亿参数,SparseDriveV2 非常轻量。轻量是 sparse 范式的直接红利——大部分算力集中在少数 query 上,不需要巨大的 backbone。
参考
Image Encoder
Backbone + FPN:标准结构
SparseDriveV2 的 Image Encoder 是最经典的设计:
6 × RGB ──► ResNet-34 ──► {C2, C3, C4, C5}(多尺度特征)
│
▼
FPN ──► {P2, P3, P4, P5}(多尺度融合特征)
- Backbone(ResNet-34):对每张图像独立提取特征,输出 4 个尺度的特征图(C2,C3,C4,C5,分辨率依次减半、通道数递增)。
- FPN(Feature Pyramid Network):自顶向下融合多尺度,让低层特征(高分辨率、细节多)和高层特征(低分辨率、语义强)互补。
为什么用 ResNet-34 而不是 ResNet-101
参数量对比:
| Backbone | 参数量 | 备注 |
|---|
| ResNet-34 | 21.8 M | SparseDriveV2 选用 |
| ResNet-50 | 25.6 M | |
| ResNet-101 | 44.5 M | UniAD、许多 BEV 方案用 |
ResNet-34 比 ResNet-101 轻量约 2 倍(44.5 / 21.8 ≈ 2.04)。
为什么 sparse 范式敢用更小的 backbone?因为后续的 Deformable Aggregation 只在少数关键点采样,对 backbone 的”全局表示能力”要求低——query 自己会去需要的位置精确取特征,不像 BEV 那样依赖 backbone 把整张图都编码好。所以 backbone 可以瘦身。
多尺度特征的作用
输出多个尺度的特征图(FPN 的 P2∼P5)是为了让不同尺度的目标都能被采到:
- P2(高分辨率):适合采样小目标(远处的车、行人)的关键点。
- P5(低分辨率、语义强):适合采样大目标(近处的大卡车)或获取整体上下文。
Deformable Aggregation 投影关键点后,会根据关键点的”图像尺度”(目标在图上的大小)选择从哪个 FPN 层采样——这是多尺度设计的工程价值。
6 个相机独立编码,无跨视角融合
注意一个细节:Image Encoder 对 6 个相机各自独立提取特征,不做跨视角融合。跨视角的信息整合发生在后续的 Sparse Perception(通过 query 的 attention)。
这是 sparse 范式和 BEV 范式的另一个区别:
- BEV 范式(BEVFormer 等):在 backbone 之后立刻做跨视角 attention,把 6 个相机特征”拍”到 BEV。
- Sparse 范式:backbone 只管提单视角特征,跨视角融合推迟到 query 级别(更晚、更稀疏)。
这样 backbone 完全可以批量并行处理 6 张图(一次前向),效率高。
易错点
- ResNet-34 是 ImageNet 预训练:不是从头训练,预训练权重提供良好的低层特征(边缘、纹理),加速收敛。
- 归一化用 ImageNet 均值方差:推理时图像必须用 ImageNet 的 mean/std 归一化,否则 backbone 输出分布会和训练时不一致。
- 输入分辨率要固定:ResNet 全是卷积,理论上支持任意分辨率,但 FPN 和后续投影逻辑是按固定分辨率标定的,换分辨率要重标定相机内参。
参考
为什么需要专门的采样算子
端到端驾驶的核心难点:query 是 3D 概念(“前方 12 米那辆车”),但图像是 2D 的。怎么让 3D query 从 2D 图像里拿到自己的视觉特征?
朴素方案是 global attention——让 query 和所有图像位置做 attention。但 6 张 1920×1080 图像展开是上千万个 token,global attention 计算量爆炸。
Deformable Aggregation 的解法:query 用自己的 3D 锚点找到图像上的少数采样位置,只在那里采样。这是 Deformable DETR 思想在多视角驾驶场景的扩展。
三步流程
① 在 3D 锚点周围生成关键点
query 的 3D 锚点 a∈R3 是个点,但一个目标(一辆车)有体积。所以 query 在 a 周围生成 K 个采样关键点 {pk}k=1K,覆盖目标的整个 3D 空间分布:
pk=a+Δk
其中 Δk 是关键点相对锚点的偏移,由 query 的特征向量 f 预测出来(经过一个小 MLP):
Δk=MLPk(f)
关键点布局是自适应的——不同 query(不同目标)的关键点分布不同。这一步把”3D 空间采样”问题转化成”在哪几个点采样”。
② 投影到 2D,只在视野内有效
每个 3D 关键点 pk=(X,Y,Z)(Ego 车体坐标系)投影到第 i 个相机:
uv1∼KiRiXYZ+ti
其中 Ki 是内参,(Ri,ti) 是相机外参(由挂载位置决定,每帧随 Ego 运动更新)。
只有投影 (u,v) 落在第 i 个相机图像 [0,W]×[0,H] 范围内的关键点,才在那个相机采样。一个 3D 关键点通常只落在 1–2 个相机的视野里(环视相机有重叠区,但单个点不会同时落在 6 个相机里)。
③ 局部采样 + 加权聚合
在有效投影位置 (u,v) 附近用 deformable attention 取特征(不是单点取值,是小邻域内的加权采样),然后按权重聚合回 query:
f′=∑i∈cams∑k=1Kwi,k⋅ϕ(Fcami, ui,k, vi,k)
- ϕ 是从第 i 个相机的特征图 Fcami 在 (ui,k,vi,k) 处取特征的函数(双线性采样 + 小邻域 attention)。
- wi,k 是采样权重,由 query 特征 f 预测,让模型知道哪些关键点更重要。
聚合后 f′ 就是 query 从图像里”看到自己”得到的更新特征——包含了”我的视觉长什么样”的信息。
工程实现:自定义 CUDA 算子
这套操作的计算模式是:Nq 个 query、每个 K 个关键点、每个最多 V 个相机。这是高度并行的(query 之间、关键点之间、相机之间都独立),适合 GPU。
但标准 PyTorch 算子不能高效表达”3D 点投影到对应相机、只在视野内采样、加权聚合”这种稀疏不规则访问。所以 SparseDriveV2 用自定义 CUDA 算子实现 Deformable Aggregation,把整个流程融合成一个 kernel,避免中间 tensor 分配。这是性能的关键——同样的算法用纯 Python 实现会慢几十倍。
为什么省算力
对比 global attention:
- Global:query 对 ∑iHiWi 个图像位置做 attention(上千万)。
- Deformable:query 对 K×V 个采样位置做(K 几十、V≤6,实际有效 ∼1.5)。
加速比∼Nq⋅K⋅V∑iHiWi≈102⋅101⋅100107=104
而且空白区域无 query,不浪费——这是 sparse 范式的核心红利。
易错点
- 关键点偏移初始化:训练初期 f 没意义,Δk 接近 0,所有关键点堆在锚点上。好的初始化(如把 Δk 初始化为均匀分布在 bbox 内)加速收敛。
- 投影用 Ego 坐标系:3D 关键点是 Ego 车体坐标,外参把 Ego 坐标转到相机坐标。坐标系混乱是 bug 高发区。
- 采样要可微:双线性采样本身可微,但若用
round 取整会断梯度。要保证整个投影-采样链路梯度能回传。
参考
Detection & Tracking
Instance Query:11 维 anchor 编码什么
检测模块维护 Nd 个 Instance Query(Nd 通常 100 左右)。每个 query 的 anchor 是一个 11 维向量,编码一个候选目标的完整几何和运动状态:
| 维度 | 含义 |
|---|
| (x,y,z) | 3D 中心位置 |
| (w,l,h) | 尺寸(宽、长、高) |
| sinθ,cosθ | 朝向角(用 sin/cos 编码避免角度周期性) |
| vx,vy | 速度(横向、纵向) |
合起来 3+3+2+2=10… 加上置信度相关项共 11 维。用 sin/cos 编码朝向是个易被忽略的技巧:直接回归角度 θ 时,θ=0 和 θ=2π 是同一朝向但数值差很大,loss 会误解;用 (sinθ,cosθ) 把周期函数拆成两个连续值,回归稳定。
6 层 Decoder:逐步精炼
query 经过 6 层 Decoder,每层做一次 Deformable Aggregation + self-attention + FFN,逐步修正 anchor:
f(l+1),a(l+1)=DecoderLayer(l)(f(l),a(l))
每层都会更新 query 的特征和 anchor 位置——anchor 不是固定的,而是随训练学习逐步逼近真实目标。第一层 query 的 anchor 是随机初始化(或可学习的位置编码),到第六层 anchor 应该收敛到真实目标位置。
这和 DETR 的迭代框精炼(iterative box refinement)思想一致:用粗 anchor 起步,逐层细化。
第一层 vs 后五层:时序信息
视频强调的关键设计:
- 第 1 层:无时序——只用当前帧的图像特征。
- 第 2–6 层:引入历史帧——query 携带 H=3 帧的历史状态(前 3 帧时该 query 的特征和 anchor)。
为什么这样分?第一层是”初始化”——还不知道这个 query 对应哪个目标,没法做时序对齐。从第二层开始,query 已经有了当前帧的初步预测,可以把历史帧的对应 query(按位置或特征相似度匹配)拿过来,做时序 attention:
f(l+1)=Attn(f(l), {ft−1(l),ft−2(l),ft−3(l)})
历史信息让 query 知道”这辆车上一帧在哪、速度多少”,从而直接预测速度(不需要帧间差分),也应对遮挡(目标短暂被遮住,靠历史延续)。
Tracking:简洁的”持久 ID”机制
传统多目标跟踪(MOT)需要复杂的关联算法——匈牙利匹配、卡尔曼滤波、轨迹生命周期管理。SparseDriveV2 的跟踪极其简洁:
置信度超过阈值的检测自动获得持久 ID。
为什么这么简单能用?因为 query 本身是持久的——同一个 query 在连续帧里通过时序 attention 维护自己的状态,自然就对应同一个目标。只要这个 query 在某帧检测置信度高(确认是真目标),它就一直带着同一个 ID。
代价是:query 数量 Nd 固定(比如 100),如果场景里同时有超过 Nd 个目标,会漏检。但自动驾驶场景里单帧可见目标通常远小于 100,这个限制基本不触发。
检测的输出
每个 query 最终输出:
- 类别分布:分类 head(softmax over C 类)。
- 几何状态:精炼后的 11 维 anchor。
- 置信度:是否是真目标(query 可能空跑——对应的 anchor 处没目标)。
- 持久 ID(若置信度超阈值)。
这些就是 Sparse Perception 给下游 Planner 的”动态场景理解”。
易错点
- Nd 是超参:太小漏目标,太大浪费算力。100 是经验值。
- 第一层不可逆地决定时序对齐:如果第一层 anchor 离真实目标太远,后续时序对齐会出错。好的初始化和多层精炼缓解这一点。
- ID 跳变:query 置信度在阈值附近抖动时,ID 会反复开关。需要迟滞(hysteresis)阈值。
参考
Online Mapping
与 Detection 完全对称的架构
SparseDriveV2 的建图模块和检测模块结构完全相同:
- 同样的 6 层 Decoder。
- 同样的 Deformable Aggregation 算子。
- 同样的时序设计(第 1 层无时序,第 2–6 层引入历史帧)。
唯一的区别是 query 的定义——anchor 编码什么。这种”换 query 不换架构”的设计非常优雅:一套算子处理两种性质完全不同的实体。
20 点 Polyline Anchor
地图元素(车道线、道路边界、人行横道)是线状结构,不是盒子状。所以 map query 的 anchor 是一条 polyline(折线),由 20 个 3D 点组成:
amap={p1,p2,…,p20},pi∈R3
20 个点串联起来近似一条曲线。每个点都参与 Deformable Aggregation——投影到图像、采样、聚合。所以一条车道线 query 会从 6 个相机里沿着它的视觉投影采样 20 个位置,把”这条线的视觉长什么样”全收集起来。
为什么是 20 点
折线的点数是个权衡:
- 太少(如 5 点):曲线被过度简化,弯道拟合不准。
- 太多(如 100 点):参数冗余,训练困难,且大部分点和邻居高度相关(信息冗余)。
20 点是经验值,足够拟合城市道路的典型车道线曲率,又不至于参数爆炸。对于特别长的元素(如长车道线),20 点可能不够密,但实际场景里地图元素通常被分段表示。
100 个 Map Query
建图模块维护 100 个 Map Query,覆盖三类元素:
| 类型 | 说明 |
|---|
| 车道线(lane divider) | 车道之间的分界线 |
| 道路边界(road boundary) | 路面边缘、护栏 |
| 人行横道(pedestrian crossing) | 斑马线 |
100 个 query 的分配可以均匀,也可以按场景先验(城市路口人行横道多)。每个 query 学到”自己代表哪类元素”+ “我的 polyline 长什么样”。
“Online” 的含义
Online Mapping 强调在线(运行时)建图——模型从当前帧图像直接推断地图结构,不依赖预存的高精地图。
这是端到端范式的关键优势:
- 模块化方案在推理时需要 HD Map 提供车道线、边界等信息——但 HD Map 采集成本高、更新慢、覆盖有限。
- Online Mapping 让模型从视觉自己”读”出地图,能在任何有图像的地方工作。
代价是精度不如 HD Map(视觉推断的车道线位置有误差),但对规划够用——规划需要的是”大致车道结构 + 我相对它的位置”,不需要厘米级。
检测和建图共享算子的好处
同一套 Decoder 处理检测和建图,意味着:
- 算子优化共享:Deformable Aggregation 的 CUDA 算子只写一份,两边都用。
- 跨任务交互:detection query 和 map query 可以互相 attention(“这辆车压在哪条车道上”)——这是 B10 的 Agent-Map interaction。
- 训练 loss 共享:检测 loss 和建图 loss 一起回传,backbone 同时为两者优化。
易错点
- Polyline 方向:车道线有方向(前进方向),20 个点的顺序约定要一致,否则训练时同一条线不同方向会让 loss 不收敛。
- 地图元素遮挡:远处车道线常被前车遮挡,query 要靠可见部分推断整体——这是 online mapping 的固有挑战。
- 坐标系:polyline 点是 Ego 车体坐标系,每帧随 Ego 运动变化,时序对齐要补偿 Ego 自身运动(ego-motion compensation)。
参考
Factorized Vocabulary:262K 候选的由来
候选池的两难再回顾
打分式规划的前提是候选池足够密(覆盖率),但池子越大评分越慢(计算量)。朴素枚举所有 (曲率,速度,时长) 组合会让候选数指数爆炸。
SparseDriveV2 的核心洞察:轨迹可以分解成两个几乎独立的维度。
轨迹的分解
一条完整的驾驶轨迹 τ 描述”未来 T 秒内 Ego 在每个时刻的位置和速度”:
τ={(xt,yt,vt)}t=1T
把它拆成两部分:
- Geometric Path(几何路径):只关心空间形状——(xt,yt) 序列。回答”走哪条线”。
- Velocity Profile(速度剖面):只关心时间速度曲线——vt 序列。回答”走多快”。
τ=Path⊕Velocity
理论上路径和速度有耦合(弯道限速),但在多数驾驶场景里两者近似独立:同一条路径可以配多种速度(快过弯/慢过弯),同一种速度可以配多条路径(左换道/右换道)。
笛卡尔积的规模
Vocabulary(候选池)是两个独立集合的笛卡尔积:
V=Vpath×Vvel,∣Vpath∣=1024, ∣Vvel∣=256
∣V∣=1024×256=262144≈262K
26 万条候选,比传统方案(如 6 条生成轨迹)密集 4 万倍,比一些打分方案密集 32 倍(视频提到的 32× 密度)。这么密的池子几乎覆盖所有合理驾驶行为。
为什么”加法而非乘法”
这是最关键的设计巧思。如果要对 26 万条候选逐条精细评分,计算量是 O(∣V∣)=O(262K)——虽然比连续回归简单,但 26 万次精细 scoring 在实时系统里仍不可承受。
但因为 path 和 velocity 独立,粗筛阶段可以分别评分:
Scorepath(path),Scorevel(vel)
两个轻量 MLP 分别处理 1024 条路径和 256 种速度:
粗筛计算量=∣Vpath∣+∣Vvel∣=1024+256=1280
注意是加法 O(1280),不是乘法 O(262K)。这就是”足够密变得可计算”的秘密。
1024 和 256 怎么来的
这两个数字不是随便选的:
- 1024 条 path:覆盖直行、各种曲率的弯道、左/右换道、U 型调头等。用聚类从训练集真实轨迹里学出来——把 nuScenes/NAVSIM 所有 Ego 轨迹聚类成 1024 个典型形状。
- 256 种 velocity:覆盖急刹、缓刹、匀速、加速等典型速度曲线。同样从数据聚类。
这些候选是预定义的常量(vocabulary),训练和推理都用同一份。模型不生成候选,只学怎么评分。
路径和速度怎么合成完整轨迹
粗筛选出 Top-K path 和 Top-K velocity 后,需要把它们组合成完整轨迹做精细评分。组合时要做时间对齐——把 path(空间点序列)和 velocity(时间速度序列)对齐到统一时间轴:
给定 path {(xs,ys)}(按弧长参数化)和 velocity {vt}(按时间参数化),积分得到完整轨迹:
st=∫0tvt′dt′,(xt,yt)=Path(st)
即沿 path 走的弧长由 velocity 决定。这个合成过程就是 B09 的 Trajectory Re-Conditioning。
易错点
- path/velocity 独立性是近似:极端场景(高速过急弯)下两者强耦合,分解会漏掉某些轨迹。这是 factorized 设计的固有代价。
- 候选是固定的:如果测试场景出现训练集没有的轨迹形状(如某些罕见调头),候选池里没有,模型选不到。这是固定 vocabulary 的局限。
- 聚类质量决定覆盖率:1024 条 path 是从训练集聚类来的,聚类不好会导致候选分布有盲区。
参考
Coarse-to-Fine Scoring
两阶段筛选漏斗
26 万候选不可能逐条精细评分(O(262K) 的精细推理在实时系统里跑不动)。SparseDriveV2 用两阶段漏斗逐级过滤:
262K 候选(笛卡尔积)
│
│ 粗筛:path 和 vel 独立评分(加法)
▼
1024 path → Top-K path 256 vel → Top-K vel
│ │
└────────── K×K 组合 ──────────┘
│
│ 精排:时空联合精细评分
▼
~K² 条完整轨迹
│
▼
最高分轨迹 τ*
SparseDriveV2 用两层 Decoder 实现渐进式筛选:第一层保留 Top-128 path + Top-64 velocity;第二层进一步收窄到 Top-20 path + Top-20 velocity,两两组合得到 400 条完整轨迹进入精排。从 26 万 → ~192 → 400 → 1,每级过滤掉绝大部分候选。
粗筛:独立打分
粗筛阶段两个轻量 MLP 分别处理 path 和 vel,各自独立评分:
spath(i)=MLPpath(pathi, Fscene),i=1,…,1024
svel(j)=MLPvel(velj, Fscene),j=1,…,256
Fscene 是感知模块输出的场景特征(动态目标、地图)。MLP 把”这条 path/这种 vel 在当前场景下好不好”压成一个标量分数。
计算量是 O(1280)——这是加法,不是 O(262K) 的乘法(详见 B08)。
两层 Decoder 渐进收窄(论文具体配置):
| Decoder 层 | path 保留 | velocity 保留 | 说明 |
|---|
| 第 1 层 | 1024 → Top-128 | 256 → Top-64 | 粗排,丢弃明显劣解 |
| 第 2 层 | 128 → Top-20 | 64 → Top-20 | 精排入口,组合成 400 条 |
注意 NAVSIM v2 配置下第 2 层 velocity 进一步减到 Top-10(加速 ground-truth 计算),此时精排候选是 20×10=200 条。
精排:组合 + 时空联合
Top-20 path 和 Top-20 vel 两两组合,得到 400 条完整候选(精排入口):
Cfine={(pathi,velj):i∈I20, j∈J20},∣Cfine∣=400
组合时用 Trajectory Re-Conditioning(轨迹再条件化)——把独立的 path 和 vel 合成有时空一致的完整轨迹。这是因为粗筛时两者独立评分,没考虑组合后的耦合(如某条 path + 某种 vel 组合起来会撞车)。Re-Conditioning 重新计算合成轨迹的具体 (xt,yt,vt):
τij(t)=ReCondition(pathi,velj,t)
然后用一个更重的 scoring 网络做时空联合推理——既看空间形状(path 部分),又看时间动力学(vel 部分),还和场景特征做 attention:
sij=Scorer(τij, Fscene)
这个 Scorer 比 MLP 重(可能含 attention 层),但只跑 400 次,可承受。
最终选择
选最高分:
τ∗=τargmaxi,jsij
整个流程可微(argmax 用 softmax 软选择或 Gumbel-softmax 平滑),所以梯度可以从最终选择回传到 scoring 网络和场景特征。
为什么不直接精排所有 26 万
精排网络重,跑 26 万次单次推理就要几秒——远超 50 ms 实时预算。粗筛的轻量 MLP 跑 1280 次只要几毫秒,能快速过滤掉绝大部分明显不合理的候选(撞墙的 path、超速的 vel)。这种”先用便宜的过滤,再用贵的精排”的漏斗是工程上常见的两阶段范式,也是 SparseDriveV2 把 26 万候选压到实时可算的关键工程手段。
可微性的细节
整个流程要可微才能端到端训练:
- 粗筛 Top-K:Top-K 本身不可微,但可以用 softmax 权重做软选择(让所有 path 都参与,但按分数加权)。
- 精排 argmax:用 soft argmax 或 Gumbel-softmax 平滑。
- Re-Conditioning 的积分:用可微的数值积分(如 Riemann 和)。
训练时这些软化保证梯度流通;推理时可以切回硬选择(取真正的 Top-K 和 argmax)。
易错点
- 粗筛漏掉好候选:如果 Top-K 太小,可能把真正最优的组合(粗筛分数不高但组合后最好)过滤掉。K 要够大。
- Re-Conditioning 误差:path 和 vel 合成时的弧长积分有数值误差,影响精排判断。
- 训练-推理不一致:训练用软选择、推理用硬选择,分布有差异。要保证两者接近。
参考
Spatial-Temporal Interactions
三种 Attention 连接感知与规划
SparseDriveV2 的感知和规划之间通过三种 attention 机制连接。这三种 attention 让 ego(自己的车)能”看到”所有相关实体,做出合理规划。
| Attention | 谁关注谁 | 目的 |
|---|
| Agent-Temporal | Agent 关注自己的 H=3 帧历史 | 时序连续,预测速度 |
| Agent-Agent | 各 Agent 互相交互 | 多车博弈、避让 |
| Agent-Map | Agent 与地图元素交互 | 遵守车道、不出界 |
Agent-Temporal:时序记忆
每个 Agent query 携带最近 H=3 帧的历史状态。Temporal Decoder(前面说的第 2–6 层)让 query 关注自己的历史:
f′=Attn(fnow, {ft−1,ft−2,ft−3})
这给 query 两项能力:
- 直接预测速度:通过历史位置差分得到速度,不用单独的速度估计模块。
- 应对遮挡:目标被短暂遮挡时(如被前车挡住),靠历史延续轨迹,不会”突然消失”。
5 层 Temporal Decoder 反复利用这些历史信息更新 query——每次更新都重新关注历史,让时序信息深度融入特征。
Agent-Agent:多车交互
各 Agent 之间互相 attention,捕捉”这辆车会影响我吗”的交互:
fi′=Attn(fi, {fj}j=i)
这对预测交互式行为至关重要:
- 前车减速 → 我该减速。
- 旁车要换道 → 我要让或加速。
- 路口来车 → 谁先走的博弈。
没有 Agent-Agent attention,每个 Agent 独立预测自己的未来,会忽略交互(如两辆车都预测自己直行,结果相撞)。SparseDriveV2 让所有 Agent 互相看到,预测就是博弈式的。
Agent-Map:地图约束
Agent 与地图元素(车道线、边界)attention,让 Agent 知道”我必须在哪条车道内”:
fi′=Attn(fi, {mk}map queries)
这是规划合理性的关键约束——一辆车不能凭空漂出车道。Agent-Map attention 让车的预测轨迹自然贴合地图结构。
最关键设计:Ego 是普通 Agent
视频强调的核心设计:Ego Vehicle 被当作一个普通 Agent,参与所有三种 attention,和 NPC 用同一套机制交互。
这意味着规划和预测本质上是同一个任务:
- 预测:“NPC 接下来会怎么走”。
- 规划:“Ego 接下来会怎么走”。
两者的网络结构、attention 机制完全一样——Ego query 和 NPC query 在同一个 Decoder 里互相交互。差别只在输出:Ego 的输出是规划轨迹(要执行),NPC 的输出是预测轨迹(给 Ego 参考)。
这种”统一”的好处:
- 架构简洁:一个模块同时做预测和规划,不用两套网络。
- 交互对称:Ego 能预测 NPC,NPC 也”知道”Ego 的存在——双向博弈更真实。
- 训练数据互补:预测和规划的 loss 都更新同一个网络,样本效率高。
时序对齐的细节
Agent-Temporal 用历史帧,但历史帧的 query 和当前帧的 query 不一定一一对应(query 数量固定,但场景里目标会增减)。对齐方式:
- 按位置最近:把当前帧 query 的 anchor 和历史帧 query 的 anchor 做最近邻匹配。
- 按特征相似度:用 cosine 相似度找历史里最像的 query。
这是时序 attention 的隐藏复杂度——匹配错了会让 query 关注到错误的历史(如把两辆不同车的状态搞混),导致速度预测错。
易错点
- Ego-motion 补偿:query 的历史 anchor 是当时 Ego 坐标系下的位置,当前帧 Ego 已经移动,要把历史 anchor 转到当前 Ego 坐标系才能比较。漏做这步会让所有目标看起来”在动”。
- 时序窗口太短:H=3 在 20 Hz 下只有 150 ms,对慢速目标(远处车)速度估计不准。
- Agent-Agent 的二次复杂度:Nd 个 Agent 两两 attention 是 O(Nd2),Nd=100 时 1 万次,可接受;但 Nd 增大要小心。
参考
Scaling Law 与性能
轨迹密度的 Scaling Law
SparseDriveV2 的关键发现:候选轨迹密度和规划性能之间存在 Scaling Law(缩放定律)——候选从 1× 密度增加到 32× 密度,性能持续上升,没有饱和。
形式化地说,设候选密度为 ρ(如 1×,2×,4×,…,32×),性能指标 P(如 PDMS):
P(ρ) 随 ρ 单调递增,在实验范围内未见饱和
这和 LLM 领域的 Scaling Law(模型越大性能越好)同构——表示能力随表示空间的扩展而提升。
为什么没有饱和
理论上性能应该有上限(轨迹质量不可能无限提升),但实验范围内没看到饱和,原因是:
- 真实驾驶行为空间巨大:合理轨迹的组合空间远未被 32× 密度覆盖。增加密度总能覆盖到之前漏掉的有用轨迹。
- Coarse-to-Fine 控制了计算代价:即使密度提升 32 倍,评分计算量增长远小于 32 倍(粗筛是加法),所以可以负担更高密度。
这个 Scaling Law 的工程意义是:想要更高性能,加候选密度就行——这是一个清晰的性能提升路径,不像很多方法到了某点就不再涨。
实测性能数据
SparseDriveV2 在两个基准上的成绩(来自论文报告):
| 基准 | 指标 | SparseDriveV2 | 说明 |
|---|
| NAVSIM(开环) | PDMS | 92.0 | SOTA,比第二名显著领先 |
| Bench2Drive(闭环) | Driving Score | 89.15 | SOTA |
NAVSIM 是更现代的开环评测(比 nuScenes planning 更全面),PDMS(Predictive Driver Model Score)是它的综合分。Bench2Drive 是 CARLA 上的闭环评测,Driving Score 综合路线完成率和违规惩罚(EP06 详述)。两个基准都 SOTA,说明 SparseDriveV2 在开环(看预测准不准)和闭环(看真的能不能安全开)都强。
与 UniAD 的全方位对比
| 维度 | UniAD | SparseDriveV2 |
|---|
| 表示 | Dense BEV | Sparse query |
| 规划 | 单条回归 | 26 万候选打分 |
| Backbone | ResNet-101 (44.5M) | ResNet-34 (21.8M) |
| 训练 | A100 × 8, ~144h | L20 × 8, ~10h |
| 推理 | ~1.8 FPS | 实时(>20 Hz) |
训练从 144 小时降到约 10 小时(14× 加速),推理从 1.8 FPS 到实时(>10× 加速),backbone 还更小。这是 sparse + scoring 范式的全方位效率优势——不是单点优化,是范式层面的红利。
Scaling Law 的局限
虽然密度提升一直涨性能,但有几个限制:
- 内存:候选池越大占用显存越多(虽然评分是加法,但存储 vocabulary 是常数)。
- 覆盖率边际递减:候选越多,新增候选”覆盖到之前漏掉的好轨迹”的概率越低。理论上回报递减,只是实验范围内还没明显。
- 泛化性:候选是从训练集聚类来的,测试场景如果分布外(OOD),候选池再大也覆盖不到。这是 Bench2Drive 闭环评测暴露的问题(EP06 的失败案例)。
参考