天天看點

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

作者:忻怡、周樓、謙言、臨在

導言

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

目标檢測(object detection)旨在定位并識别出圖像中的目标物體,一直以來都是計算機視覺領域研究的熱點問題,也是自動駕駛、目标追蹤等任務的基礎。近年來,優秀的目标檢測算法不斷湧現,其中單階段的 YOLO 系列以其高效、簡潔的優勢,始終是目标檢測算法領域的一個重要分支。2021 年,曠視提出 YOLOX[1]算法,在速度和精度上建構了新的基線,元件靈活可部署,深受工業界的喜愛。本文基于阿裡雲 PAI-EasyCV 架構複現 YOLOX 算法,探究用以實際提升 YOLOX 精度的實用技巧,并進一步結合阿裡巴巴計算平台 PAI 自研的 PAI-Blade 推理加速架構優化模型性能。經過我們對社群諸多 YOLOX 改進技巧的複現和探索,進一步提升了 YOLOX 的性能,在速度和精度上都比現階段的 40~50mAP 的 SOTA 的 YOLOv6 更勝一籌。同時,PAI-EasyCV 提供高效簡潔的模型部署和端到端推理接口,供社群快速體驗使用 YOLOX-PAI 的功能。

總結一下我們的工作貢獻:

  1. 我們提供了一套 Apache License 訓練/優化/推理的代碼庫以及鏡像,可以實作目前社群 40+MAP 量級最快(相比 YOLOV6 +0.4mAP/加速 13~20%)的目标檢測模型。
  2. 我們調研了 YOLOX 相關的改進技術和消融實驗,挑選了其中一些相對有幫助的改進,補齊了 40/0.7ms(YOLOXS)~47.6/1.5ms(YOLOXM) 之間的模型,并以配置的方式提供出來。
  3. 我們對目标檢測的端到端推理進行靈活封裝及速度優化,在 V100 上的端到端推理為 3.9ms,相對原版 YOLOX 的 9.8ms,加速接近 250%,供使用者快速完成目标檢測推理任務。

本文,我們将逐一介紹所探索的相關改進與消融實驗結果,如何基于 PAI-EasyCV 使用 PAI-Blade 優化模型推理過程,及如何使用 PAI-EasyCV 進行模型訓練、驗證、部署和端到端推理。歡迎大家關注和使用 PAI-EasyCV 和 PAI-Blade,進行簡單高效的視覺算法開發及部署任務。

PAI-EasyCV 項目位址:​​https://github.com/alibaba/EasyCV​​

PAI-BladeDISC 項目位址:​​https://github.com/alibaba/BladeDISC​​

YOLOX-PAI-算法改進

