专栏算法工具链【地平线工具链参考算法|J6|HEAL】LiDAR-Camera 融合多任务BEVFusion_v3.0

【地平线工具链参考算法|J6|HEAL】LiDAR-Camera 融合多任务BEVFusion_v3.0

芯链情报局2026-08-25
22
0

该示例为参考算法,仅作为在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 作为激光雷达流,从而展示模型框架的优秀泛化能力。

动态融合模块

动态融合模块的作用是将concat后的相机、 LiDAR的 BEV特进行有效融合。受 Squeeze-and-Excitation 机制的启发, BEVFusion应用一个简单的通道注意力模块来选择重要的融合特征,网络结构图如下所示:

Occupancy 任务头

除了公版BEVFusion就存在的3D 检测头外,参考算法增加了Occ任务头做占用预测,和3D检测头共用特征部分,从而极大地节省了计算资源。Occ任务头复用了FlashOcc中的head进行设计,通过通道转高度模块将BEV特征沿通道维度执行简单的重塑操作。相关代码如下:
代码路径:heal/models/task_modules/flashocc/bev_occ_head.py

Occ label坐标转换

由于Occ label是在ego坐标系中标注的,所以需要将其统一到Lidar坐标系,相关代码如下:

代码路径:heal/data/datasets/nuscenes_dataset.py

Bev 特征裁剪

bev的空间范围为[51.2,51.2],grid尺寸为128x128;而occ的空间范围为[40,40],grid尺寸为128x128。为了将bev空间范围对齐到Occ,occ_head中根据比例将128x128的bev feature从中心裁剪出100x100的roi,从而满足40/51.2=100/128。相关代码如下:
代码路径:configs/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes/model.py

地平线部署说明

BEVFusion参考算法采用BEVFormer和centerpoint分别生成视觉和LiDAR BEV特征,然后使用SE模型融合BEV特征,最后将BEV特征解码。

改动点:

  1. 相机流使用了地平线深度优化后的bevformer参考算法,并将其转换到LiDAR坐标系,其相对于公版的优化如下:

    1. 使用地平线深度优化后的高效backbone HENet提取图像特征;

    2. 将attention层的mean替换为conv计算,使性能上获得提升;

    3. 公版模型中,在Encoder的空间融合模块,会根据bev_mask计算有效的query和reference_points,输出queries_rebatch和reference_points_rebatch,作用为减少交互的数据量,提升模型运行性能。对于稀疏的query做crossattn后再将query放回到bev_feature中;

    4. 修复了公版模型中时序融合的bug,并获得了精度上的提升,同时通过对关键层做int16的量化精度配置以保障1%以内的量化精度损失。

  2. LiDAR流采用了地平线深度优化后的centerpoint参考算法,其相对于公版的优化如下:

    1. 前处理部分的输入为5维点云并做归一化处理,对量化训练更加友好;

    2. PillarFeatutreNet 中的 PFNLayer 使用 Conv2d + BatchNorm2d + ReLU,替换原有的 Linear + BatchNorm1d + ReLU,使该结构可在BPU上高效支持,实现了性能提升;

    3. PillarFeatutreNet 中的 PFNLayer 使用 MaxPool2d,替换公版的 torch.max,便于性能的提升;

    4. Scatter过程使用horizon_plugin_pytorch优化实现的point_pillars_scatter,便于模型推理优化,逻辑与torch公版相同;

    5. 对于耗时严重的OP,采用H、W维度转换的方式,将较大维数放到W维度,比如1x5x40000x20 转换为 1x5x20x40000;

  3. 相对于公版,增加了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倍下采样。以下为总体的结构配置:

代码路径:heal/models/backbones/henet.py

改动点2:

bevformer中的Temporal Self-Attention通过引入时序信息与当前时刻的 BEV Query 进行融合,提高 BEV Query 的建模能力,Temporal Self-Attention中最关键的结构为MultiScaleDeformableAttention。

经评估,该模块中的mean对性能影响较大,参考算法中将其替换为固定weight的conv计算,从而获取性能上的提升,相关代码:

代码路径:heal/models/base_modules/bevformer_attention.py

改动点3:

Spatial Cross-Attention利用 Temporal Self-Attention 模块输出的 bev_query, 对主干网络和 Neck 网络提取到的多尺度环视图像特征进行查询,生成 BEV 空间下的BEV Embedding特征。公版的BEVFormer中采用bevmask来减少camera的query点数的优化,但是由于涉及到BPU不支持的动态shape,并且涉及到运行效率较低的gather/scatter操作(当前gather算子已经支持 BPU加速)。进一步分析发现:
  • 从bev voxel的角度来看,中心点到multi camera的映射是稀疏的;

  • 从bev pillar的角度来看,通常每个pillar只会映射到1-2个camera;

基于以上分析以及实验结果,参考算法在设置了virtual_bev_h、virtual_bev_w、max_numcam_overlap这3个参数对稀疏率进行配置,这3个参数的具体含义是:
  • virtual_bev_h:虚拟bev的高度,用于计算将稀疏点集恢复为密集bev的网格,参考算法中配置为64;

  • virtual_bev_w:虚拟bev的宽度,用于计算将稀疏点集恢复为密集bev的网格,参考算法中配置为80;

  • max_numcam_overlap:每个bev pillar映射到的最多camera数量,参考算法中配置为2;

代码路径:configs/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes/model.py

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,便于性能的提升,对应代码:

代码路径:heal/models/task_modules/lidar/pillar_encoder.py

改动点2:

如上图所示,Scatter是实现伪图像转换的重要一个步骤,参考算法使用horizon_plugin_pytorch实现的point_pillars_scatter,便于模型推理优化,逻辑与公版相同。对应代码:
其中,核心函数point_pillars_scatter是在horizon_plugin_pytorch中实现的。
代码路径: heal/models/task_modules/lidar/pillar_encoder.py

动态融合模块

相对于公版的动态融合模块(参考3.3节),参考算法在 concat后新增了 1 个conv1x1,有助于性能的提升,相关代码如下:

代码路径: heal/models/task_modules/lidar_fusion/fusion_module.py

精度优化

浮点精度

旋转增强

在模型训练时,参考算法对bev进行旋转增强,相关代码如下:

代码路径:

configs/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes/data.py

heal/data/transforms/multi_views.py

加载预训练模型

为了提升浮点模型的精度,浮点训练时相机流和LiDAR流分别加载了预训练模型,然后再共同训练,对应代码如下:

代码路径:configs/bevfusion_pointpillar_henet_multisensor_multitask_nuscenes/train.py

量化精度

BEVFusion参考算法采用的量化策略为全int8+部分敏感算子配置为int16。最新接口下,所有量化配置集中在 qconfig.py 的 QconfigSetter 模板中(早期版本在模型 set_qconfig 中设置,现已统一迁移到模板,匹配兄弟 config 的写法)。校准采用 HistogramObserver,qat 采用 MinMaxObserver
其中 bevformer 部分(bev_decoders.0 的 object query / reference-point 投影、layers.5.sa.matmul)配置为 int16 输出,lidar_net 的 neck 敏感算子通过 SensitivityTemplate 提升 int16 精度(topk_or_ratio=1.0 即全部命中算子均提升)。
注:早期版本中这部分 int16 配置写在 MultiScaleDeformableAttention 模型的 set_qconfig 方法内(通过 qconfig_manager.get_qconfig 单独设置 sampling_offsets / quant_shape / norm_offset / add_offset / add1 / mul1 等);最新接口已将其统一迁移到 qconfig.py 的 ModuleNameTemplate,量化配置不再依赖模型内部的 set_qconfig。
模型基于int8的量化配置下做calibration,若出现精度掉点问题参考用户手册中的量化感知训练--开发指南--精度调优工具使用指南章节做badcase的debug分析,基于debug信息对部分算子配置更高的精度或者尝试手动处理。

总结与建议

训练建议:

  • 建议在浮点训练时分别加载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的部署经验,可以推广到其他多传感器多任务模型的部署中。

附录

  1. 参考算法(modellabs)官网:https://(待发布)

  2. 论文:BEVFusion
  3. 公版模型代码:https://github.com/ADLab-AutoDrive/BEVFusion

算法工具链
技术深度解析官方教程征程6
评论0
0/600