该示例为参考算法,仅作为在J6上模型部署的设计参考,非量产算法。
简介
激光雷达天然地具有深度信息,摄像头可以提供丰富的语义信息,它们是车载视觉感知系统中两个最关键的传感器。但是,如果激光雷达或者摄像头发生故障,则整个感知框架不能做出任何预测,这在根本上限制了实际自动驾驶场景的部署能力。目前主流的感知架构选择在特征层面进行多传感器融合,即中融合,其中比较有代表性的路线就是BEV范式。BEVFusion就是典型的中融合方法,其存在两个独立流,将来自相机和LiDAR的原始输入编码为同一个BEV空间。由于是通用的融合框架,相机流和LiDAR流的方法都可以自由选择,在 nuScenes 数据集表现出了很强的泛化能力。本文将介绍BEVFusion在地平线J6E/M平台上的优化部署。
性能精度指标
模型参数:
模型 | 数据集 | Input shape | LiDAR Stream | Camera Stream | BEV Head | Occ Head |
|---|---|---|---|---|---|---|
BEVFusion | Nuscenes | 图像输入:6x3x512x960 点云输入:1x5x20x40000 | CenterPoint | BEVFormer | BEVFormerDetDecoder | BevformerOccDetDecoder |
性能精度表现:
浮点/定点精度 | J6M Latency | J6M FPS | ||
|---|---|---|---|---|
NDS | mAP | MIOU | ||
0.6421/0.6293 | 0.5825/0.5719 | 0.5187/0.5206 | 23.93 ms | 49.41 |
模型介绍
BEVFusion主要由相机流、激光雷达流、动态融合模块和检测头组成,下面将逐一进行介绍。

相机流
相机流将多视角图像转到BEV空间,由图像编码器、视觉投影模块、BEV编码器组成。
图像编码器
图像编码器旨在将输入图像编码为语义信息丰富的深度特征,它由用于基本特征提取的2D backbone Dual-Swin-Tiny和用于多尺度特征提取的FPN组成,并采用了一个简单的功能自适应模块ADP来完善上采样功能,如下图所示:

视觉投影模块
视觉投影模块采用LSS将图像特征转换为3D自车坐标,将图像视图作为输入,并通过分类方式密集地预测深度。
然后,根据相机外参和预测的图像深度,获取伪体素。
BEV编码模块
BEV编码模块采用空间到通道(S2C)操作将4D伪体素特征编码到3D BEV空间,从而保留语义信息并降低成本。然后又使用四个3 × 3卷积层缩小通道维度,并提取高级语义信息。
LiDAR流
LiDAR流将激光雷达点转换为BEV空间,BEVFusion采用3种流行的方法,PointPillars、CenterPoint和TransFusion 作为激光雷达流,从而展示模型框架的优秀泛化能力。
动态融合模块

