LSS Lift Splat Shoot Encoding Images From Arbitrary Camera Rigs by Implicitly Unprojecting to 3D

Task: BEV Semantic Segmentation / Motion Planning
Method: Latent Depth Distribution, Frustum Pooling, Cost Map Planning
Venue: ECCV
Year: 2020
Paper: https://arxiv.org/abs/2008.05711
Code: https://github.com/nv-tlabs/lift-splat-shoot

摘要

自动驾驶感知系统的目标是从多个传感器中提取语义表示,并将其融合到统一的鸟瞰图(BEV)坐标系中供运动规划使用。本文提出了一种端到端架构 Lift-Splat-Shoot (LSS),能够从任意数量摄像头的图像数据中直接提取 BEV 表示。该方法的核心思路分三步:Lift——为每张图像的每个像素预测一个离散深度分布,将 2D 特征”提升”为视锥体形状的 3D 点云;Splat——利用相机内外参将所有视锥体”投射”到统一的 BEV 栅格上,通过 Pillar Pooling 进行聚合;Shoot——在 BEV 代价图上”射出”模板轨迹进行可解释的端到端运动规划。在 nuScenes 和 Lyft 数据集上的物体分割与地图分割任务中,LSS 超越了所有基线和同期工作。此外,该模型展现出了对标定误差和传感器失效的鲁棒性,以及跨相机配置的零样本迁移能力。

核心论点:多视图 BEV 感知的关键在于如何将 2D 图像特征”升维”到 3D 空间并融合——LSS 通过为每个像素预测隐式深度分布,以外积方式生成视锥体特征,开创了”Lift-Splat”这一从图像到 BEV 的通用转换范式,成为后续 BEVDetBEVDepthBEVFusion 等一系列 BEV 感知方法的基础。

问题与动机

自动驾驶感知系统需要将多相机图像融合到 BEV 坐标系中进行下游规划。现有方案面临核心挑战:如何从 2D 图像空间变换到 3D/BEV 空间。

方法类型 代表作 核心问题 特点
单目检测 + 后处理 SSD-6D, MonoGRNet 不可端到端微分,无法学习跨视图融合 逐视图独立检测再拼接
Pseudo-LiDAR PseudoLiDAR, PL++ 需独立训练深度网络,误差传播 两阶段:深度估计 + BEV 检测
3D 体素投影 OFT 像素对所有体素贡献相同特征,未建模深度 固定体素投影
BEV 直接推理 MonoLayout, PON 未利用几何先验,性能受限 直接学习图像到 BEV 映射

传统的单目检测融合方案虽然具有三个良好的对称性(平移等变性排列不变性自身坐标等距等变性),但由于使用后处理检测结果拼接,无法端到端训练,也无法学习最优的跨视图融合策略。OFT 虽然利用了相机几何,但一个像素对所有深度的体素贡献完全相同的特征,无法区分深度信息。

核心痛点:如何设计一个既保持几何对称性、又端到端可微分的架构,使模型能够从数据中学习最优的跨视图融合方式,同时对深度不确定性进行显式建模。

核心洞察

洞察 1:隐式深度分布——用概率建模替代确定性深度估计

单目深度估计存在固有歧义:同一像素可能对应多个深度值。传统方法要么忽略深度(OFT 对所有深度均匀分配特征),要么做确定性深度预测(PseudoLiDAR 预测一个深度值)。LSS 提出了一种折中方案:为每个像素预测一个离散深度分布 $\alpha \in \Delta^{|D|-1}$ 和一个上下文向量 $\mathbf{c} \in \mathbb{R}^C$,通过外积生成每个深度上的特征。

OFT 做法:像素特征不加区分地复制到所有深度位置(等价于 $\alpha$ 为均匀分布)
PseudoLiDAR 做法:预测单一确定性深度,特征仅存在于一个位置(等价于 $\alpha$ 为 one-hot 向量)
LSS 做法:预测连续的深度分布 $\alpha$,特征按概率分配到各深度位置

核心公式:

$$\mathbf{c}_d = \alpha_d \cdot \mathbf{c}$$

其中 $\mathbf{c}_d \in \mathbb{R}^C$ 是像素 $p$ 在深度 $d$ 处的特征,$\alpha_d$ 是深度为 $d$ 的概率。

为什么更优:网络可以自适应地选择:对深度确定的区域(如地面)输出尖锐分布集中特征;对深度模糊的区域(如远处物体)输出平滑分布扩散特征。这一机制统一了”确定性深度”和”均匀分配”两种极端策略。

算子层面的设计选择:外积运算 depth_prob.unsqueeze(1) * image_feat.unsqueeze(2) 是纯粹的 broadcast + elementwise multiply,刻意避开了 F.grid_sample。原因在于:若对全分辨率特征图做 $D$ 次连续坐标插值采样($H \times W \times D$ 个采样点),grid_sample 的双线性插值会产生大量随机内存访问(non-coalesced access),cache 命中率极低;而 broadcast 是连续内存的规则 tensor 运算,GPU warp 利用率远高。这一取舍是 LSS 能以 35 Hz 运行的关键原因之一。

洞察 2:Pillar Pooling + Cumsum Trick——高效的视锥体到 BEV 转换

将每个像素提升到 $|D|$ 个深度点后,$n$ 个相机共生成 $n \times D \times H \times W$ 个 3D 点。如何将如此大规模的稀疏点云高效聚合到 BEV 栅格上是关键的工程挑战。

传统做法:对每个 pillar 分别收集落入的点,需要 padding 和变长索引操作
LSS 做法:借鉴 PointPillars,将所有点按照 pillar 编号排序,利用 cumulative sum 技巧实现零填充的 sum pooling

从 PyTorch 算子角度看,Splat 本质上是 voxel pooling(体素池化):将不规则分布的视锥体点离散聚合到规则 BEV 网格,等价于 torch.scatter_add。QuickCumsum 是 scatter_add 的高效替代实现——通过排序 + 累积求和 + 差分避免了 scatter 的原子操作竞争,在 CUDA 上更快。后续 BEVFusionQuickCumsumCuda 进一步将 voxelization + pooling 融合为单一 kernel。

具体步骤:

  1. 将所有 3D 点映射到对应的 pillar(无限高度的体素)
  2. 按 pillar ID 排序所有点
  3. 对排序后的特征做累积求和
  4. 在 pillar 边界处做差值即得到每个 pillar 的聚合特征

为什么更优:避免了 padding 带来的额外内存开销,且累积求和有解析梯度,训练速度提升 2 倍。这使得在完整 6 相机输入上训练大规模模型成为可能。

洞察 3:端到端几何感知架构——三大对称性保持

LSS 架构在设计上天然保持了三个关键对称性,而不需要任何后处理:

  1. 平移等变性:图像内像素坐标平移 → 输出对应平移(来自全卷积设计)
  2. 排列不变性:$n$ 个相机的输入顺序不影响最终输出(Splat 操作是 sum pooling)
  3. 自身坐标等距等变性:同一场景在不同自车位姿下,检测结果随之刚体变换(通过内外参显式变换坐标)

传统的 CNN baseline 将所有相机特征直接拼接后上采样到 BEV,破坏了排列不变性和等距等变性。实验表明,这种缺乏几何归纳偏置的 baseline 性能远低于 LSS(nuScenes 车辆分割 IoU 仅 24.25% vs. 32.07%)。

要记住的 3 个数字

  • **32.07%**:nuScenes 车辆分割 IoU,超越所有基线和同期工作
  • 35 Hz:Titan V GPU 上的前向推理速度,满足自动驾驶实时性需求
  • 14.3M:模型总参数量,轻量级设计

方法设计

4.1 整体架构

