0 概述
该示例为参考算法,仅作为在J5上模型部署的设计参考,非量产算法
1 性能精度指标
模型配置:

性能精度表现:

注:Nuscenes 数据集官方介绍:Nuscenes
2 模型介绍
2.1 模型框架

bev_cft 模型结构图
bev_cft 使用多视图的当前帧的6个RGB图像作为输入。输出是目标的3D Box结果。多视角图像首先使用2D主干获取2D特征。然后投影到3D BEV视角。接着对BEV feature 编码获取深层BEV特征。最后,接上任务特定的head,输出检测结果。模型主要包括以下部分:
**Part2—View transformer:**采用CFT方式完成img 2D到bev 3D的转换。
**Part3—Bev transforms:**对bev特征做数据增强,仅发生在训练阶段。
**Part4—3D BEV Encoder:**BEV特征提取层。
**Part5—BEV Decoder:**使用DepthwiseSeparableCenterPointHead进行3D目标检测任务,检测的类别为["car","truck","bus","barrier","bicycle","pedestrian"]。
2.2 源码说明
config文件
注:如果需要复现精度,config中的训练策略最好不要修改。否则可能会有意外的训练情况出现。
img_encoder
来自6个view的image作为输入通过共享的backbone(efficientnet-b3)和neck(BiFPN)输出经过encoder后的feature,feature_shape为(6*B,C,1/128H,1/128W)。encoder即对多个view的img_feature 做特征提取,过程见下图:

view_transformer
view_transformer 采用CFT(camera free transformer)映射的方法,把图像视角的img_features转换到bev_features。bev_shape为[H',W']为[64,64],其转换过程见下图:

cft 框架图
根据框架图,在view_transformer流程中可以分为两部分:
position-Aware Enhancement:对位置编码进行强化,对BEV 2D和content编码,并通过PA网络实现特征增强
view-Aware Attention:对图像融合坐标位置编码,增强特征
position-Aware Enhancement
该部分为BEV 2D坐标的编码,编码为可学习、参数可更新的PositionEmbeddingLearned2D。
该步骤为对高度reference height的编码。根据位置编码query_pos来做高度的预测ref_h ,然后对高度ref_h 做正弦函数编码。计算公式为:

对应代码为:
ref_h_head 为一个输出channel为1的mlp:
step3:结合BEV的content query,细化目标的height

为了细化高度,引入BEV的content来提取目标的高度信息:

BEV的content为预设的query。num_query为bevsize大小。
Content query经过MLP后与Ref_h做mul,然后与query_pos做add。代码:
view-Aware Attention
该层对图像做encoder。融合position经过一个self-attention模块做特征增强。
其中位置编码key_pos 的方式为:
详细实现见PositionEmbeddingLearned。
图像的encoder操作为:
在公版中,为了减少计算量和内存消耗,在Decoder的自注意力计算中做了分组的Attention,在做J5部署时该部分会用到大量的slice,IO操作导致带宽资源紧张,因此,地平线版本未做part attention。
decoder为cross-attention操作,num_layers为2:
bev_head
检测为多task检测,主要分为:
bev_det的head为DepthwiseSeparableCenterPointHead
对应代码:hat/models/task_modules/centerpoint/head.py
在hat/models/task_modules/centerpoint/head.py的TaskHead对不同的task定义conv_layers:
bev_decoder
在检测任务中使用CenterPointDecoder,具体实现流程见下图:

3 浮点模型训练
3.1 Before Start
3.1.1 2.1.1 发布物及环境部署
step2:解压发布包
解压后文件结构如下:
step3:拉取docker环境
3.1.2 数据集准备
3.1.2.1 数据集下载
Full dataset(v1.0)包含多个子数据集,如果不需要进行v1.0-trainval数据集的浮点训练和精度验证,可以只下载v1.0-mini数据集进行小场景的训练和验证。
将下载完成的v1.0-trainval01_blobs.tar~v1.0-trainval10_blobs.tar、v1.0-trainval_meta.tar和can_bus.zip进行解压,解压后的目录如下所示:
3.1.2.2 数据集打包
--src-data-dir为解压后的nuscenes数据集目录;
--target-data-dir为打包后数据集的存储目录;
--version 选项为["v1.0-trainval", "v1.0-test", "v1.0-mini"],如果进行全量训练和验证设置为v1.0-trainval,如果仅想了解模型的训练和验证过程,则可以使用v1.0-mini数据集;v1.0-test数据集仅为测试场景,未提供注释。
全量的nuscenes数据集较大,打包时间较长。每打包完100张会在终端有打印提示,其中train打包约28100张,val打包约6000张。
2.1.2.3 meta文件夹构建
3.1.3 config配置
在进行模型训练和验证之前,需要对configs文件中的部分参数进行配置,一般情况下,我们需要配置以下参数:
device_ids、batch_size_per_gpu:根据实际硬件配置进行device_ids和每个gpu的batchsize的配置;
ckpt_dir:浮点、calib、量化训练的权重路径配置,权重下载链接在config文件夹下的README中;
data_rootdir:2.1.2.2中打包的数据集路径配置;
meta_rootdir :2.1.2.3中创建的meta文件夹的路径配置;
float_trainer下的checkpoint_path:浮点训练时backbone的预训练权重所在路径,可以使用README的# Backbone Pretrained ckpt中ckpt download提供的float-checkpoint-best.pth.tar权重文件。
3.2 浮点模型训练
config文件中的参数配置完成后,使用以下命令训练浮点模型:
float训练后模型ckpt的保存路径为config配置的ckpt_callback中save_dir的值,默认为ckpt_dir。
3.3 浮点模型精度验证
浮点模型训练完成以后,可以使用以下命令验证已经训练好的浮点模型精度:
验证完成后,会在终端打印浮点模型在验证集上检测精度,如下所示:
4 模型量化和编译
4.1 Calibration
模型完成浮点训练后,便可进行 Calibration。calibration在forward过程中通过统计各处的数据分布情况,从而计算出合理的量化参数。 通过运行下面的脚本就可以开启模型的Calibration过程:
4.2 Calibration 模型精度验证
Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:
验证完成后,会在终端输出calib模型在验证集上检测精度,格式见2.3。
4.3 量化模型训练
通过运行下面的脚本就可以开启模型的qat训练:
4.4 量化模型精度验证
Calibration完成以后,可以使用以下命令验证经过calib后模型的精度:
验证完成后,会在终端输出calib模型在验证集上检测精度,格式见2.3。
4.5 量化模型精度验证
指定calibration-checkpoint后,通过运行以下命令进行量化模型的精度验证:
qat模型的精度验证对象为插入伪量化节点后的模型(float32);quantize模型的精度验证对象为定点模型(int8),验证的精度是最终的int8模型的真正精度,这两个精度应该是十分接近的。
4.6 仿真上板精度验证
除了上述模型验证之外,我们还提供和上板完全一致的精度验证方法,可以通过下面的方式完成:
4.7 量化模型编译
opt为优化等级,取值范围为0~3,数字越大优化等级越高,编译时间更长,但部署性能更好。
compile_perf脚本将生成.html文件和.hbm文件(compile文件目录下),.html文件为BPU上的运行性能,.hbm文件为上板实测文件。
运行后,ckpt_dir的compile目录下会产出以下文件:
5 其他工具
5.1 结果可视化
如果你希望可以看到训练出来的模型对于单帧的检测效果,我们的tools文件夹下面同样提供了预测及可视化的脚本,你只需要运行以下脚本即可:
可视化示例:



