地平线静态目标检测 MapTR 参考算法-V1.0

news2024/11/15 8:25:15

简介

高清地图是自动驾驶系统的重要组件,提供精确的驾驶环境信息和道路语义信息。传统离线地图构建方法成本高,维护复杂,使得依赖车载传感器的实时感知建图成为新趋势。早期实时建图方法存在局限性,如处理复杂地图元素的能力不足、缺乏实例级信息等,在实时性和后处理复杂度上存在挑战。

为了解决这些问题,基于 Transformer 的 MapTR 模型被提出,它采用端到端结构,仅使用图像数据就能实现高精度建图,同时保证实时性和鲁棒性。MapTRv2 在此基础上增加了新特性,进一步提升了建图精度和性能。

地平线面向智驾场景推出的 征程6 系列(J6)芯片,在提供强大算力的同时带来了极致的性价比,征程6 芯片对于 Transformer 模型的高效支持助力了 MapTR 系列模型的端侧部署。本文将详细介绍地平线算法工具链在 征程6 芯片部署 MapTR 系列模型所做的优化以及模型端侧的表现。

性能精度指标

模型配置:

模型数据集

图片

性能精度表现:

图片

  1. 预测的地图元素:“divider”,“ped_crossing”,“boundary”;
  2. 默认使用 Lidar 坐标系,和公版保持一致。同时适配 ego 坐标系;
  3. 量化配置 TopK:前 K 个量化敏感的算子。

公版模型介绍

MapTR

在这里插入图片描述

MapTR 模型的默认输入是车载摄像头采集到的 6 张相同分辨率的环视图像,使用 nuScenes 数据集,同时也支持拓展为多模态输入例如雷达点云。模型输出是矢量化的地图元素信息,其中地图元素为人行横道、车道分隔线和道路边界 3 种。模型主体采用 encoder-decoder 的端到端结构:

  • Map Encoder 通过 CNN Backbone+BEV Encoder 负责提取 2D 图像特征并转换到统一的 BEV 视角。MapTR-nano 默认使用 ResNet18 作为 Backbone,MapTR-tiny 默认使用 ResNet50。MapTR 兼容多种 BEV Encoder 实现方式例如 GKT、LSS 和 IPM 等并且表现稳定,鉴于 GKT 的部署高效性以及在消融实验中的精度表现更好,公版 MapTR 使用 GKT 作为默认 BEV Encoder 实现方式。
  • Map Decoder 采用 Hierarchical Query Embedding Scheme,即从 point-level(位置)和 instance-level(轮廓)显式地编码地图元素,point-level queries 被所有 instances 共享并融合进 instance-level queries 从而生成 hierarchical queries,hierarchical queries 经过级联的 decoder layers(默认是 6 层)不断更新。每个 decoder layer 首先使用多头自注意力(MHSA)做 inter-instance 和 intra-instance 的信息交互,接着会使用 Deformable Attention 来与 Map Encoder 输出的 BEV 特征做信息交互。point-level 的信息被所有 instance 共享,所以对于每个 instance 而言,映射到 BEV 空间的多个参考点 reference points 是灵活且动态分布的,这对于提取 long-range context information 预测随机形状的地图元素是有益的。
  • MapTR Head 由分类分支和回归分支构成。分类分支预测 instances 的类别,回归分支预测 points 集合的位置。Head 输出的预测值和真值 GT 之间采用 Hierarchical Bipartite Matching 实现监督学习,分为 Instance-level Matching 和 Point-level Matching,因此损失函数为三个部分的加权和:分类 Classification Loss、点对点位置 Point2point Loss 和连接边方向 Edge Direction Loss。

MapTRv2

在这里插入图片描述

MapTRv2 在 MapTR 的基础上增加了新的特性:

  1. 针对层次化 query,引入解耦自注意力,极大地减少了计算量和显存消耗;对于和输入特征交互的 cross-attention 部分,则引入了 BEV、PV 和 BEV+PV 三种变体;
  2. 引入辅助 one-to-many 集合预测分支,增加了正样本数,加速了训练收敛;
  3. 引入辅助 dense supervision,引入深度估计预测头、PV 和 BEV 视角下的分割头,进一步提升模型精度。由于引入深度信息做监督学习,为了显式地提取深度信息,公版 MapTRv2 选择基于 LSS 的 BEVPoolv2 来作为 BEV 视角转换方式;
  4. 引入新的地图元素车道中心线(centerline);
  5. 增加 3D 地图元素预测能力,并提供 Argoverse2 数据集上的指标。

