“预测未来的占用空间,然后在里面开车”——这是我看到这篇标题时脑子里蹦出来的第一句话。把自动驾驶的感知从“识别当前世界”推进到“预判未来世界”,这几年在学术界和工业界都卷得很凶,尤其是视觉中心的4D占用预测加规划这条线,算是我个人觉得世界模型落地最扎实的范式之一,没有那么多花哨的生成式大模型概念,就是把感知、预测、规划拧成一条实际能跑的链路。这篇文章就以“Driving in the Occupancy World: Vision-Centric 4D Occupancy Forecasting and Planning”为主题,把这个范式的核心拆开揉碎,讲清楚它解决的问题、技术链路、实操要点,以及真正落地时那几个绕不开的坎。
1. 范式背景:为什么“预测占用”比“检测障碍物”更适合当世界模型的抓手
1.1 从BEV到4D占用:世界模型到底在建模什么
过去几年视觉中心方案的主流做法是BEV感知,把环视摄像头图像通过几何变换和注意力机制统一投影到鸟瞰视角,在二维网格上检测车辆、行人、车道线。BEV感知的成熟让很多团队尝到了甜头,但也暴露了天花板:BEV是一个自顶向下的俯视平面,它天然丢失了空间中的垂向信息。立交桥下层的车、伸出去的树枝、半挂车的货箱高度——这些在BEV网格里都只能压成一个扁片,规划模块拿到这种表征以后,只能做一个非常粗糙的二维几何判断。
而4D占用预测做的事情完全不同。它在三维空间中定义一个体素化的立方体,预测每个体素在未来一段时间内是否被占据,以及被什么占据。这个“4D”指的是空间三维再加时间一维。就好比一个会游泳的人一头扎进水池里,水在他手里的感觉不是一张二维地图上的投影,而是整个水体在三维空间中的压力分布——哪里是实心的,哪里是空的,哪里会动,哪里会消失。
从世界模型的角度看,占用表示最接近“对世界状态的建模”。它不关心某个目标能不能被分类成一个准确的语义标签,它关心的是“这个空间区域现在有没有东西,未来会不会有东西,我能不能从旁边开过去”。这个表述跟规划的语法天然吻合。规划器不关心障碍物具体是什么品牌型号的轿车,它关心的是这条轨迹会不会擦到某个占据空间。
1.2 视觉中心的路线为什么能走到台前
占用预测最早流行是依赖激光雷达的。激光雷达点云天然提供三维几何信息,体素化以后算占用是很直接的。但激光雷达的成本、维护、稀疏性都限制了它在量产车上的大规模铺开。视觉中心方案的优势就在这里:低成本、高信息密度、可扩展性好,只要摄像头装到位、标定到位,理论上就能输出一个足够稠密的三维占用预测结果。
这里说的“视觉中心”不是简单地把图像像素投到三维空间那么就完了。纯粹的几何三角化在遮挡、反光、雨天这些情况下都会碎掉,所以这个范式的核心其实是数据驱动的三维重建与预测——让网络学会从多视角二维像素灰度中直接推理出三维体的占据变化规律,而不是依赖某一帧的几何一致性。
某团队在早期实验里测试过一个很有意思的场景:一辆公交车停在十字路口,视觉中心方案不仅能预测当前时刻公交车占据的空间,还能预测未来两秒公交车起步后让出来的空间。这就是把“感知”变成了“理解”,理解的输出是未来空间的状态。
1.3 这篇标题里的“Driving in”意味着什么
标题里最值得玩味的词是“Driving in”。它不是在说“看到”一个占用世界,而是说“在这个世界中驾驶”。也就是说,这篇工作指向的不是一个孤立的三维重建模块,而是把4D占用预测作为规划系统运行环境的完整闭环。车不是在几何空间里行驶,而是在一组不断更新的、带有未来信息的占用场中行驶。
这引出了世界模型范式的一个关键共识:世界模型的核心能力不是生成漂亮的画面,而是提供一套“未来状态推演”的空间底座。规划器基于这个世界底座,可以在每一个时间步反复查询、反复求值,而不是像传统方案那样先做一个障碍物列表再来碰撞检测。碰撞检测的对象不再是一组边界框,而是随时可查询的连续空间场。
2. 技术链路拆解:4D占用预测的输入、输出与关键结点
2.1 输入表示:环视相机如何进入体素空间
整条链路的起点是n路环视图像,以常见的6路相机为例,每路图像经过一个共享的视觉编码器,得到多尺度feature map。然后通过外参和内参将图像特征投影到三维空间。这里有一个关键选择:是用纯粹的几何投影加特征池化,还是用可学习的查询机制。
早期BEV方案里常用的方式是把图像特征沿着相机的视线方向在BEV网格上做投影池化,但这种方式在体素化三维空间里会有严重的深度模糊问题。一个像素可能对应体素链条上的一整列,根本无法判断到底该把特征放到哪一个深度上。后来的主流做法引入了显式深度估计:为每个像素预测一组深度概率分布,再把特征按概率加权投到对应深度位置。
这种做法的直觉类比是:一个人看远处的一棵树,他不能一次就说清楚树到底在50米还是60米,但他心里其实有一个概率区间,比如50到60米都有可能,只不过中间某个位置的可能性最大。显式深度估计就是把这种模糊性学出来,再让后续的三维卷积/注意力结构去消化。
除了图像,还需要输入相机位姿、传感器内外参、时间戳序列。如果做的是未来占用预测,通常会给模型一个历史帧序列,比如过去1秒的6帧图像,让网络建立运动学的时间上下文。
2.2 输出定义:体素网格的粒度与标签设计
所有4D占用预测模型的输出端都定义在一个有限范围的三维空间包围盒内。常见范围是x方向[-50m, 50m],y方向[-50m, 50m],z方向[-5m, 3m]左右,体素分辨率常见从0.4m到1.0m不等。0.5m分辨率下,这个空间大约有200乘200乘16个格子,也就是64万个体素。对每个体素,模型要输出两个东西:占据概率和语义类别概率。
比较讲究的工作还会额外输出一个“未来占用流”或者“速度场”,也就是每个体素在未来哪个方向运动。这个东西在规划时非常重要——如果只知道某个体素未来会被占据,但不知道它是静止的还是快速向左移动,碰撞代价的估计就会失真。
我见过最实用的标签设计是这样的:三维空间划分成三类标签——空闲、静态占据、动态占据。其中动态占据再细分成车辆、行人、骑车人、背景动态等类别。为什么不要做得过细?因为感知的最终目的是为了规划可行驶空间,粒度过细会造成类别数膨胀、样本不均、训练困难,而且规划器也不真的关心一辆皮卡和一辆MPV的区别。
2.3 时间维度:预测未来多长时间才算有意义
4D里的第四个维度“未来”,到底要预测多远?这是非常实际的问题。规划决策的典型时间窗口是3到8秒:一个紧急刹停可能只需要0.5秒,但一个变道超车或过路口动作需要至少5秒以上的安全视野。理论上预测越长越有用,但预测误差随时间指数累积,预测6秒以后的占用场基本就是一团糊。
当前实践中比较务实的配置是:预测未来1到3秒,以0.5秒为间隔输出中间帧。如果要做更长时域的规划,可以级联两段式预测——先预测前3秒的稠密结果,再把这3秒的中间状态当作条件输入继续滚后续的3秒。这种方式有点类似自回归解码,能有效缓解一次性长时预测的blurry问题。
另一个常见做法是双时间尺度:高频短时预测(比如0.5秒间隔、2秒时长)供轨迹规划闭环使用,低频长时预测(比如1秒间隔、5秒时长)供决策层做变道意图、让行判断等宏观行为规划使用。两条分支共享同一个三维特征主干,只在解码头分叉,算力增加有限,收益却很直接。
2.4 监督信息与损失函数设计经验
训练4D占用预测模型,最理想的情况是有激光雷达点云密集标注的未来帧,直接投影到体素网格生成真值。但在实际道路上,未来时刻的点云真值并不容易获取,尤其是在自车也在运动的情况下,需要非常精确的位姿补偿。
更现实的做法是利用多帧拼合的重建结果作为伪真值。某实验室在这块的经验是:先离线做一帧稠密深度估计,再跨帧匹配出场景流,把场景流推演到未来时刻生成占用伪真值。这一步做得好不好,直接决定了模型的上限。
损失函数方面,一般组合以下四部分:
- 占据分类损失:focal loss,解决空体素远多于占固体素的正负样本不均衡问题
- 语义分类损失:对占固体素预测类别,用带类别权重的cross entropy处理长尾
- 未来流回归损失:对动态体素预测速度场,用smooth L1
- 时间一致性损失:相邻预测帧之间的体素特征应尽量平滑,加一个L2约束
这个组合看着简单,但每个权重都值得仔细调。占主导的是第一项,如果一个场景空体素占95%以上,随便把权重分配不当,模型就会退化成一个全空闲的平凡解。所以我习惯在训练初期把focal loss的伽玛设置到2.0到2.5之间,并且把分类损失权重压低,让模型先学会“哪儿有东西”,再去学会“是什么东西”。
3. 从占用到规划:预测结果怎么真正驱动车辆
3.1 两条主流路线:显式语义查询与隐式端到端
拿到预测好的4D占用场之后,规划模块怎么用?目前有两条路线在互相竞争。
第一条是显式查询路线。规划器在生成一批候选轨迹后,逐条沿着轨迹的未来位置查询附近的占用体素,把相邻未来帧的占用概率当作碰撞风险成本放到轨迹代价函数里。这种做法的好处是可控、透明、可调试,跟传统的采样规划、优化规划框架兼容。最近不少量产方案都在尝试这条路线:预测模块输出一个“代价体积”,规划模块在这个代价体积上做轨迹优化。
第二条是隐式端到端路线。占用场不显式输出给规划器,而是直接作为中间特征流进一个神经网络策略头,由网络直接输出转向、油门、制动信号。这种做法训练目标更对齐最终的驾驶指标,但缺点是很难解释模型为什么在某个路口突然减速。
我个人看法是,在安全冗余和工程可维护性面前,显式查询路线更能打动团队负责人,因为出了问题能定位。但隐式端到端路线确实在跨场景泛化上展现出更强潜力,适合研究性的项目去冲上限。
3.2 轨迹代价设计:怎么把占用场变成加减速决心
这里我们详细说一下显式查询路线的代价函数实现。假设规划模块采样了M条候选轨迹,每条轨迹包含未来N个时刻的位置点。对轨迹j上的第k个未来时刻,我们从预测的占用场中预测对应时刻的占用概率分布,取轨迹点周围邻域内的最大占用概率或者加权和,得到碰撞风险项。
但直接拿概率最大的体素不太稳,因为单个体素预测噪声大,更稳的做法是考虑一个矩形包围的邻域,维度与车宽、车长相关。比如说车的宽度是2米,体素是0.5米,那至少要考虑横向左右各两个体素的范围。在这个范围内对占用概率和对应的速度场做积分,得到一个综合碰撞风险。
还有一个非常容易踩坑的点:轨迹点的“未来时刻”与占用预测帧的“时间索引”要对齐。很多团队第一次做的时候没用时间对齐,把第3秒的占用概率直接套在轨迹的第1秒位置上,结果高速场景下轨迹被白白惩罚,车开起来一顿一顿的。
除了碰撞项,代价函数里一般还有:
- 参考线偏移代价:鼓励轨迹贴近车道中心
- 速度波动代价:避免频繁加减速
- 加速度与加加速度代价:保证乘坐舒适性
- 语义区域代价:比如占用场预测的“人行横道”区域,即便当前空闲也要给一个温和的减速倾向
我见过一个很好的工程优化:把碰撞代价计算做成并行的体素查询表,轨迹采样完后直接查表求值,而不是逐个体素做神经网络推理。这样整个规划周期能把代价计算压在5到10毫秒以内,为决策和冗余争取了大量时间预算。
3.3 未来的车辆如何应对未知区域
现实场景里,预测模型总会遇到没见过的区域。占用预测模型在训练分布外的场景(比如突发交通事故造成的大规模占道)会退化,输出一个很模糊的高熵概率场。规划器在这种高熵场里如果还机械地做碰撞代价求值,容易陷入两个极端:要么过于保守——整个前路都是高风险,车直接刹死;要么过于激进——碰撞概率都高,选了一个碰撞风险相对最低但实际已经非常危险的轨迹。
应对这个问题的核心是置信度门控机制。规划器不仅要看占用概率,还要看预测头输出的“不确定性”估计。如果某个区域的不确定性超过阈值,就把它视作“不可行驶告警区”,规划器必须强制放慢速度,并且缩小转向幅度。这个机制像一个安全护栏,随时兜住感知模型能力退化时的底线。
更进一步,如果配合车端的高精定位和地图拓扑信息,还可以把地图上的静态先验与预测的占用场融合,用地图给“不可能出现障碍物”的区域打一个置信度先验,反过来压低误报导致的频繁刹停。
4. 项目实践复盘:这套范式跑通一个Demo的完整代价
4.1 硬件选型与算力分配
在真正动手做这个项目之前,还有一个绕不开的现实问题:这套系统到底要多少算力才跑得动?我以一个中等难度的验证级Demo来算一笔账:6路1080p摄像头输入,输入帧率10Hz,预测窗口3秒、0.5秒间隔输出6帧,体素范围是x-y各80米、z 8米,分辨率0.5米。
视觉编码器部分(比如一个小型的ReNet或者Eff-Encoder)在6路图像上并行跑,大概需要10到15 TFLOPS的算力。三维体积编码器和解码器部分是最贵的,一个基于3D卷积的体积网络在80米立方体0.5米分辨率下,单帧前向就要跑8到12 TFLOPS。如果算上6帧未来预测的自回归推理,整体峰值算力接近35 TFLOPS,显存消耗在12GB到20GB之间。
这意味着消费级显卡(比如单张中高端显卡)只能勉强跑离线推理,不太可能上车实时运行。实际车端如果要跑这套方案,要么做模型蒸馏,要么大幅降低预测帧数和分辨率,比如把预测窗口缩到1.5秒、体素分辨率放到0.8米。
我建议团队在起步阶段先不急着上车,用一段离线采集的复杂路口数据,把预测的占用视频可视化出来,先看看模型能不能直观地想明白这个路口发生了什么事。可视化这一步能发现大量坐标、对齐、设备时延问题,比直接看指标有用十倍。
4.2 数据闭环:最容易被低估的坑
任何一个视觉中心模型的效果上限都由数据和标注质量决定,占用预测模型尤甚。图像数据本身虽然便宜,但真值生成很贵。激光雷达能够提供稠密的真值,但标定误差、时间同步误差会直接污染体素真值。通常说“同步误差5毫秒内可接受”,但在一个车速72公里每小时的车上前进20厘米,体现在体素占用上就是一个格子,时间同步不过关,真值就直接废掉。
某项目组在早期实验时发现预测准确率怎么都上不去,排查了两个星期,最后定位到是相机与定位系统的时间戳有80毫秒的固定偏移。把偏移修正后指标直接涨了四个点。这个经历让我养成了一个习惯:任何一次开始训练前,先随机选一帧数据,从图像、点云、投影坐标、真值车道几个通道手工对一遍,宁可慢一点,不要把脏数据喂给模型。
数据闭环另一个重点是要主动搜集“硬场景”:路口拥堵、鬼探头、异形车、洒水车扬雾、夜间对向远光。这些场景占比可能不到总量的5%,但决定了模型在真实驾驶中的可用性。很多团队用全量数据训练,结果模型在常规场景上指标很漂亮,一到长尾就原形毕露。
更好的策略是分阶段训练:先用均匀采样的数据训通用编码器,再用重采样的难例数据微调预测头和解码器,最后用小批量人工标注的极端场景做正则。
4.3 与端到端驾驶方案的关系:不是对立,是互补
很多人把视觉中心4D占用预测和纯端到端驾驶对立起来看,觉得一个是老派模块化、一个是新派神经网络。但实际项目经验告诉我,两者更合理的定位是互补关系。4D占用预测提供了一个显式的空间推理底座,纯端到端方案提供了一个高效的策略映射。不少团队已经在尝试把两者串成一条管线:占用场作为可微分的中间表示,梯度可以同时回传到预测网络和规划网络,两边一起训练。
这样一来,感知预测模块能直接感受到规划损失的压力,比如模型发现某个区域对最终转向特别关键,它就会在该区域多分配一些特征分辨率;规划模块也能借助占用场的平滑性获得更稳健的梯度支撑。这种“预测-规划联合训练”的模式,本质上是把世界模型的两种用途——描述世界和优化行动——在同一个框架里统一了。
当然,联合训练也带来新的烦恼:两个任务的loss尺度差很远,规划损失一个单位的波动可能把预测头压垮。我看过比较稳的训练调度是分段式优化:前60%的epoch只训感知预测,把占用场训到一个足够好的初始状态;后40%的epoch打开规划损失,用一个很小的权重(比如整体损失的5%)逐步注入。
4.4 实际可参考的最小模块清单
最后给想要走一遍这条链路的朋友画一个最小模块清单,方便对着做:
| 模块 | 功能 | 输入 | 输出 | 参考配置 |
|---|---|---|---|---|
| 多视角图像编码器 | 提取图像特征 | 6路环视图像 | 多尺度特征图 | ReNet18级,约2G FLOPs/路 |
| 几何投影模块 | 像素特征投影到体素空间 | 图像特征、内外参、深度估计 | 体素特征种子 | 深度估计用LSS风格概率分布 |
| 三维体积编码器 | 在体素空间编码上下文 | 体素特征种子 | 稠密体素特征 | 3D卷积或稀疏卷积,5千万参数级 |
| 时间融合模块 | 按时间序列融合历史帧 | 历史体素特征 | 当前状态特征 | 使用门控循环结构或轻量transformer |
| 未来预测解码器 | 递归预测未来占用 | 当前状态特征 | 多帧占用概率+语义+流 | 采用共享解码头加时间偏移查询 |
| 轨迹采样器 | 生成候选轨迹 | 车身状态、参考线、语义图 | M条轨迹 | 采样模型为横向偏移+纵向速度段 |
| 代价评估器 | 把占用场映射为轨迹代价 | 轨迹、占用场 | 每条轨迹的代价向量 | 并行查表实现,5到10毫秒 |
| 安全门控 | 不确定性兜底 | 占用不确定度 | 允许速度上限 | 设定阈值,动态降级 |
这个清单不需要一次全部做完,也可以先只实现前五个模块,输出预测结果用三种彩色语义渲染出来,先靠在可视化里判断模型学得怎么样。等可视化结果看着顺眼了,再往后面接轨迹采样和代价评估,整条链路从“能看到未来了”升级成“能驾驶在预测的世界里”。
我自己的体会是,这个项目最迷人的部分恰恰是最后一步——当预测的占用场像水一样轻轻让开给规划轨迹留出一条路的时候,你会觉得这辆车真的“理解”了一点周围世界。它不再仅仅是用摄像头看路的机器,而是在心里对即将到来的空间有个预判,然后像一个老司机一样从容地把自己放进那些“即将空出来”的位置里。