给定 $n$ 张图像 ${X_k \in \mathbb{R}^{3 \times H \times W}}^n$ 及其对应的外参 $E_k \in \mathbb{R}^{3 \times 4}$ 和内参 $I_k \in \mathbb{R}^{3 \times 3}$,模型输出 BEV 表示 $\mathbf{y} \in \mathbb{R}^{C \times X \times Y}$:

$$\text{Images} \xrightarrow{\text{Lift}} \text{Frustum Point Cloud} \xrightarrow{\text{Splat}} \text{BEV Grid} \xrightarrow{\text{BEV CNN}} \text{Segmentation / Cost Map}$$
LSS 架构图
输入:n 张图像 (128×352) + 内参 I + 外参 E
                │
                ▼
 ┌─────────────────────────────┐
 │  EfficientNet-B0 Backbone   │  逐图像独立处理
 │  + Up(320+112 → 512)        │
 └──────────────┬──────────────┘
                │ 特征图 (8×22×512)
                ▼
 ┌─────────────────────────────┐
 │  Depth Net (Conv 1×1)       │  输出 D+C = 41+64 = 105 通道
 │  → α ∈ ℝ^D (softmax)        │  深度分布
 │  → c ∈ ℝ^C                  │  上下文向量
 └──────────────┬──────────────┘
                │ 外积: c_d = α_d · c
                ▼
 ┌─────────────────────────────┐
 │  Frustum Point Cloud        │  n × D × H × W × C
 │  坐标变换 (I, E) → ego frame │  
 └──────────────┬──────────────┘
                │ 按 pillar 排序 + cumsum trick
                ▼
 ┌─────────────────────────────┐
 │  BEV Pseudo Image           │  C × 200 × 200
 │  (200×200, 0.5m/pixel)      │  [-50m, 50m] × [-50m, 50m]
 └──────────────┬──────────────┘
                │
                ▼
 ┌─────────────────────────────┐
 │  BEV Encoder (ResNet-18)    │  Conv7s2 → layer1 → layer2 → layer3
 │  + Multi-scale Upsample     │  Up(64+256→256, ×4) → Up(256→128→outC, ×2)
 └──────────────┬──────────────┘
                │
                ▼
     BEV Segmentation Map
     或 Cost Map (用于规划)

4.2 关键组件

组件 输出尺寸 功能 备注
CamEncode (B×N) × 105 × 8 × 22 提取图像特征 + 预测深度分布和上下文 EfficientNet-B0 + 1×1Conv
Depth Head D=41 通道 预测 4.0m~45.0m 离散深度概率 Softmax 归一化
Context Head C=64 通道 提取上下文语义特征 与深度分布外积
Frustum Pooling C × 200 × 200 视锥体点云 → BEV 栅格聚合 Cumsum trick, 2× 加速
BevEncode outC × 200 × 200 BEV 特征提取 + 多尺度融合 ResNet-18 前 3 层 + FPN

损失函数

物体分割和可行驶区域使用带正样本权重的二值交叉熵损失:

$$\mathcal{L} = \text{BCEWithLogitsLoss}(\hat{y}, y; w_{pos})$$

其中车辆分割和可行驶区域分割的 $w_{pos} = 1.0$,车道线分割的 $w_{pos} = 5.0$。

运动规划使用 Boltzmann 分布形式的交叉熵损失:

$$p(\tau_i | o) = \frac{\exp(-\sum_{x_i, y_i \in \tau_i} c_o(x_i, y_i))}{\sum_{\tau \in \mathcal{T}} \exp(-\sum_{x_i, y_i \in \tau} c_o(x_i, y_i))}$$

其中 $c_o(x, y)$ 为 BEV 代价图上 $(x, y)$ 处的代价值,$\mathcal{T}$ 为 K-Means 聚类得到的 $K=1000$ 条模板轨迹。

4.3 关键代码