地平线部署说明

地平线参考算法使用流程请参考附录《TCJ6007-J6 参考算法使用指南》;对应高效模型设计建议请参考附录《TCJ6005-J6 平台算法设计建议》

模型对应的代码路径:

模块代码路径

模块代码路径
Config{oe_path}/samples/ai_toolchain/horizon_model_train_sample/scripts/configs/map/maptrv2_resnet50_bevformer_nuscenes.py
Model Structure/usr/local/lib/python3.10/dist-packages/hat/models/structures/maptr/maptrv2.py: class MapTRv2(nn.Module)
Backbone/usr/local/lib/python3.10/dist-packages/hat/models/backbones/resnet.py: class ResNet50(ResNet)
Neck/usr/local/lib/python3.10/dist-packages/hat/models/necks/fpn.py: class FPN(nn.Module)
View Transformer/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/bevformer/view_transformer.py: class SingleBevFormerViewTransformer(BevFormerViewTransformer)其中包含的BEV Encoder模块:/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/bevformer/encoder.py: class SingleBEVFormerEncoder(BEVFormerEncoder)
BEV Decoder/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/maptr/decoderv2.py: class MapTRPerceptionDecoderv2(nn.Module)其中具体包含的BEV Decoder模块:/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/maptr/decoder.py: class MapTRDecoder(nn.Module)
Criterion/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/maptr/criterion.py: class MapTRCriterion(nn.Module)其中的Assigner模块:/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/maptr/assigner.py: class MapTRAssigner(nn.Module)
Post Process/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/maptr/postprocess.py: class MapTRPostProcess(nn.Module)

性能优化

Neck

Neck 部分采用了地平线内部实现的 FPN,相比公版 FPN 实现,在 征程6 平台上性能更加友好。

View Transformer

地平线参考算法版本将基于 LSS 的视角转换方式替换为 Bevformer 的 View Transformer 部分。

  1. BEV Grid 尺寸:对于 Dense BEV 而言,BEV Grid 的尺寸大小实际地影响模型性能。征程6 平台增强了带宽能力,但仍需注意 BEV 网格过大导致访存压力过大而对性能带来负面影响,建议考虑实际部署情况选择合适的 BEV 网格大小来设计模型。相比公版 MapTRv2 模型使用 200x100 的网格,地平线部署模型使用 100x50 的网格来实现性能和精度的平衡。
  2. BEV 特征编码:
    1. 默认 prev_bev 由 cur_bev 改为全 0;
    2. 取消 can_bus 信息的使用,前一帧 bev 特征 prev_bev 和当前帧 cur_bev 的对齐方式由使用 can_bus 信息正向校准改为使用 GridSample 算子反向采样校准;
    3. 取消了 bev_query 初始化部分和 can_bus 的融合;
    4. 取消了公版的 TemporalSelfAttention,改为 HorizonMSDeformableAttention,提升速度。
公版模型
class MapTRPerceptionTransformer(BaseModule):
    ...
    def attn_bev_encode(...):
        ...
        if prev_bev is not None:
            if prev_bev.shape[1] == bev_h * bev_w:
                prev_bev = prev_bev.permute(1, 0, 2)
            if self.rotate_prev_bev:
                for i in range(bs):
                    # num_prev_bev = prev_bev.size(1)
                    rotation_angle = kwargs['img_metas'][i]['can_bus'][-1]
                    tmp_prev_bev = prev_bev[:, i].reshape(
                        bev_h, bev_w, -1).permute(2, 0, 1)
                    tmp_prev_bev = rotate(tmp_prev_bev, rotation_angle,
                                          center=self.rotate_center)
                    tmp_prev_bev = tmp_prev_bev.permute(1, 2, 0).reshape(
                        bev_h * bev_w, 1, -1)
                    prev_bev[:, i] = tmp_prev_bev[:, 0]

        # add can bus signals
        can_bus = bev_queries.new_tensor(
            [each['can_bus'] for each in kwargs['img_metas']])  # [:, :]
        can_bus = self.can_bus_mlp(can_bus[:, :self.len_can_bus])[None, :, :]
        bev_queries = bev_queries + can_bus * self.use_can_bus
        ...
地平线参考算法
class BevFormerViewTransformer(nn.Module):
    ...
    def 
