BEVFormer-accelerate:基于 EasyCV 加速 BEVFormer

news2025/1/16 8:16:45

导言

BEVFormer是一种纯视觉的自动驾驶感知算法,通过融合环视相机图像的空间和时序特征显式的生成具有强表征能力的BEV特征,并应用于下游3D检测、分割等任务,取得了SOTA的结果。我们在EasyCV开源框架(https://github.com/alibaba/EasyCV)中,对BEVFomer算法进行集成,并从训练速度、算法收敛速度角度对代码进行了一些优化。同时,我们进一步使用推理优化工具PAI-Blade对模型进行优化,相比于原始模型在A100配置下能取得40%的推理速度提升。本文将从以下几个部分进行介绍:1、BEVFormer算法思想 2、训练速度和算法收敛速度优化 3、使用PAI-Blade优化推理速度。

BEVFormer算法思想

如上图所示,BEVFormer由如下三个部分组成:

  1. backbone:用于从6个角度的环视图像中提取多尺度的multi-camera feature
  2. BEV encoder:该模块主要包括Temporal self-Attention 和 Spatial Cross-Attention两个部分。
    1. Spatial Cross-Attention结合多个相机的内外参信息对对应位置的multi-camera feature进行query,从而在统一的BEV视角下将multi-camera feature进行融合。
    2. Temporal self-Attention将History BEV feature和 current BEV feature通过 self-attention module进行融合。
    3. 通过上述两个模块,输出同时包含多视角和时序信息的BEV feature进一步用于下游3D检测和分割任务
  3. Det&Seg Head:用于特定任务的task head

BEVFormer训练优化

训练加速优化

我们从数据读取和减少内存拷贝消耗等角度对训练代码进行优化。

  • 数据读取
    • 使用更高效的图片解码库 turbojpeg
    • BEVFormer在训练过程中,需要时序上的数据作为输入,将串形的读取方式优化为并行读取。
    • 先做resize再做其他预处理,减少了额外像素带来的计算开销
  • 内存拷贝优化
    • 使用pin_memery=True,并修复了mmcv DataContainer pin_memory的bug
    • 将代码中的numpy操作替换为torch.tensor,避免不必要的h2d拷贝
  • other
    • 使用torch.backends.cudnn.benchmark=True(ps:需要保证在输入数据没有动态性的情况下使用,否则反而会增加训练耗时)
    • 修复了torch.cuda.amp混合精度在LayerNorm层失效的bug

我们在A100 80G的机器上,使用fp16对比吞吐量如下:

Settingthroughput(samples/s)
BEVFormer-tiny bs=323.55
EasyCV BEVFormer-tiny bs=329.84(+177%)
BEVFormer-base bs=50.727
EasyCV BEVFormer-base bs=50.8(+10%)

精度收敛优化

我们使用额外的数据增广方式和不同的损失函数来优化模型。同时加入额外的训练策略来进一步提升模型收敛速度及精度。

  • 数据增广方式
    • rand scale(采用不同分辨率的输入进行训练,实验中发现该操作会引入至少20%的额外训练时间,因此在下述实验中,均没有采用)
    • rand_flip(以50%的概率随机翻转图片)
  • 损失函数
    • 使用smooth l1 loss或 balance l1 loss代替l1 loss。(在mini dataset的实验中,这两个损失都可以提升精度,下面的实验中采用balance l1 loss)
  • 训练策略
    • 使用one2many Branch

这个做法来自于H-Deformable-DETR,在DETR系列的检测模型中采用one2one的匹配方式来分配GT Boxes,这种做法虽然让模型在测试的时候,能够避免冗余的NMS后处理操作,但是只有少数的Query会被分配给正样本,导致训练时模型收敛速度相比于one2many的方式会慢很多。因此,在训练过程中加入auxiliary Query,同一个GT Box会匹配多个auxiliary Query,并使用attention mask将one2one branch和one2many branch的信息隔离开。通过这样的方式,能够显著的提升训练过程中的收敛速度,同时在测试过程中只需要保持one2one branch进行预测。(在实验中,使用额外加入1800个auxiliary Query,每个GT box匹配4个query进行训练)

    • CBGS in one2many Branch

我们的实验是在NuScenes数据集上进行的,在该数据集的3D检测任务上有10类标签,但是这10类标签之间的样本极度不均衡,很多算法会采用CBGS操作进行类间样本均衡,但是这个操作会将整个数据集扩大4.5倍,虽然有一定的精度提升,但是也带来了巨大的训练成本。我们考虑在one2many Branch上进行样本均衡操作,即对于实例数量较多的样本使用较少的auxiliary Query进行匹配,而对于长尾的样本使用较多的auxiliary Query进行匹配。通过CBGS in one2many Branch的方式,训练时间和base保持一致的基础上会进一步提升收敛速度,最终的精度也有一定的提升。(实验中匹配框数量变化:[4, 4, 4, 4, 4, 4, 4, 4, 4, 4] -> [2, 3, 7, 7, 9, 6, 7, 6, 2, 5])

我们在单机8卡A100 80G下进行实验,如下表所示:

config settingNDSmAPthroughput(samples/s)
官方 BEVFormer-base52.4441.913.289
EasyCV BEVFormer-base52.6642.133.45
EasyCV BEVFormer-base-one2manybranch53.02(+0.58)42.48(+0.57)3.40
EasyCV BEVFormer-base-cbgs_one2manybranch53.28(+0.84)42.63(+0.72)3.41

模型收敛速度如下图所示:

由上图可以看出,使用上述优化方式可以大幅提升模型收敛速度,仅需要75%的训练时间就可以达到base的最终精度。同时最终的NDS相比于base也有0.8的提升。

详细配置,训练log和模型权重,参考:https://github.com/alibaba/EasyCV/blob/master/docs/source/model_zoo_det3d.md

在阿里云机器学习平台PAI上使用BEVFormer模型

PAI-DSW(Data Science Workshop)是阿里云机器学习平台PAI开发的云上IDE,面向各类开发者,提供了交互式的编程环境。在DSW Gallery中(链接),提供了各种Notebook示例,方便用户轻松上手DSW,搭建各种机器学习应用。我们也在DSW Gallery中上架了BEVFormer进行3D检测的Sample Notebook(见下图),欢迎大家体验!

使用PAI-Blade进行推理加速

PAI-Blade是由阿里云机器学习平台PAI开发的模型优化工具,可以针对不同的设备不同模型进行推理加速优化。PAI-Blade遵循易用性,鲁棒性和高性能为原则,将模型的部署优化进行高度封装,设计了统一简单的API,在完成Blade环境安装后,用户可以在不了解ONNX、TensorRT、编译优化等技术细节的条件下,通过简单的代码调用方便的实现对模型的高性能部署。更多PAI-Blade相关技术介绍可以参考 [PAI-Blade介绍]。

PAI-EasyCV中对Blade进行了支持,用户可以通过PAI-EasyCV的训练config 中配置相关export 参数,从而对训练得到的模型进行导出。

对于BEVFormer模型,我们在A100机器下进行进行推理速度对比,使用PAI-Blade优化后的模型能取得42%的优化加速。

NameBackendMedian(FPS)Mean(FPS)Median(ms)Mean(ms)
easycvTensorRT3.686973.686510.2712260.271259
easycv scriptTensorRT3.81313.798590.2622540.26337
bladeTensorRT5.402485.23383(+42%)0.18510.192212

环境准备

我们提供一个PAI-Blade + PAI-EasyCV 的镜像包供用户可以直接使用,镜像包地址:easycv-blade-torch181-cuda111.tar

用户也可以基于Blade每日发布的镜像自行搭建推理环境 [PAI-Blade社区镜像发布]。

自行搭建环境时需要注意:BEVFomer-base使用resnet101-dcn作为image backbone,DCN算子使用的是mmcv中的自定义算子,为了导出TorchScript,我们对该接口进行了修改。所以mmcv需要源码编译。

  1. clone mmcv源码
$ git clone https://github.com/open-mmlab/mmcv.git
  1. 替换mmcv文件

替换时请注意mmcv的版本,注意接口要匹配。mmcv1.6.0版本已验证。

参考easycv/thirdparty/mmcv/目录下的修改文件。用mmcv/ops/csrc/pytorch/modulated_deform_conv.cpp和mmcv/ops/modulated_deform_conv.py去替换mmcv中的原文件。

  1. 源码编译

mmcv源码编译请参考:https://mmcv.readthedocs.io/en/latest/get_started/build.html

导出Blade模型

导出Blade的模型的配置可以参考文件bevformer_base_r101_dcn_nuscenes.py中的export字段,配置如下:

export = dict(
    type='blade',
    blade_config=dict(
        enable_fp16=True,
        fp16_fallback_op_ratio=0.0,
        customize_op_black_list=[
            'aten::select', 'aten::index', 'aten::slice', 'aten::view',
            'aten::upsample', 'aten::clamp'
        ]
    )
)

导出命令:

$ cd ${EASYCV_ROOT}
$ export PYTHONPATH='./'
$ python tools/export.py configs/detection3d/bevformer/bevformer_base_r101_dcn_nuscenes.py bevformer_base.pth bevformer_export.pth

Blade模型推理

推理脚本:

from easycv.predictors import BEVFormerPredictor

blade_model_path = 'bevformer_export.pth.blade'
config_file = 'configs/detection3d/bevformer/bevformer_base_r101_dcn_nuscenes.py'

predictor = BEVFormerPredictor(
            model_path=blade_model_path,
            config_file=config_file,
            model_type='blade',
      )

inputs_file = 'nuscenes_infos_temporal_val.pkl'  # 以NuScenes val数据集文件为例
input_samples = mmcv.load(inputs_file)['infos']
predict_results = predictor(input_samples)
print(predict_results)

NuScenes数据集准备请参考:NuScenes数据集准备

展望

我们在EasyCV框架中,集成了BEVFormer算法,并从训练加速、精度收敛和推理加速角度对算法进行了一些改进。近期,也涌现了许多新的BEV感知算法,如BEVFormerv2。在BEVFormerv2中通过Perspective Supervision的方式,让算法能够不受限于使用一些在深度估计或3D检测上的预训练backbone,而直接使用近期更有效的大模型BackBone(如ConvNext、DCNv3等),同时采用two-stage的检测方式进一步增强模型能力,在Nuscenes数据集的camera-based 3D检测任务取得sota的结果。

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/93912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

照片调色JixiPix Hand Tint Pro

JixiPix Hand Tint Pro带有专业分层系统的简单工作流程具有色调,色调,颜色,乘法,柔和涂料或可以逐层更改的涂料的模式,以及功能强大的选色工具,可在隔离区域内保持刷涂,以实现快速着色和准确性。…

Linux环境下多线程C/C++程序的内存问题诊断

目录说明常见的内存错误举例常见的内存访问错误有以下几种:内存问题定位步骤野指针内存释放后使用(UaF,Use after Free)内存问题检查工具常见的内存问题检查工具Valgrindgcc 命令行参数 -fsanitizeaddress -fno-omit-frame-pointe…

Prim算法

应用场景 1.如何修路才能保证修路的总路程最短? 特点: 1.将所有节点全部连通,并且边上的权总和最小——>最小生成树 2.N个顶点,有N-1条边 Prim算法图解分析 简而言之,就是先确定顶点A,然后寻找没有遍…

代码随想录训练营第52天|LeetCode 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

参考 代码随想录 题目一:LeetCode 300.最长递增子序列 确定dp数组下标及其含义 dp[i]:在nums数组中,在下标0~i元素(包含i)的基础上,以nums[i]作为子序列的最后一个元素,组成的最长严格递增子序…

0126 搜索与回溯算法 Day15

剑指 Offer 34. 二叉树中和为某一值的路径 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [5,4,8,11,null,13,…

cuda学习笔记4——cuda 核函数

cuda学习笔记4——cuda 核函数一、CUDA规范二、核函数内部线程的使用2.1 如何启动核函数demo 1:起16个线程来计算,四个线程块,每个块内四个线程例子demo2核函数是指在GPU端运行的代码,核函数内部主要干了什么?简而言之…

一个《跳动的爱心》代码,纯HTML+JS,双击直接运行

HTMLJS实现的一个跳动的爱心。集合了web动画库GSAP JS、OBJ 文件加载器OBJLoader、WebGL第三方库Three.js等。效果非常棒! 目录实际效果:目录结构:HTML代码CSS代码js代码:简单的修改完整文件下载实际效果: 由于是纯前端…

学会IDEA这些断点操作,生产问题解决的越来越快了

文章目录IDEA断点高级用法1、断点类型1)行断点(line breakpoints)2)字段断点(field breakpoints)3)方法断点(method breakpoints)1> 加载类名上的断点2> 正常方法断…