Occupancy 任务头
Occ label坐标转换
由于Occ label是在ego坐标系中标注的,所以需要将其统一到Lidar坐标系,相关代码如下:
Bev 特征裁剪
地平线部署说明
BEVFusion参考算法采用BEVFormer和centerpoint分别生成视觉和LiDAR BEV特征,然后使用SE模型融合BEV特征,最后将BEV特征解码。
改动点:
相机流使用了地平线深度优化后的bevformer参考算法,并将其转换到LiDAR坐标系,其相对于公版的优化如下:
使用地平线深度优化后的高效backbone HENet提取图像特征;
将attention层的mean替换为conv计算,使性能上获得提升;
公版模型中,在Encoder的空间融合模块,会根据bev_mask计算有效的query和reference_points,输出queries_rebatch和reference_points_rebatch,作用为减少交互的数据量,提升模型运行性能。对于稀疏的query做crossattn后再将query放回到bev_feature中;
修复了公版模型中时序融合的bug,并获得了精度上的提升,同时通过对关键层做int16的量化精度配置以保障1%以内的量化精度损失。
LiDAR流采用了地平线深度优化后的centerpoint参考算法,其相对于公版的优化如下:
前处理部分的输入为5维点云并做归一化处理,对量化训练更加友好;
PillarFeatutreNet 中的 PFNLayer 使用 Conv2d + BatchNorm2d + ReLU,替换原有的 Linear + BatchNorm1d + ReLU,使该结构可在BPU上高效支持,实现了性能提升;
PillarFeatutreNet 中的 PFNLayer 使用 MaxPool2d,替换公版的 torch.max,便于性能的提升;
Scatter过程使用horizon_plugin_pytorch优化实现的point_pillars_scatter,便于模型推理优化,逻辑与torch公版相同;
对于耗时严重的OP,采用H、W维度转换的方式,将较大维数放到W维度,比如1x5x40000x20 转换为 1x5x20x40000;
相对于公版,增加了OCC 任务头,实现了LiDAR+Camera+OCC动静态二网合一;
性能优化
相机流
公版 BEVFusion使用流行的Lift-Splat-Shoot(LSS)并适度调整以提高性能。参考算法直接采用了地平线深度优化后的 BEVFormer参考算法作为相机流网络,bev网格的尺寸配置为 128 x128。
改动点 1:
backbone由公版的Dual-Swin-Tiny替换为地平线的高效 backbone HENet,不仅在精度上可与 ResNet50 相媲美,而且在性能上有显著优势。
HENet是针对J6平台专门设计的高效backbone,其采用了纯CNN架构,总体可分为四个stage,每个stage会进行2倍下采样。以下为总体的结构配置:
改动点2:
经评估,该模块中的mean对性能影响较大,参考算法中将其替换为固定weight的conv计算,从而获取性能上的提升,相关代码:
改动点3:
从bev voxel的角度来看,中心点到multi camera的映射是稀疏的;
从bev pillar的角度来看,通常每个pillar只会映射到1-2个camera;
virtual_bev_h:虚拟bev的高度,用于计算将稀疏点集恢复为密集bev的网格,参考算法中配置为64;
virtual_bev_w:虚拟bev的宽度,用于计算将稀疏点集恢复为密集bev的网格,参考算法中配置为80;
max_numcam_overlap:每个bev pillar映射到的最多camera数量,参考算法中配置为2;
LiDAR流
公版BEVFusion采用了当前流行的 3 种激光点云检测模型PointPillars , CenterPoint和TransFusion作为LiDAR流来展示框架的通用性。BEVFusion参考算法复用了经过深度优化的 centerpoint参考算法,其相对于公版主要做了以下性能优化,下面将逐一介绍。
改动点1:
为了应用 2D 卷积架构,PillarFeatutreNet将点云(P,N,5)转换为2D伪图像,整体步骤如下图所示:
公版模型中PillarFeatutreNet 中的部分算子在 BPU运行效率比较低,所以参考算法对其做了替换:
PillarFeatutreNet 中的 PFNLayer 使用BPU上运行比较高效的 Conv2d + BathNorm2d + ReLU算子,替换了公版的 Linear + BatchNorm1d + ReLU结构,实现了性能的提升;
PillarFeatutreNet 中的 PFNLayer 使用 MaxPool2d,替换原有的 torch.max,便于性能的提升,对应代码:
改动点2:
动态融合模块
相对于公版的动态融合模块(参考3.3节),参考算法在 concat后新增了 1 个conv1x1,有助于性能的提升,相关代码如下:
精度优化
浮点精度
旋转增强
在模型训练时,参考算法对bev进行旋转增强,相关代码如下:
代码路径:
configs/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes/data.py
heal/data/transforms/multi_views.py
加载预训练模型
为了提升浮点模型的精度,浮点训练时相机流和LiDAR流分别加载了预训练模型,然后再共同训练,对应代码如下:
量化精度
注:早期版本中这部分 int16 配置写在 MultiScaleDeformableAttention 模型的 set_qconfig 方法内(通过 qconfig_manager.get_qconfig 单独设置 sampling_offsets / quant_shape / norm_offset / add_offset / add1 / mul1 等);最新接口已将其统一迁移到 qconfig.py 的 ModuleNameTemplate,量化配置不再依赖模型内部的 set_qconfig。
总结与建议
训练建议:
建议在浮点训练时分别加载Lidar流和相机流的预训练模型,然后再训练整个网络;
建议选择合适的bev grid size,实验中发现bev grid size配置为128x128时的精度比50x50要高;
对于多任务模型,建议在量化训练适当增加epoch,即量化训练不一定要严格按照浮点训练的1/10 epoch来训练;
- 浮点训练时采用CosineAnnealingLrUpdater策略,量化训练时采用StepDecayLrUpdater策略,对于此模型来说,采用StepDecayLrUpdater策略对量化训练精度更友好;
部署建议:
- 点云前处理当前为 CPU计算,对性能不是很友好,建议参考J6工具链用户手册【统一计算平台(UCP)】-DSP示例章节将点云前处理放在 DSP上进行计算加速;
建议在模型架构设计之初就考虑采用地平线深度优化后的backbone或者网络作为base model;
在注意力机制中存在一些add、sum等ElementWise操作,对于导致性能瓶颈的可以考虑conv替换,对于造成量化风险的可以根据敏感度分析结果合理选择更高的量化精度,以确保注意力机制的部署;
建议在选择bev size时考虑性能影响。J6相比于J5带宽增大,但仍需注意bev size过大导致访存时间过长对性能的影响,建议考虑实际部署情况选择合适的bev size;
若出现性能问题可以通过优化backbone或者减少层数或者点数的方式来提升性能,但要注意以上操作可能会导致精度损失,请优先考虑对点数的减少等对精度的影响较小性能收益最高的操作;
本文通过对BEVFusion在地平线征程6上量化部署的优化,使得模型在J6E上得到FPS为32.4的部署性能,同时,通过BEVFusion的部署经验,可以推广到其他多传感器多任务模型的部署中。
附录
参考算法(modellabs)官网:https://(待发布)
- 论文:BEVFusion
公版模型代码:https://github.com/ADLab-AutoDrive/BEVFusion