函数 / 类 任务
CamEncode 图像特征提取 + 深度分布/上下文预测
LiftSplatShoot.create_frustum 构建视锥体网格坐标
LiftSplatShoot.get_geometry 将视锥体坐标变换到 ego 坐标系
LiftSplatShoot.voxel_pooling Frustum Pooling(含 cumsum trick)
QuickCumsum 自定义 autograd 的高效累积求和
BevEncode BEV 特征编码器
📄 点击展开 CamEncode 代码

(来源:src/models.py

class CamEncode(nn.Module):
def __init__(self, D, C, downsample):
super(CamEncode, self).__init__()
self.D = D # 深度离散化数量(41)
self.C = C # 上下文特征维度(64)

# EfficientNet-B0 作为图像骨干网络
self.trunk = EfficientNet.from_pretrained("efficientnet-b0")

# 多尺度特征融合(reduction_5 + reduction_4)
self.up1 = Up(320+112, 512)
# 1×1 卷积同时输出深度分布和上下文特征
self.depthnet = nn.Conv2d(512, self.D + self.C, kernel_size=1, padding=0)

def get_depth_dist(self, x, eps=1e-20):
return x.softmax(dim=1)

def get_depth_feat(self, x):
x = self.get_eff_depth(x)
# Depth
x = self.depthnet(x)
# 前 D 个通道 → 深度分布 α(softmax 归一化)
depth = self.get_depth_dist(x[:, :self.D])
# 后 C 个通道 → 上下文特征 c
# 外积:c_d = α_d · c,得到 D×H×W×C 的视锥体特征
new_x = depth.unsqueeze(1) * x[:, self.D:(self.D + self.C)].unsqueeze(2)

return depth, new_x

def get_eff_depth(self, x):
endpoints = dict()
x = self.trunk._swish(self.trunk._bn0(self.trunk._conv_stem(x)))
prev_x = x
for idx, block in enumerate(self.trunk._blocks):
drop_connect_rate = self.trunk._global_params.drop_connect_rate
if drop_connect_rate:
drop_connect_rate *= float(idx) / len(self.trunk._blocks)
x = block(x, drop_connect_rate=drop_connect_rate)
if prev_x.size(2) > x.size(2):
endpoints['reduction_{}'.format(len(endpoints)+1)] = prev_x
prev_x = x
endpoints['reduction_{}'.format(len(endpoints)+1)] = x
# 融合 reduction_5(320ch)和 reduction_4(112ch)得到 512ch
x = self.up1(endpoints['reduction_5'], endpoints['reduction_4'])
return x

def forward(self, x):
depth, x = self.get_depth_feat(x)
return x
📄 点击展开 QuickCumsum(Frustum Pooling 核心)代码

(来源:src/tools.py

class QuickCumsum(torch.autograd.Function):
@staticmethod
def forward(ctx, x, geom_feats, ranks):
# 对已排序的特征做累积求和
x = x.cumsum(0)
# 标记 pillar 边界(ranks 变化的位置)
kept = torch.ones(x.shape[0], device=x.device, dtype=torch.bool)
kept[:-1] = (ranks[1:] != ranks[:-1])

# 只保留每个 pillar 的最后一个累积值
x, geom_feats = x[kept], geom_feats[kept]
# 相邻边界值做差 → 得到每个 pillar 内的 sum pooling 结果
x = torch.cat((x[:1], x[1:] - x[:-1]))

# 保存 kept 用于反向传播
ctx.save_for_backward(kept)
ctx.mark_non_differentiable(geom_feats)

return x, geom_feats

@staticmethod
def backward(ctx, gradx, gradgeom):
kept, = ctx.saved_tensors
# 解析梯度:将 pillar 的梯度广播回所有属于该 pillar 的点
back = torch.cumsum(kept, 0)
back[kept] -= 1
val = gradx[back]
return val, None, None
📄 点击展开 voxel_pooling 代码

(来源:src/models.py

def voxel_pooling(self, geom_feats, x):
B, N, D, H, W, C = x.shape
Nprime = B*N*D*H*W

# 展平特征和坐标
x = x.reshape(Nprime, C)

# 将连续坐标离散化到栅格索引
geom_feats = ((geom_feats - (self.bx - self.dx/2.)) / self.dx).long()
geom_feats = geom_feats.view(Nprime, 3)
batch_ix = torch.cat([torch.full([Nprime//B, 1], ix,
device=x.device, dtype=torch.long) for ix in range(B)])
geom_feats = torch.cat((geom_feats, batch_ix), 1)

# 过滤超出 BEV 网格范围的点
kept = (geom_feats[:, 0] >= 0) & (geom_feats[:, 0] < self.nx[0])\
& (geom_feats[:, 1] >= 0) & (geom_feats[:, 1] < self.nx[1])\
& (geom_feats[:, 2] >= 0) & (geom_feats[:, 2] < self.nx[2])
x = x[kept]
geom_feats = geom_feats[kept]

# 计算一维排序索引,使同一 pillar 的点相邻
ranks = geom_feats[:, 0] * (self.nx[1] * self.nx[2] * B)\
+ geom_feats[:, 1] * (self.nx[2] * B)\
+ geom_feats[:, 2] * B\
+ geom_feats[:, 3]
sorts = ranks.argsort()
x, geom_feats, ranks = x[sorts], geom_feats[sorts], ranks[sorts]

# cumsum trick 进行 sum pooling
if not self.use_quickcumsum:
x, geom_feats = cumsum_trick(x, geom_feats, ranks)
else:
x, geom_feats = QuickCumsum.apply(x, geom_feats, ranks)

# 将聚合特征填入 BEV 网格 (B × C × Z × X × Y)
final = torch.zeros((B, C, self.nx[2], self.nx[0], self.nx[1]), device=x.device)
final[geom_feats[:, 3], :, geom_feats[:, 2], geom_feats[:, 0], geom_feats[:, 1]] = x

# 沿 Z 轴展平 → BEV 伪图像
final = torch.cat(final.unbind(dim=2), 1)

return final

实验与分析

5.1 主要结果

物体分割(IoU %)

方法 nuScenes Car nuScenes Vehicle Lyft Car Lyft Vehicle
CNN Baseline 22.78 24.25 30.71 31.91
Frozen Encoder 25.51 26.83 35.28 32.42
OFT 29.72 30.05 39.48 40.43
Lift-Splat 32.06 32.07 43.09 44.64
PON* 24.7 - - -
FISHING Net* - 30.0 - 56.0

地图分割(IoU %)

方法 Drivable Area Lane Boundary
CNN Baseline 68.96 16.51
Frozen Encoder 61.62 16.95
OFT 71.69 18.07
Lift-Splat 72.94 19.96
PON* 60.4 -

注:PON 和 FISHING Net 使用不同的 BEV 网格定义和验证集划分,非严格对齐对比。

关键发现

  1. LSS 在所有 4 个物体分割任务和 2 个地图分割任务上全面超越基线
  2. 相比无几何先验的 CNN baseline,LSS 在车辆分割上提升近 10 个百分点(24.25→32.07),证明显式建模 3D 几何结构的重要性
  3. 相比 OFT(不做深度区分),LSS 的深度分布建模带来约 2% 的额外提升

5.2 消融实验:验证三个洞察

配置 nuScenes Vehicle IoU 验证洞察
CNN Baseline(无几何先验) 24.25 洞察 3
Frozen Encoder(深度隐式学习受限) 26.83 洞察 1
OFT(均匀深度分布) 30.05 洞察 1
Lift-Splat(学习深度分布) 32.07 洞察 1 + 2 + 3
训练时 Sensor Dropout(随机丢 1 相机) 最优性能(6 相机全在时) 洞察 3
训练时加外参噪声 对高噪声更鲁棒 洞察 3

注:CNN baseline 直接将所有相机特征拼接上采样到 BEV;Frozen Encoder 冻结 EfficientNet-B0 的预训练权重。

  • 洞察 1 验证:OFT(30.05)vs. Lift-Splat(32.07),学习深度分布优于均匀分配
  • 洞察 2 验证:Lift-Splat 的高效实现使得在 6 相机 × 41 深度点 × 8×22 特征图的规模上端到端训练成为可能,模型以 35 Hz 运行
  • 洞察 3 验证:CNN baseline(24.25)远低于 Lift-Splat(32.07),说明几何归纳偏置至关重要

5.3 性能瓶颈分析

与 Oracle Depth(LiDAR)对比

方法 Drivable Area Lane nuScenes Car nuScenes Vehicle
Oracle Depth (1 sweep) 74.91 25.12 40.26 44.48
Oracle Depth (>1 sweep) 76.96 26.80 45.36 49.51
Lift-Splat 70.81 19.58 32.06 32.07

主要性能差距来源:

  • 深度估计精度:单帧图像的隐式深度分布远不如 LiDAR 点云提供的真实深度
  • 远距离衰减:两种方法性能均随距离线性下降,但 LSS 衰减更快
  • 夜间场景:LSS 在夜间性能显著下降,而 LiDAR 不受光照影响

提升空间明确在于深度估计的质量——未来需要多帧时序信息来接近或超越 LiDAR 的深度精度。

5.4 失效场景分析

  • 夜间场景:图像质量大幅下降导致深度估计和语义理解同时恶化,性能相对 LiDAR 差距最大
  • 远距离物体:单目深度歧义随距离增大而加剧,远处车辆分割 IoU 明显低于 LiDAR baseline
  • 相机失效/遮挡区域:当缺失某个相机时,对应覆盖区域的预测变得模糊;后视相机(更宽视角)缺失时性能下降最大
  • 单帧运动推理:没有时序信息,模型无法准确判断物体运动状态和速度,限制了规划性能(Top-5 规划准确率 15.52% vs. LiDAR 1-sweep 19.27%)

工程实践

6.1 训练配置

Backbone:        EfficientNet-B0(ImageNet 预训练)
BEV Encoder: ResNet-18(层 1-3)+ 多尺度 FPN
Input Size: 128 × 352(裁剪并调整内外参)
BEV Grid: 200 × 200(-50m~50m, 0.5m/pixel)
Depth Range: 4.0m ~ 45.0m, step 1.0m(41 bins)
Optimizer: Adam, lr=1e-3, weight_decay=1e-7
Training Steps: 300k
Loss: BCEWithLogitsLoss(车辆/道路 pos_weight=1.0, 车道线 pos_weight=5.0)
Parameters: 14.3M
Inference Speed: 35 Hz (Titan V)
Framework: PyTorch

6.2 复现要点

  1. 输入预处理:图像裁剪到 128×352 后必须相应调整内参(焦距和主点)和外参,否则投影关系错误
  2. 深度离散化范围:4.0m~45.0m 间隔 1.0m 共 41 个 bin,过小的 step 会显著增加内存消耗(点云规模 = $n \times D \times H/16 \times W/16$)
  3. Frustum Pooling 实现:必须使用 QuickCumsum(含自定义 backward)而非 autograd 默认梯度,否则训练速度减半
  4. 正样本权重:车道线分割的 pos_weight=5.0 对平衡极度不均衡的正负样本至关重要
  5. Sensor Dropout 训练策略:训练时随机丢弃 1 个相机可提升模型在完整输入下的性能(类似 Dropout 正则化效果)
  6. BEV 网格 Z 轴:虽然生成 3D 体素,但最终通过沿 Z 轴 concatenate 展平为 2D BEV 伪图像,Z 轴分辨率不需要太高

6.3 性能优化方向

精度提升

  • 时序融合:引入多帧图像,通过时序信息提升深度估计精度(论文结论明确指出这是未来方向)
  • 深度监督:利用 LiDAR 投影深度对深度分布进行显式监督(后续 BEVDepth 已验证有效)
  • 更高分辨率 BEV 网格:增大 BEV 分辨率可提升小物体检测,但会增加 Frustum Pooling 的计算量

速度优化

  • 特征图下采样:增大 downsample 比例减少点云规模,但会损失空间分辨率
  • 深度 bin 数量:减少离散深度数量可线性降低计算量,但损失深度精度
  • BEV Encoder 轻量化:使用更轻量的 BEV 网络(如 MobileNet 替代 ResNet-18),训练和推理均加速
  • BEVPoolv2 算子优化:通过索引间接访问替代显式外积存储,避免计算和缓存完整的 $(N,D,H,W,C)$ 视锥体特征张量,速度可提升 3.1×15.1×,显存降至原先的 2%5.7%(详见 BEVDet 系列论文笔记

研究启示

7.1 可迁移的思想

  • “Lift-Splat” 范式:将任意 2D 传感器特征通过深度分布提升到 3D 再投射到 BEV 的流程,已成为多视图 BEV 感知的标准方案,被 BEVDetBEVDepthBEVFusionBEVFormer 等大量后续工作采用
  • 隐式深度分布建模:用 softmax 将深度概率分布与上下文特征外积的思想,可推广到任何需要处理深度不确定性的任务(如 3D 语义分割、占据栅格预测)
  • Cumsum Trick:基于排序的 scatter_add 替代方案(参见洞察 2),不仅适用于 pillar pooling,也可用于其他需要对稀疏数据按组求和的场景(如点云分割中的 voxel 特征聚合)
  • 几何归纳偏置:在模型中显式嵌入已知的物理/几何约束(如相机投影模型),比让网络从数据中隐式学习更高效、更可泛化

7.2 方法局限

  • 单帧推理缺少时序信息,深度估计精度有限,与 LiDAR 仍有明显差距
  • 深度分布无显式监督信号,完全依赖下游任务反向传播间接学习
  • Dense Lift 的空体素问题:每个像素按 $D$ 个 depth bin 展开后,$H \times W \times D$ 的视锥体中绝大多数体素概率接近 0(每个像素真实深度只有一个),带来显存浪费和计算冗余,后续 Sparse4D 等稀疏方案正是为解决这一问题而生
  • BEV 表示为固定范围栅格(100m×100m),难以高效处理更大范围或更精细分辨率的需求

7.3 技术影响

  • 开创 BEV 感知范式:LSS 是首个提出完整的”图像→视锥体→BEV”端到端流程的工作,直接催生了 BEVDet(2021)、BEVDepth(2022)、BEVFusion(2022)等显式深度路线,同时也启发了 BEVFormer(2022)等 query-based 路线,进而演化出 Sparse4D(2022)等 sparse query 方法——两条路线共同构成了当前 BEV 感知的技术版图
  • 推动纯视觉自动驾驶方案:证明了不依赖 LiDAR 进行 BEV 感知的可行性,对降低自动驾驶硬件成本具有重要意义(Tesla 纯视觉方案的理论基础之一)
  • Frustum Pooling 工程实践:QuickCumsum(scatter_add 的高效替代,参见洞察 2)及其 CUDA 实现被广泛复用,成为 BEV 感知 codebase 的标准组件
  • 引发 BEV 深度估计研究:LSS 暴露的深度估计瓶颈直接催生了 BEVDepth(LiDAR 深度监督)、STS(时空立体匹配)等一系列改进工作
  • 工业界偏好 LSS 范式:尽管 dense lift 产生大量空体素,但全流程均为连续内存的 dense tensor 计算(参见洞察 1),GPU 利用率高、TensorRT 易量化、延迟稳定;静态计算图利于 GPU/NPU 算子融合,BEVPoolv2 等工程优化进一步抵消空体素开销。相比之下,BEVFormer 的 query-driven attention 是 memory-bound 的随机访存,落地困难得多。因此 LSS 仍是 Tesla、NVIDIA 及国内多家 OEM 量产方案的主流架构——算得多但算得规整,比算得少但算得零散更适合 GPU