xss-labs(WriteUp)

xss-labs 先讲讲什么是跨站脚本攻击XSS(Cross Site Scripting) XSS原理 本质上是针对html的一种注入攻击,没有遵循数据与代码分离的原则,把用户输入的数据当作代码来执行 xss跨站脚本攻击是指恶意攻击者往Web页面里插入恶意脚本代码(包括当…

redis之codis和redis cluster对比

写在前面 codis和Redis cluster 都是Redis的集群方案,本文就一起来看下。 1:codis的组件和架构 codis的组件有4个,如下: codis server:基于redis进行了二次开发的组件,负责数据的读写 codis proxy&…

Halcon图像拼接

图像拼接在实际的应用场景很广,比如无人机航拍,遥感图像等等,图像拼接是进一步做图像理解基础步骤,拼接效果的好坏直接影响接下来的工作,所以一个好的图像拼接算法非常重要。 如按下图是将两张楼房图片拼接成一个图像。…

QT 学习笔记(九)

文章目录一、事件的接收和忽略1. 准备工作2. 接收和忽略二、event() 函数1. 简介2. 实例演示3. 总结三、事件过滤器四、总结(细看)1. 知识点汇总2. QT 的事件处理五、事件、事件的接收和忽略、event() 函数和事件过滤器代码1. 主窗口头文件 mywidget.h2.…

英语文本转语音软件哪个好?分享三个新手也能学会的工具

大家平时都是怎么学习英语的呢?课上老师让我们熟悉单词意思、巩固语法、多练阅读理解;其实通过练习听力来加强语感也很重要。很多小伙伴的阅读理解很好,但是听力却跟不上。这里教大家一个小技巧,就是在做阅读理解的时候&#xff0…

第十章TomCat详解

文章目录Tomcat的部署和启动Tomcat扮演的角色①对外:Web服务器②对内:Servlet容器深入理解为什么需要TomCat从目的开始出发遇到的问题总过程部署前提解压TomCat的目录文件启动Tomcat并访问首页如何部署一个项目访问对应的web资源专业版IDEA创建一个JavaW…

力扣(718.1143)补9.12

718.最长重复子数组 这题真的想不到。 看图的话会好懂很多。 class Solution { public int findLength(int[] nums1, int[] nums2) { int nnums1.length; int n2nums2.length; int[][] dpnew int[n1][n21]; int result0; for(int…

【区块链-智能合约工程师】第二篇:Solidity入门

文章目录Solidity极简入门HelloWorld数值类型三种函数类型函数输出变量作用域引用类型参考文章:一文速览2022十大智能合约开发工具 资料地址:WTF学院 Solidity极简入门 HelloWorld remix:在线智能合约开发IDE(Integrated Deve…

DBCO-PEG-Aminooxy, Aminooxy-PEG-DBCO,氨甲基聚乙二醇环辛炔

DBCO-PEG-Aminooxy , Aminooxy-PEG-DBCO,二苯并环辛炔-聚乙二醇-氨甲基,氨甲基聚乙二醇环辛炔 Product specifications: 1.CAS No:N/A 2.Molecular weightMV:1000,2000,34000&#x…

小侃设计模式(十八)-发布订阅模式

1.概述 发布订阅模式又叫观察者模式(Observer Pattern),它是指对象之间一对多的依赖关系,每当那个特定对象改变状态时,所有依赖于它的对象都会得到通知并被自动更新,它是行为型模式的一种。观察者模式内部…

被吹爆的JVM笔记,一招教会什么是JVM调优,资深架构师强推!

面试经常被问 JVM 如何调优?这个问题该怎么回答?没有实际调优经验怎么办? 一般面试时问JVM调优,主要是因为,这个技术并不是懂了Java就能自然懂的,需要明白一些底层原理,有一些深度。所以比较适合…

传奇客户端文件介绍注解教程,GM必备知识

传奇客户端文件介绍注解教程,GM必备知识 很多朋友架设微端,或者说修改传奇版本素材方面的内容的时候对于客户端很懵逼! 尤其是新手朋友他并不知道传奇客户端里面哪个文件是对应什么内容的! 今天我们将这些发出来分享给支持奇速的朋…