一本精品热在线视频,久久免费视频分类,精品婷婷乱码久久久久久蜜桃,在线可以免费观看的Av

<mark id="vd61v"><dl id="vd61v"></dl></mark>
    <sub id="vd61v"><ol id="vd61v"></ol></sub>

  • <sub id="vd61v"><ol id="vd61v"></ol></sub>
    "); //-->

    博客專欄

    EEPW首頁 > 博客 > 地平線靜態(tài)目標(biāo)檢測(cè) MapTR 參考算法 - V2.0

    地平線靜態(tài)目標(biāo)檢測(cè) MapTR 參考算法 - V2.0

    發(fā)布人:地平線開發(fā)者 時(shí)間:2025-06-28 來源:工程師 發(fā)布文章

    該示例為參考算法,僅作為在征程 6 上模型部署的設(shè)計(jì)參考,非量產(chǎn)算法

    一、簡(jiǎn)介

    高清地圖是自動(dòng)駕駛系統(tǒng)的重要組件,提供精確的駕駛環(huán)境信息和道路語義信息。傳統(tǒng)離線地圖構(gòu)建方法成本高,維護(hù)復(fù)雜,使得依賴車載傳感器的實(shí)時(shí)感知建圖成為新趨勢(shì)。早期實(shí)時(shí)建圖方法存在局限性,如處理復(fù)雜地圖元素的能力不足、缺乏實(shí)例級(jí)信息等,在實(shí)時(shí)性和后處理

    復(fù)雜度上存在挑戰(zhàn)。

    為了解決這些問題,基于 Transformer 的 MapTR 模型被提出,它采用端到端結(jié)構(gòu),僅使用圖像數(shù)據(jù)就能實(shí)現(xiàn)高精度建圖,同時(shí)保證實(shí)時(shí)性和魯棒性。MapTRv2 在此基礎(chǔ)上增加了新特性,進(jìn)一步提升了建圖精度和性能。

    地平線面向智駕場(chǎng)景推出的征程 6 系列(征程 6)芯片,在提供強(qiáng)大算力的同時(shí)帶來了極致的性價(jià)比,征程 6 芯片對(duì)于 Transformer 模型的高效支持助力了 MapTR 系列模型的端側(cè)部署。本文將詳細(xì)介紹地平線算法工具鏈在征程 6 芯片部署 MapTR 系列模型所做的優(yōu)化以及模型端側(cè)的表現(xiàn)。

    二、性能精度指標(biāo)

    模型配置:

    image.png

    性能精度表現(xiàn):

    image.png


      三、公版模型介紹

      3.1 MapTR

      image.png

      MapTR 模型的默認(rèn)輸入是車載攝像頭采集到的 6 張相同分辨率的環(huán)視圖像,使用 nuScenes 數(shù)據(jù)集,同時(shí)也支持拓展為多模態(tài)輸入例如雷達(dá)點(diǎn)云。模型輸出是矢量化的地圖元素信息,其中地圖元素為人行橫道、車道分隔線和道路邊界 3 種。模型主體采用 encoder-decoder 的端到端結(jié)構(gòu):


        3.2 MapTRv2

        image.png

        MapTRv2 在 MapTR 的基礎(chǔ)上增加了新的特性:


          四、地平線部署說明

          地平線參考算法使用流程請(qǐng)參考征程 6 參考算法使用指南;對(duì)應(yīng)高效模型設(shè)計(jì)建議請(qǐng)參考《征程 6 平臺(tái)算法設(shè)計(jì)建議》

          MapTROE 模型引入了 SD map 的前融合結(jié)構(gòu),與圖像視角轉(zhuǎn)換后的 bev feature 進(jìn)行融合,再通過優(yōu)化后的 MapTR head 生成矢量化的地圖元素。整體結(jié)構(gòu)如下:

          image.png

          因此 maptroe_henet_tinym_bevformer_nuscenes 模型相比之前版本新增了如下優(yōu)化點(diǎn):

            maptroe_henet_tinym_bevformer_nuscenes 模型對(duì)應(yīng)的代碼路徑:

            image.png

            4.1 性能優(yōu)化

            4.1.1 Backbone

            MapTROE 采用基于征程 6 芯片的高效輕量化 Backbone HENet_TinyM(Hybrid Efficient Network, Tiny for J6M),HENet 能更好地利用征程 6 系列芯片的算力,在模型精度和性能上更具優(yōu)勢(shì)。HENet_TinyM 采用了純 CNN 架構(gòu),總體分為四個(gè) stage,每個(gè) stage 會(huì)進(jìn)行一次 2 倍下采樣,具體結(jié)構(gòu)配置如下:

            # henet-tinym
            depth = [4, 3, 8, 6]
            block_cls = ["GroupDWCB", "GroupDWCB", "AltDWCB", "DWCB"]
            width = [64, 128, 192, 384]
            attention_block_num = [0, 0, 0, 0]
            mlp_ratios, mlp_ratio_attn = [2, 2, 2, 3], 2
            act_layer = ["nn.GELU", "nn.GELU", "nn.GELU", "nn.GELU"]
            use_layer_scale = [True, True, True, True]
            extra_act = [False, False, False, False]
            final_expand_channel, feature_mix_channel = 0, 1024
            down_cls = ["S2DDown", "S2DDown", "S2DDown", "None"]
            patch_embed = "origin"

            4.1.2 Neck

            Neck 部分采用了地平線內(nèi)部實(shí)現(xiàn)的 FPN,相比公版 FPN 實(shí)現(xiàn),在征程 6 平臺(tái)上性能更加友好。

            4.1.3 View Transformer

            地平線參考算法版本將基于 LSS 的視角轉(zhuǎn)換方式替換為深度優(yōu)化后 Bevformer 的 View Transformer 部分。

              # 公版模型
              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,
                              ) # 對(duì)應(yīng)改動(dòng)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
                      ) # 對(duì)應(yīng)改動(dòng)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) # 對(duì)應(yīng)改動(dòng)2.c
                      ...

              d. 取消了公版的 TemporalSelfAttention,改為 HorizonMSDeformableAttention,保持精度的同時(shí)提升速度;

              # 公版模型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", # 對(duì)應(yīng)改動(dòng)2.d
                                  ...
                              ),
                          )
                      )
                  )
              )

              e. 支持公版 Bevformer 中的 bev_mask,并將涉及到的 gather/scatter 操作,用 gridsample 等價(jià)替換,提高模型速度。

              # 地平線參考算法Config
              view_transformer=dict(
                  type="SingleBevFormerViewTransformer",
                  ...
                  max_camoverlap_num=2, # 對(duì)應(yīng)根據(jù)bev_mask進(jìn)行稀疏映射,提高運(yùn)行效率,對(duì)應(yīng)改動(dòng)2.e
                  virtual_bev_h=int(0.4 * bev_h_),
                  virtual_bev_w=bev_w_,
                  ...
              )

              4.1.4 Head

              公版 MapTR 使用分層 query 機(jī)制,定義一組 instance queries 和由所有 instance 共享的 point queries,每個(gè)地圖元素對(duì)應(yīng)一組分層 query(一個(gè) instance query 和共享的 point queries 廣播相加得到),在 decoder layer 中分別使用 self-attention 和 cross-attention 來更新分層 query。

              MapTROE 的改進(jìn)則是為每個(gè)地圖元素分配一個(gè) instance query(無直接 point query),每個(gè) query 用于編碼語義信息和地理位置信息,decoder 階段和公版 MapTR 一樣,分別進(jìn)行 multi-head self-attention 和 deformable cross-attention,最后每個(gè) instance query 通過 MLP 網(wǎng)絡(luò)生成類別信息和元素內(nèi)的點(diǎn)集坐標(biāo),相比公版預(yù)測(cè)分層 query,改進(jìn)后直接預(yù)測(cè) instance query 帶來的計(jì)算量更少,極大地提高了模型在端側(cè)的運(yùn)行性能。同時(shí)借鑒 StreamMapNet,使用多點(diǎn)注意力方法來適應(yīng)高度不規(guī)則的地圖元素,擴(kuò)大感知范圍。代碼見/usr/local/lib/python3.10/dist-packages/hat/models/task_modules/maptr/instance_decoder.py: class MapInstanceDetectorHead(nn.Module)

              4.1.5 多點(diǎn)注意力

              image.png 傳統(tǒng)的可變形注意力為每個(gè) query 分配一個(gè)參考點(diǎn),多點(diǎn)注意力則使用前一層預(yù)測(cè)的地圖元素的多個(gè)點(diǎn)作為當(dāng)前層 query 的參考點(diǎn),具體計(jì)算方式是在點(diǎn)維度上擴(kuò)展了一層求和,將一個(gè)點(diǎn)變成多個(gè)點(diǎn),分別計(jì)算 deformable attention。回歸的時(shí)候并非預(yù)測(cè) offsets,而是直接預(yù)測(cè)地圖元素點(diǎn)的坐標(biāo)位置。

              4.1.6Attention

              模型中用到的 attention 操作均使用地平線提供的算子,相比 PyTorch 提供的公版算子,地平線 attention 算子在保持算子邏輯等價(jià)的同時(shí)在效率上進(jìn)行了優(yōu)化

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

              4.2 精度優(yōu)化

              4.2.1 浮點(diǎn)精度

              MapTROE 模型引入 SD Map 前融合,與圖像轉(zhuǎn)換后的 bev feature 進(jìn)行融合,以提高在線地圖的生成質(zhì)量。模塊結(jié)構(gòu)如下圖所示:

              image.png

              4.2.1.1 SD Map 特征提取

              SD Map 從 OpenStreetMap(OSM)中獲取,通過由 GPS 提供的車輛位姿,查詢車輛當(dāng)前位姿附近的 SD Map,然后將 SD Map 轉(zhuǎn)換到自車坐標(biāo)系下,與 NuScenes 中的數(shù)據(jù)標(biāo)注坐標(biāo)系保持一致。SD Map 會(huì)從車道中心骨架線 Polyline 的形式轉(zhuǎn)化為柵格結(jié)構(gòu),大小和 BEV 特征相同,經(jīng)過 CNN 變成特征圖,對(duì)應(yīng) SD Map 的先驗(yàn)信息。

              4.2.1.2 SD Map 特征融合

              柵格化后的 SD Map 和實(shí)際場(chǎng)景可能會(huì)出現(xiàn)錯(cuò)位、不對(duì)齊的情況,這種錯(cuò)位導(dǎo)致直接 Concatenate BEV 特征和 SD Map 特征的效果并不好,為了解決這個(gè)問題,引入了特征融合模塊,通過網(wǎng)絡(luò)學(xué)習(xí)來決定最適合的對(duì)齊方式,可以有效地利用 SD Map 先驗(yàn)提升 BEV 特征的效果。關(guān)于特征融合模塊,分別實(shí)驗(yàn)了交叉注意力與 CNN 網(wǎng)絡(luò),通過精度與性能的平衡,最后選擇了 CNN 網(wǎng)絡(luò)模塊。

              4.3 量化精度

                # Config文件
                cali_qconfig_setter = (default_calibration_qconfig_setter,)
                qat_qconfig_setter = (default_qat_fixed_act_qconfig_setter,)

                2.浮點(diǎn)階段采用更大的 weight decay 訓(xùn)練,使浮點(diǎn)數(shù)據(jù)分布范圍更小,浮點(diǎn)模型參數(shù)更有利于量化

                # Config文件
                float_trainer = dict(
                    ...
                    optimizer=dict(
                        ...
                        weight_decay=0.1, # 相比maptrv2_resnet50_bevformer_nuscenes增大了10倍
                    ),
                    ...
                )

                3.QAT 訓(xùn)練采用固定較小的 learning rate 來 fine-tune,這里固定也即取消 LrUpdater Callback 的使用,配置如下:

                # Config文件
                qat_lr = 1e-9

                4.取消了公版模型 MapTRHead 中對(duì)于量化不友好的 inverse_sigmoid 操作;此外 MapTROE 對(duì) Head 的優(yōu)化無需再引入 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 MapInstanceDetectorHead(nn.Module):
                    ...
                    def get_outputs(...):
                        ...
                        for lvl in range(len(outputs_classes)):
                            tmp = reference_out[lvl].float()
                
                            outputs_coord, outputs_pts_coord = self.transform_box(tmp)
                            outputs_class = outputs_classes[lvl].float()
                
                            outputs_classes_one2one.append(
                                outputs_class[:, 0 : self.num_vec_one2one]
                            )
                            outputs_coords_one2one.append(
                                outputs_coord[:, 0 : self.num_vec_one2one]
                            )
                            outputs_pts_coords_one2one.append(
                                outputs_pts_coord[:, 0 : self.num_vec_one2one]
                            )
                
                            outputs_classes_one2many.append(
                                outputs_class[:, self.num_vec_one2one :]
                            )
                            outputs_coords_one2many.append(
                                outputs_coord[:, self.num_vec_one2one :]
                            )
                            outputs_pts_coords_one2many.append(
                                outputs_pts_coord[:, self.num_vec_one2one :]
                            )
                    ...        
                    def forward(...):
                        outputs = self.bev_decoder(...)
                        if self.is_deploy:
                            return outputs
                        ...
                        outputs = self.get_outputs(...)
                        ...
                        return self._post_process(data, outputs)

                5.Attention 結(jié)構(gòu)優(yōu)化,通過數(shù)值融合方法,將部分?jǐn)?shù)值運(yùn)算提前進(jìn)行融合,減少整體的量化操作,提高模型的量化友好度

                4.4 其他優(yōu)化

                4.4.1 設(shè)計(jì)優(yōu)化

                  五、總結(jié)與建議

                  5.1 部署建議

                    5.2 總結(jié)

                    本文通過對(duì) MapTR 進(jìn)行地平線量化部署的優(yōu)化,使得模型在征程 6 計(jì)算平臺(tái)上用較低的量化精度損失,最優(yōu)獲得征程 6M 單核 93.77 FPS 的部署性能。同時(shí),MapTR 系列的部署經(jīng)驗(yàn)可以推廣到其他相似結(jié)構(gòu)或相似使用場(chǎng)景模型的部署中。

                    對(duì)于地平線 MapTR 參考算法模型,結(jié)合 Sparse Bev 等的優(yōu)化方向仍在探索和實(shí)踐中,Stay Tuned!

                    六、附錄


                      *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



                      相關(guān)推薦

                      技術(shù)專區(qū)

                      關(guān)閉