__init__
(...):
        ...
        self.prev_frame_info = {
            "prev_bev": None,
            "scene_token": None,
            "ego2global": None,
        }
        ...
    def get_prev_bev(...):
        if idx == self.queue_length - 1 and self.queue_length != 1:
            prev_bev = torch.zeros(
                (bs, self.bev_h * self.bev_w, self.embed_dims),
                dtype=torch.float32,
                device=device,
            )
            ...
        else:
            prev_bev = self.prev_frame_info["prev_bev"]
            if prev_bev is None:
                prev_bev = torch.zeros(
                    (bs, self.bev_h * self.bev_w, self.embed_dims),
                    dtype=torch.float32,
                    device=device,
                ) # 对应改动 2.a
                ...
    def bev_encoder(...):
        ...
        tmp_prev_bev = prev_bev.reshape(
            bs, self.bev_h, self.bev_w, self.embed_dims
        ).permute(0, 3, 1, 2)
        prev_bev = F.grid_sample(
            tmp_prev_bev, norm_coords, "bilinear", "zeros", True
        ) # 对应改动 2.b
        ...
class SingleBevFormerViewTransformer(BevFormerViewTransformer):
    ...
    def get_bev_embed(...):
        ...
        bev_query = self.bev_embedding.weight
        bev_query = bev_query.unsqueeze(1).repeat(1, bs, 1) # 对应改动 2.c
        ...
公版模型 Config
model = dict(
    ...
    pts_bbox_head=dict(
        type='MapTRHead',
        ...
        transformer=dict(
            type='MapTRPerceptionTransformer',
            ...
            encoder=dict(
                type='BEVFormerEncoder',
                ...
                transformerlayers=dict(
                    type='BEVFormerLayer',
                    attn_cfgs=[
                        dict(
                            type='TemporalSelfAttention',
                            embed_dims=
_dim_
,
                            num_levels=1),
                            ...
                    ]
                )
            )
        )
    )
)
地平线参考算法 Config
model = dict(
    ...
    view_transformer=dict(
        type="SingleBevFormerViewTransformer",
        ...
        encoder=dict(
            type="SingleBEVFormerEncoder",
            ...
            encoder_layer=dict(
                type="SingleBEVFormerEncoderLayer",
                ...
                selfattention=dict(
                    type="HorizonMSDeformableAttention", # 对应改动 2.d
                    ...
                ),
            )
        )
    )
)

Attention

模型中用到的 attention 操作均使用地平线提供的算子,相比 PyTorch 提供的公版算子,地平线 attention 算子在保持算子逻辑等价的同时在效率上进行了优化

from hat.models.task_modules.bevformer.attention import (
    HorizonMSDeformableAttention,
    HorizonMSDeformableAttention3D,
    HorizonSpatialCrossAttention,
)

精度优化

量化精度

  1. 对模型中量化敏感的 Top30 个算子采用 Int16 精度量化:
Config 文件
if os.path.exists(pts_path):
    pts_table = torch.load(pts_path)
    cali_qconfig_setter = (
        sensitive_op_calibration_8bit_weight_16bit_act_qconfig_setter(
            pts_table,
            topk=30,
            ratio=None,
        ),
        default_calibration_qconfig_setter,
    )
    qat_qconfig_setter = (
        sensitive_op_qat_8bit_weight_16bit_fixed_act_qconfig_setter(
            pts_table,
            topk=30,
            ratio=None,
        ),
        default_qat_fixed_act_qconfig_setter,
    )
  1. QAT 训练采用固定较小的 learning rate 来 fine-tune,这里固定也即取消 LrUpdater Callback 的使用,配置如下:
Config 文件
float_lr = 6e-4
qat_lr = 1e-6
  1. 取消了公版模型 MapTRHead 中对于量化不友好的 inverse_sigmoid 操作;此外部署模型取消了 MapTRHead 中 reg_branches 输出和 reference 相加后再 sigmoid 的操作(该操作可以转移到部署后处理中完成):
公版模型
class MapTRHead(DETRHead):
    ...
    def forward(...):
        ...
        for lvl in range(hs.shape[0]):
            if lvl == 0:
                # import pdb;pdb.set_trace()
                reference = init_reference
            else:
                reference = inter_references[lvl - 1]
            reference = inverse_sigmoid(reference)
            ...
            tmp = self.reg_branches
[lvl](...)
            tmp[..., 0:2] += reference[..., 0:2]
            tmp = tmp.sigmoid() # cx,cy,w,h
            