YOLOX-PAI 是我們在阿裡雲機器學習平台 PAI 的開源計算機視覺代碼庫 EasyCV(​​https://github.com/alibaba/EasyCV​​​)中內建的 YOLOX 算法。若讀者不了解 YOLOX 算法,可以自行學習(可參考:​​連結​​),本節主要介紹我們基于 YOLOX 算法的改進。

通過對 YOLOX 算法的分析,結合檢測技術的調研,我們從以下 4 個方向對原版的 YOLOX 進行優化,

  1. Backbone : repvgg backbone
  2. Neck : gsconv / asff
  3. Head : toods / rtoods
  4. Loss : siou / giou

在算法改進的基礎上,利用 PAI-Blade 對優化後的模型進行推理優化,開發了如下的 PAI-YOLOX 模型。篩選有效改進與現有主流算法的對比結果如下:

( -ASFF 代表使用了 NeckASFF, -TOODN 代表使用 N 個中間層的 TOODHead 取代原有的 YOLOXHead)

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

從結果中可以看到,相比目前同水準(1ms 以内)SOTA 的 YOLO6 模型,融合上述改進的 YOLOX-PAI 在同等精度/速度的條件下有一定的速度/精度優勢。

有關測評需要注意以下幾點:

  1. YOLOV6 release 測試速度不包含 decode 和 nms,是以我們為了公平對比,也進行了相關測速設定的關閉。(上表所示結果計算了 Blade 優化後的對應模型在 bs32 下平均一張圖像模型前向推理所用時間,關于端到端推理的時間(包含圖像前、後處理的總用時)見 PAI-EasyCV Export 一節)
  2. YOLOV6 release 的精度是在訓練過程中測試的,會出現部分 shape=672 的情況,然而測速是在導出到 image_size=(640, 640) 的完成,實際上社群也有相關同學補充了 YOLOV6 在 640 下的測試精度,是以上表放了兩個測試精度。
  3. 使用 EasyCV 的 Predictor 接口加載相關模型預測進行從圖檔輸入到結果的預測,由于包含了預處理和 NMS 後處理,相對應的時間會變慢一些,詳細參考端到端優化結果。

下面我們将詳細介紹每一個子產品的改進和消融實驗。

Backbone

RepConv

近期 YOLO6 [2],PP-YOLOE [3]等算法都改進了 CSPNet[4]的骨幹網絡,基于 RepVGG[5]的思想設計了可重參數化的骨幹網絡,讓模型在推理上具有更高效的性能。我們沿用了這一思想,利用 YOLO6 的 EfficientRep 代替 YOLOX 原來的 CSPDarkNet-53 骨幹網絡。得到的實驗結果與 YOLO6 相關模型對比如下(YOLOX-Rep 表示使用了 EfficientRep 作為骨幹網絡的 YOLOX 模型):

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

RepVGG 結構的網絡設計确實會增大參數量和計算量,但實際推理速度都更有優勢,是以我們選擇 YOLO6 EfficientRep 作為可以配置的 Backbone。

Neck

在更換了骨幹網絡的基礎上,我們對 Neck 部分分别進行了兩方面的探究。

  1. ASSF[6]:基于對 PAN 輸出特征次元變換後基于 SE-Attention 特征融合的特征增強,大幅提升參數量和精度,部分降低推理速度。
  2. ASSF-Sim : 我們選取了參數量更低的特征融合實作,用較少的參數量(ASFF:5M -> ASFF-Sim:380K)來保留了 84%的精度精度提升(+0.98map->+0.85map)。然而,這一改進會讓推理速度變慢,未來我們會針對這個 OP 實作對應的 Plugin 完成推理加速。
  3. GSNeck[7] :基于 DW Conv 對 Neck 資訊融合,降低 Neck 參數量,輕微提升精度,也會會降低推理速度。

ASFF 資訊融合

ASFF,通過進行不同 PAN 不同特征圖之間的資訊互動,利用 attention 機制完成 Neck 部分的資訊融合和增強,具體思想如下圖。

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

ASFF-SIM 輕量版

參考 YOLO5[8]中的 Fcous 層的設計,PAI-EasyCV 利用切片操作進行特征通道的增加和特征圖的縮小。同時,利用求平均操作進行通道的壓縮,基于這種實作的 ASFF,我們簡單區分為 ASFF-Sim。我們進行特征圖統一的核心操作(通道擴充和通道壓縮)如下:

def expand_channel(self, x):    # [b,c,h,w]->[b,c*4,h/2,w/2]    patch_top_left = x[..., ::2, ::2]    patch_top_right = x[..., ::2, 1::2]    patch_bot_left = x[..., 1::2, ::2]    patch_bot_right = x[..., 1::2, 1::2]    x = torch.cat(        (            patch_top_left,            patch_bot_left,            patch_top_right,            patch_bot_right,        ),        dim=1,    )    return x
def mean_channel(self, x):    # [b,c,h,w]->[b,c/2,h,w]    x1 = x[:, ::2, :, :]    x2 = x[:, 1::2, :, :]    return (x1 + x2) / 2      

針對不同的特征圖,其融合機制如下:

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強
YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

GSConvNeck

采用 DWConv 降低參數量是一種常用技巧,在 YOLOX 中,GSconv 設計了一種新型的輕量級的卷積用來減少模型的參數和計算量。為了解決 Depth-wise Separable Convolution (DSC)在計算時通道資訊分離的弊端,GSConv(如下圖所示)采用 shuffle 的方式将标準卷積(SC)和 DSC 得到的特征圖進行融合,使得 SC 的輸出完全融合到 DSC 中。

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

此外,GSConv 原文指出,如果在整個網絡都使用 GSconv,則會大大加深網絡的深度,降低模型的推理速度,而僅在通道資訊次元最大,空間資訊次元最小的 Neck 處使用 GSConv 是一種更優的選擇。我們在 YOLOX 中利用 GSConv 優化模型,特别的我們采用了兩種方案分别進行實驗(a: 僅将 Neck 的部分用 GSConv,b: Neck 的所有子產品均使用 GSConv):

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強
YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

所得到的實驗結果如下(僅統計 Neck 部分的 Params, Flops)。可以看到 GSConv 對參數量進行了優化,且提升了模型的性能,降低 3%的推理速度可以換來 0.3mAP 的提升。

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

Head

TOOD

參考 PPYOLOE,我們同樣考慮利用 TOOD[9]算法中的 Task-aligned predictor 中的注意力機制(T-Head)分别對分類和回歸特征進行增強。如下圖所示,特征先通過解耦頭的 stem 層(1x1)進行通道壓縮,接着由通過堆疊卷積層得到中間的特征層,再分别對分類和回歸分支利用注意力機制進行特征的增強,來解耦兩個任務。

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

我們對堆疊的中間層個數進行消融實驗,每堆疊可以進一步提升一定的精度,并帶來速度上的一些損失。(下表的 Params 和 Flops 隻統計了檢測頭部分。測速及精度基于的基線方法為以 EfficientRep 為 backbone + ASFF 進行特征增強。)

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

此外,我們利用 RepVGGBlock 分别優化 inter_conv,cls_conv/reg_conv 層。實驗結果表明用 RepVGGBlock 實作 inter_conv 層會帶來性能上的下降,而 RepVGGBlock 實作的 cls_conv/reg_conv 層與原始卷積層在 stack 較大時效果相當,在 stack 比較小時,RepVGGBlock 能起到優化作用。

Loss function

S/G/D/E/CIou

PAI-EasyCV 實作了社群常用的集中 IOU 損失函數,使用者可以通過 config 自行選擇,特别的,對于最新提出的 SIoU[10],在實驗過程中發現原公式中的反三角函數會使得模型訓練不穩定,且計算開銷相對較高,我們對原公式利用三角函數公式化簡可得(符号與論文原文一緻,詳見原論文):

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

實驗結果顯示,在 YOLOX 上引入 SIoU 訓練模型的确能加快模型的收斂速度,但在最終精度上使用 GIoU[11]性能達到最優。

綜合上述 Backbone/Neck/Head/Loss 方向的改進,我們可以獲得如上的 YOLOX-PAI 模型。進一步,我們采用 PAI-Blade 對已經訓練好的模型進行推理優化,實作高性能的端到端推理。

YOLOX-PAI-推理優化

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

PAI-EasyCV Predictor

針對使用 PAI-EasyCV 訓練的 YoloX-PAI 模型,使用者可以使用 EasyCV 自帶的導出(export)功能得到優化後的模型,并使用 EasyCV Predictor 進行端到端的推理。 該導出功能對檢測模型進行了如下優化:

  • 使用 PAI-Blade 優化模型推理速度,簡化對模型的推理加速(TensorRT/編譯優化)開發流程。
  • 支援 EasyCV 配置 TorchScript/PAI-Blade 對圖像前處理、模型推理、圖像後處理分别優化,供使用者靈活使用
  • 支援 Predictor 結構端到端的模型推理優化,簡化圖檔預測過程。

也可以參考​​[EasyCV detector.py]​​​ 自行組織相應的圖像前處理/後處理過程,或直接使用我們導出好的模型和接口):我們這裡提供一個已經導出好的檢測模型,使用者下載下傳三個模型檔案到本地 [​​preprocess​​​, ​​model​​​, ​​meta​​]

