2026/3/29 1:06:53
网站建设
项目流程
dede网站首页加悬浮广告,用手机下载地图到内全卡,想要标注倾斜直线的实际长度,云开发cms内容管理系统1. 简介
在自动驾驶领域#xff0c;BEV 是一种从上方看对象或场景的视角#xff0c;通过多个不同视场的传感器融合成 BEV 特征#xff0c;可以提供车辆周围环境的完整视图#xff0c;供下游任务使用#xff0c;例如障碍物检测#xff0c;路径规划等。
基于 BEV 的环境感…1. 简介在自动驾驶领域BEV 是一种从上方看对象或场景的视角通过多个不同视场的传感器融合成 BEV 特征可以提供车辆周围环境的完整视图供下游任务使用例如障碍物检测路径规划等。基于 BEV 的环境感知目前主要是有两种技术路线一种是以 petr 为代表的 sparse bev 方法它的主要思路是通过 3D 位置编码和 2D 的特征直接生成融合特征再用基于 transformer 的 decoder 实现环境感知这个过程不需要显式地生成 Dense Bev 特征 另一种是以 bevformer 为代表的 dense bev 方法该方法利用内外参信息将 2D 特征融合到一个 BEV 特征再用 BEV 特征来进行后续的感知或规划任务。基于 Dense Bev 的方法可以很方便地实现多传感器融合和多任务预测因此在自动驾驶领域被广泛应用。地平线面向智驾场景推出的征程 6 系列J6芯片在提供强大算力的同时带来了极致的性价比。BEVFormer 是当前热门的自动驾驶系统中的 3D 视觉感知任务模型我们基于 BevFormer 与征程 6 芯片优化了多视图融合生成 Dense Bev 特征的方案进一步提升基于 Dense Bev 的算法推理效率。本文将详细介绍参考算法对 BevFormer 中 ViewTransformer 优化方法以及模型端侧的表现。2. 性能精度指标BEVFormer 为参考算法 V1.0 版本BEVFormer-OPT 为优化后的参考算法 V2.0 版本地平线 3D 目标检测 Bevformer 参考算法-V2.0BEVFormer-OPT 使用了 Dense Bev 的优化方案3.优化方法介绍3.1 整体架构本文的 Dense Bev 方案是基于 BevFormer 的模型结构进行优化而来参考算法 BevFormer 介绍见地平线 3D 目标检测 Bevformer 参考算法-V1.0 这里不再赘述。在 BevFormer 中SpatialCrossAttention 模块是用来做空间融合的即将多个 2D 视图特征融合成 Bev 特征由于公版的 BevMask 会根据内外参进行动态变化进而导致模型中出现动态 Shape对部署非常不友好因此在 V1 版本中我们直接去掉了 BevMask虽然对部署更友好了但是 SpatialCrossAttention 模块多了很多冗余的计算和 IO对性能影响很大。整体框架如下图所示3.2 方案优化点3.2.1 使用 BevMask在优化方案中我们对内外参生成 BevMask 的原理做了详细的分析发现当相机传感器位置固定时内外参转换矩阵即固定轻微抖动对 BevMask 影响不大。从 BEV voxel 的角度来看中心点到 multi camera 的映射是稀疏的在 BevFormer 开源的代码和模型中默认利用了这个特性加速计算而不会带来任何精度损失也就是上面说的 bev_mask从 BEV pillar 的角度来看通常每个 pillar 只会映射到 1-2 个 camera如上图右上角所示。利用到上面的几个特性我们可以减少空间融合模块的复杂度但需要引入一对 gather/scatter 操作以及相关的 index 计算。即先通过 gather 将 bev 空间上的有效点取出来计算完空间特征融合后再用 scatter 将其还原到 Bev 空间对应的位置然后根据每个 bevpillar 的有效点数来算 Bev 空间每个点的均值即可。整体框架如下图所示为了能编译成静态模型有 2 个额外需要关注的设置Bev 空间映射到每个 camera 的最大点数。这个可以根据内外参计算得到但为了应对一些抖动情况可以适当放开在 Nuscenes 数据集上50*50 大小的 Bevsize 下我们设置为 20*32。 这个数字直观理解就是最大视场的相机在 Bev 空间覆盖的区域大小。每个 BEV pillar 映射到的最大的 camera 数。目前是一个静态设置的最大值可以根据数据统计得到在 Nuscenes 数据集中我们设定为 2 这个数字直观理解就是有视野重叠的最大 camera 数。代码均在算法包位置hat/models/task_modules/bevformer/attention.py# 对输入的Bevquery和reference_points取出有效点 def rebatch_attention_inputs( self, query: Tensor, queries_rebatch_grid: Tensor, reference_points_rebatch: Tensor, ) - Tuple[Tensor, Tensor]: Rebatch the attention inputs. bs query.shape[0] ... return queries_rebatch, reference_points_rebatch # 将SpatialCrossAttention模块的输出映射会Bevfeat上并求均值 def restore_outputs( self, restore_bev_grid: Tensor, queries_out: Tensor, counts: Tensor, bs: int, queries_rebatch_grid: Tensor, ): Restore outputs to bev feature. queries_out queries_out.reshape( bs, self.num_cams, self.embed_dims, -1 ) ... return slots3.2.2 使用 Gridsample 高效实现 Gather 和 Scattergather/scatter 这一对操作在 BPU 上不是很友好通过分析这对操作的 index 我们发现可以换成 BPU 更友好的方式即使用 Gridsample 来实现这一对操作。Index 只受 camera 内外参的影响而往往内外参的变化是非常低频的因此我们可以把 index 生成的逻辑放在前处理按需触发计算再把生成好的 index 转换为对应 Gridsample 需要的 grid 作为模型输入给到模型供 Gridsample 算子直接使用代码均在算法包位置hat/models/task_modules/bevformer/view_transformer.py根据 Gather 的 Index 计算 Gridsample 的 Gridbev_mask bev_mask.permute(2, 1, 3, 0, 4).squeeze(-1) max_len self.virtual_bev_h * self.virtual_bev_w queries_rebatch_grid reference_points_cam.new_zeros( [B * self.numcam, self.virtual_bev_h, self.virtual_bev_w, 2] ) ... reference_points_rebatch ( reference_points_cam.flatten(-2) .permute(1, 0, 3, 2) .flatten(0, 1) .reshape(B * self.numcam, D * 2, self.bev_h, self.bev_w) )根据 Scatter 的 Index 计算 Gridsample 的 Grid 和 每个 Bev Pillar 对应的有效点数bev_mask_ori bev_mask.clone() bev_mask bev_mask.permute(1, 0, 2, 3) restore_bev_grid ( reference_points_cam.new_zeros( B, self.max_camoverlap_num * self.bev_h, self.bev_w, 2 ) - 1.5 ) ... restore_bev_grid restore_bev_grid * 2 - 1 bev_pillar_counts bev_mask_ori.sum(-1) 0 bev_pillar_counts bev_pillar_counts.permute(1, 2, 0).sum(-1) bev_pillar_counts torch.clamp(bev_pillar_counts, min1.0)4.总结4.1 优化策略小结引入 BevMask 可以大幅度降低空间融合模块的计算量和 IO根据模型特征使用 BPU 友好的 OP。4.2 总结本文主要介绍了基于 Bevformer 优化的 DenseBev 方案通过减少冗余计算和 IO使用 BPU 友好 OP相比于 v1.0 版本模型这种方案在精度相当的情况下在 征程 6M 平台上推理性能提升 30%。同时这种 DenseBev 的优化经验可以推广到其他相似结构或相似使用场景模型的部署中。