地平线参考算法
class MapTRPerceptionDecoderv2(nn.Module):
    ...
    def get_outputs(...):
        ...
        for lvl in range(len(outputs_classes)):
            reference = reference_out[lvl].float()
            # reference = inverse_sigmoid(reference)
            ...
            tmp = bbox_outputs[lvl].float()
            tmp[..., 0:2] += reference[..., 0:2]
            tmp = tmp.sigmoid()
    ...

    def forward(...):
        outputs = self.bev_decoder(...)
        if self.is_deploy:
            return outputs
        ...
        outputs = self.get_outputs(...)
        ...
        return self._post_process(data, outputs)

其他优化

设计优化

  1. 在 View Transformer,使用 Bevformer 替换地平线支持不友好的公版 MapTRv2 基于 LSS 的 BEVPoolv2 来作为 PV 视角转 BEV 视角的方式;
  2. 在 View Transformer 的 BEV Encoder 模块取消了 BEV 特征的时序融合,也取消了 Bevformer 时序自注意力模块,模型整体精度不低于公版基于 Bevformer 的精度。

总结与建议

部署建议

  1. 遵循硬件对齐规则,一般的 tensor shape 对齐到 2 的幂次,conv-like 的算子 H 维度对齐到 8、W 维度对齐到 16、C 维度对齐到 32,若设计尺寸不满足对齐规则时会对 tensor 自动进行 padding,造成无效的算力浪费;
  2. 合理选择 BEV Grid 尺寸,征程6 平台的带宽得到增强,但仍需考虑 BEV Grid 尺寸对模型性能的影响,并且综合衡量模型精度预期,选择合适的 BEV Grid 尺寸以获得模型性能和精度的平衡;
  3. 优先选择 征程6 平台高效 Backbone 来搭建模型,高效 Backbone 经过在 征程6 平台的反复优化和验证,相比其他 Backbone 的选择,在性能和精度上可以同时取得出众的效果,因此选取 征程6 平台高效 Backbone 来搭建模型可以对整个场景模型带来性能和精度的增益。

总结

本文通过对 MapTRv2 进行地平线量化部署的优化,使得模型在 征程 6 计算平台上用较低的量化精度损失,获得单核 26.66 FPS 的部署性能。同时,MapTRv2 的部署经验可以推广到其他相似结构或相似使用场景模型的部署中。

对于地平线 MapTR 参考算法模型,Backbone 和 BEV 中融合方式等的优化仍在探索和实践中,Stay Tuned!

附录

  1. 公版论文:MapTR;
  2. 公版模型源码:GitHub-MapTR。

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

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

相关文章

【python】requests 库 源码解读、参数解读

文章目录 一、基础知识二、Requests库详解2.1 requests 库源码简要解读2.2 参数解读2.3 处理响应2.4 错误处理 一、基础知识 以前写过2篇文章: 计算机网络基础: 【socket】从计算机网络基础到socket编程——Windows && Linux C语言 Python实现…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【LMS调测】

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 基本概念 LMS全称为Lite Memory Sanitizer,是一种实时…

新版本大疆上云API指令飞行(drc)模式通讯搭建思路

一、大疆上云API mqtt官方通讯指导 1.1drc链路 1.2mqtt交互时序图 二、自行搭建mqtt说明 2.1工具:用emqx搭建mqtt服务器,mqttx作为客户端测试工具 2.2端口说明:1883,普通mqtt消息端口,8083,ws通信协议端…

商业银行应用安全架构设计实践

传统的信息安全工作通常偏向于事中或事后检测漏洞,随着敏捷开发工作的逐步推进,商业银行认识到安全架构设计在实现IT降本增效方面的独特优势。近几年,商业银行逐步构建了安全架构设计工作体系,在组织人员、安全技术与管控流程方面,与企业IT架构密切协同,着力建设安全公共…

课程表-LeetCode100

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。 例如,想要学习课程 0 ,你需要先完成课程 1…

Python | Leetcode Python题解之第432题全O(1)的数据结构

题目: 题解: class Node:def __init__(self, key"", count0):self.prev Noneself.next Noneself.keys {key}self.count countdef insert(self, node: Node) -> Node: # 在 self 后插入 nodenode.prev selfnode.next self.nextnode.…

【机器学习】——支持向量机

文章目录 支持向量机(Support Vector Machine, SVM)概述SVM 的工作原理线性不可分数据:软间隔与核技巧SVM 的数学形式SVM 的优势SVM 的缺点SVM 的应用 支持向量机(Support Vector Machine, SVM)概述 支持向量机&#…