export_blade/├── epoch_300_pre_notrt.pt.blade├── epoch_300_pre_notrt.pt.blade.config.json└── epoch_300_pre_notrt.pt.preprocess      

PAI-EasyCV Export

下面我們簡單介紹如何通過 PAI-EasyCV 的配置檔案,導出不同的模型(具體的模型部署流程即相應的配置檔案說明介紹見​​連結​​),并展示導出的不同模型進行端到端圖像推理的性能。

為導出不同的模型,使用者需要對配置檔案進行修改,配置檔案的說明如下:

export = dict(export_type='ori', # 導出的模型類型['ori','jit','blade']               preprocess_jit=False, # 是否用jit對前處理進行加速              static_opt=True, # 是否使用static shape優化,預設True              batch_size=1,  # 靜态圖的輸入batch_size              blade_cnotallow=dict(                  enable_fp16=True,                  fp16_fallback_op_ratio=0.05 # 所有的layer都會針對轉fp16前後的輸出                  # 的偏移進行排序,會對數值變化最大的層回退到fp32,該參數用于控制回退的比例,                  # 如果出現模型輸出漂移太大,影響相關測試結果,可以手動調整該參數。              ),               use_trt_efficientnms=False) # 是否使用trt優化的efficientnms      

根據不同的模型配置,我們在單卡 V100 上測試 YOLOX-s 所有配置下模型的端到端推理性能 (1000 次推理的平均值):

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

下圖,我們展示了由 PAI-EasyCV 中內建的使用 PAI-Blade/JIT 優化的模型端到端推理速度與 YOLOX 官方原版的 不同模型(s/m/l/x)的推理速度對比:

YOLOX-PAI: 加速 YOLOX, 比 YOLOV6 更快更強

可以看到 PAI-EasyCV 導出的模型,極大程度的優化了原模型的端到端推理速度,未來我們将進一步優化 blade 接入 trt_efficientnms 的速度,提升端到端性能。

PAI-Blade 推理優化

PAI-Blade 是由阿裡雲機器學習平台 PAI 開發的模型優化工具,可以針對不同的裝置不同模型進行推理加速優化。PAI-Blade 遵循易用性,魯棒性和高性能為原則,将模型的部署優化進行高度封裝,設計了統一簡單的 API,在完成 Blade 環境安裝後,使用者可以在不了解 ONNX、TensorRT、編譯優化等技術細節的條件下,通過簡單的代碼調用友善的實作對模型的高性能部署。更多 PAI-Blade 相關技術介紹可以參考 ​​[PAI-Blade介紹]​​。

PAI-EasyCV 中對 Blade 進行了支援,使用者可以通過 PAI-EasyCV 的訓練 config 中配置相關 export 參數,進而對訓練得到的模型進行導出。

這裡我們提供一個 PAI-Blade + PAI-EasyCV 社群版 V100 對應的鏡像(cuda11.1/TensorRT8/cudnn8):使用者也可以基于 Blade 每日釋出的鏡像自行搭建推理環境 ​​[PAI-Blade社群鏡像釋出]​​

registry.cn-shanghai.aliyuncs.com/pai-ai-test/eas-service:blade_cu111_easycv      

使用者執行如下導出指令即可

cd ${EASYCV_ROOT}export LD_LIBRARY_PATH=/usr/loca/cuda/lib64/:${LD_LIBRARY_PATH}export CUDA_VISIBLE_DEVICES=0export PYTHONPATH='./'python tools/export.py yolox_pai_trainconfig.py input.pth export.pth      

值得注意的是上文所有的模型的推理速度都限定在 V100 BatchSize=32 靜态 Shape (end2end=False)的 PAI-Blade 優化設定結果。Blade 中已經內建了常見 OP 的優化,針對使用者自定義的 op 可以參考 PAI-EasyCV 中的 easycv/toolkit/blade/trt_plugin_utils.py 自行實作。

YOLOX-PAI-訓練與複現

我們在 PAI-EasyCV 架構中複現了原版的 YOLOX,及改進的 YOLOX-PAI,并利用 PAI-Blade 對模型進行推理加速。為了更好的友善使用者快速體驗基于 PAI-EasyCV 和 PAI-Blade 的 YOLOX,接下來,我們提供利用鏡像對 YOLOX-PAI 進行模型的訓練、測試、及部署工作。更多的關于如何在本地開發環境運作,可以參考該​​連結​​安裝環境。若使用 PAI-DSW 進行實驗則無需安裝相關依賴,在 PAI-DSW docker 中已内置相關環境。

拉取鏡像

sudo docker pull registry.cn-shanghai.aliyuncs.com/pai-ai-test/eas-service:blade_cu111_easycv      

啟動容器

sudo nvidia-docker run -it -v path:path --name easycv_yolox_pai --shm-size=10g --network=host registry.cn-shanghai.aliyuncs.com/pai-ai-test/eas-service:blade_cu111_easycv      

資料代碼準備

# 資料準備參考 https://github.com/alibaba/EasyCV/blob/master/docs/source/prepare_data.mdgit clone https://github.com/alibaba/EasyCV.gitcd EasyCV      

模型訓練

export PYTHONPATH=./ && python -m torch.distributed.launch  --nproc_per_node=8 --master_port=29500 tools/train.py config.py --work_dir workdir --launcher pytorch      

模型測試

python tools/eval.py config.py pretrain_model.pth --eval      

模型導出

python tools/export.py config.py pretrain_model.pth export.pth        

寫在最後

YOLOX-PAI 是 PAI-EasyCV 團隊基于曠視 YOLOX 複現并優化的在 V100BS32 的 1000fps 量級下的 SOTA 檢測模型。整體工作上內建和對比了很多社群已有的工作:通過對 YOLOX 的替換基于 RepVGG 的高性能 Backbone, 在 Neck 中添加基于特征圖融合的 ASFF/GSConv 增強,在檢測頭中加入了任務相關的注意力機制 TOOD 結構。結合 PAI-Blade 編譯優化技術,在 V100Batchsize32 1000FPS 的速度下達到了 SOTA 的精度 mAP=43.9,同等精度下比美團 YOLOV6 加速 13%,并提供了配套一系列算法/訓練/推理優化代碼和環境。

PAI-EasyCV(​​https://github.com/alibaba/EasyCV​​)是阿裡雲機器學習平台深耕一年多的計算機視覺算法架構,已在集團内外多個業務場景取得相關業務落地成果,主要聚焦在自監督學習/VisionTransformer 等前沿視覺領域,并結合 PAI-Blade 等自研技術不斷優化。歡迎大家參與進來一同進步。

YOLOX-PAI 未來規劃:

  1. 基于 CustomOP(ASFFSim, EfficientNMS (fp16))實作的加速推理

[1] Ge Z, Liu S, Wang F, et al. Yolox: Exceeding yolo series in 2021[J]. arXiv preprint arXiv:2107.08430, 2021.

[2] YOLOv6, ​​https://github.com/meituan/YOLOv6​​.

[3] Xu S, Wang X, Lv W, et al. PP-YOLOE: An evolved version of YOLO[J]. arXiv preprint arXiv:2203.16250, 2022.

[4] Wang C Y, Liao H Y M, Wu Y H, et al. CSPNet: A new backbone that can enhance learning capability of CNN[C]//Proceedings of the IEEE/CVF conference on computer vision and pattern recognition workshops. 2020: 390-391.

[5] Ding X, Zhang X, Ma N, et al. Repvgg: Making vgg-style convnets great again[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2021: 13733-13742.

[6] Liu S, Huang D, Wang Y. Learning spatial fusion for single-shot object detection[J]. arXiv preprint arXiv:1911.09516, 2019.

[7] Li H, Li J, Wei H, et al. Slim-neck by GSConv: A better design paradigm of detector architectures for autonomous vehicles[J]. arXiv preprint arXiv:2206.02424, 2022.

[8] YOLOv5, ​​https://github.com/ultralytics/yolov5​​.

[9] Feng C, Zhong Y, Gao Y, et al. Tood: Task-aligned one-stage object detection[C]//2021 IEEE/CVF International Conference on Computer Vision (ICCV). IEEE Computer Society, 2021: 3490-3499.

[10] Gevorgyan Z. SIoU Loss: More Powerful Learning for Bounding Box Regression[J]. arXiv preprint arXiv:2205.12740, 2022.

[11] Rezatofighi H, Tsoi N, Gwak J Y, et al. Generalized intersection over union: A metric and a loss for bounding box regression[C]//Proceedings of the IEEE/CVF conference on computer vision and pattern recognition. 2019: 658-666.

繼續閱讀