JavaSE高级(3)——lombok、juint单元测试、断言

一、lombok的使用 默认jvm不解析第三方注解,需要手动开启 链式调用 二、juint单元测试 下载juint包 public class TestDemo {// 在每一个单元测试方法执行之前执行Beforepublic void before() {// 例如可以在before部分创建IO流System.out.println("befor…

荣耀手机AI搜索革新体验:一键总结归纳,让信息获取更高效

在信息爆炸的时代,我们每天都被海量的数据包围,如何快速、准确地获取所需信息成为了现代人的一大挑战。 近日,荣耀手机宣布其AI搜索功能正式上线,这一创新举措不仅为使用者带来了前所未有的便捷体验,更在智能手机领域…

栈:只允许在一端进行插入或删除操作的线性表

一、重要术语: 栈顶、栈底、空栈 二、线性表的基本操作 三、栈的相关操作: 把线性表中的list改成stack insert改成 push delete 改成 pop 总结:“后进先出” 四、顺序栈: 缺点:栈的大小不可变 1.定义: …

生物反馈治疗仪——精神患者治疗方案

生物反馈治疗仪标准型由治疗仪主机、专用软件、电极帽(含脑电放大器、电极线)套装、电源适配器与显示器配套使用,终身免费软件升级。 与显示配套使用,对儿童多动症有辅助治疗作用。建议每周训练2~3次,每次训…

CSS的表格属性

border属性 规定CSS表格边框。 table,td{border: 1px solid green;/*1px表示设置边框的大小,solid表示边框为实线,green表示边框的颜*/} border-collpapse属性 设置表格的边框是否被折叠成一个单一的边框或隔开。 table{border-collapse: collapse;} wi…

2024从传统到智能,AI做PPT软件的崛起之路

随着AI技术的飞速进步,它已悄然渗透至我们的工作与学习之中,不仅助力写作与绘画创作,就连PPT制作这一传统办公领域也迎来了AI的革新。我最近有幸探索了一系列AI驱动的PPT制作工具,亲身体验后深感震撼——合理利用这些ai做ppt工具&…

Windows11系统安装,配置CUDA、cuDNN等

已经有大几年没有安装过 Windows 的系统了,今天因为黑神话悟空,准备把 Win 11 装一台,玩玩游戏,顺便把一些 CUDA 相关的异步解析项目也安装到 Window 上。 下载安装 PE 因为十几年前,只会用 PE 装系统,所…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【Trace调测】

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 基本概念 Trace调测旨在帮助开发者获取内核的运行流程&#xff0c…

java项目之基于springboot框架开发的景区民宿预约系统的设计与实现(源码+文档)

项目简介 基于springboot框架开发的景区民宿预约系统的设计与实现的主要使用者分为: 管理员的功能有:用户信息的查询管理,可以删除用户信息、修改用户信息、新增用户信息,根据公告信息进行新增、修改、查询操作等等。。 &#x1…

英伟达NVIDIA数字IC后端笔试真题(ASIC Physical Design Engineer)

今天小编给大家分享下英伟达NVIDIA近两年数字IC后端笔试真题(ASIC Physical Design) 请使用OR门和INV反相器来搭建下面所示F逻辑表达式的电路图。 数字IC后端设计如何从零基础快速入门?(内附数字IC后端学习视频) 2024届IC秋招兆…

Vue3学习---【API】【从零开始的Vue3学习!!!】

目录 应用实例API app.mount() unmount() 常规API version nextTick() 状态选项API data() 注意: methods() 生命周期选项 beforeCreate()和Created() beforeCreate() created() beforeCreate()和created()的区别 beforeMount()和mounted() beforeM…

统信服务器操作系统【targetcli部署】

targetcli部署方案 文章目录 功能概述功能介绍1.安装targetcli2.targetcli语法及参数说明3.示例1. 配置2.访问功能概述 SCSI 即小型计算机系统接口(Small Computer System Interface;简写:SCSI) iSCSI,internet SCSI 网络磁盘 ,提供一对一的网络存储, 主机A 提供xx存储设…

数据包签名校验的Web安全测试实践

01 测试场景 在金融类的Web安全测试中,经常可以见到Web请求和响应数据包加密和签名保护,由于参数不可见,不能重放请求包,这类应用通常不能直接进行有效的安全测试,爬虫也爬不到数据。 02 解决思路 对于这类应用&am…