作者:忻怡、周樓、謙言、臨在
導言
目标檢測(object detection)旨在定位并識别出圖像中的目标物體,一直以來都是計算機視覺領域研究的熱點問題,也是自動駕駛、目标追蹤等任務的基礎。近年來,優秀的目标檢測算法不斷湧現,其中單階段的 YOLO 系列以其高效、簡潔的優勢,始終是目标檢測算法領域的一個重要分支。2021 年,曠視提出 YOLOX[1]算法,在速度和精度上建構了新的基線,元件靈活可部署,深受工業界的喜愛。本文基于阿裡雲 PAI-EasyCV 架構複現 YOLOX 算法,探究用以實際提升 YOLOX 精度的實用技巧,并進一步結合阿裡巴巴計算平台 PAI 自研的 PAI-Blade 推理加速架構優化模型性能。經過我們對社群諸多 YOLOX 改進技巧的複現和探索,進一步提升了 YOLOX 的性能,在速度和精度上都比現階段的 40~50mAP 的 SOTA 的 YOLOv6 更勝一籌。同時,PAI-EasyCV 提供高效簡潔的模型部署和端到端推理接口,供社群快速體驗使用 YOLOX-PAI 的功能。
總結一下我們的工作貢獻:
- 我們提供了一套 Apache License 訓練/優化/推理的代碼庫以及鏡像,可以實作目前社群 40+MAP 量級最快(相比 YOLOV6 +0.4mAP/加速 13~20%)的目标檢測模型。
- 我們調研了 YOLOX 相關的改進技術和消融實驗,挑選了其中一些相對有幫助的改進,補齊了 40/0.7ms(YOLOXS)~47.6/1.5ms(YOLOXM) 之間的模型,并以配置的方式提供出來。
- 我們對目标檢測的端到端推理進行靈活封裝及速度優化,在 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 進行優化,
- Backbone : repvgg backbone
- Neck : gsconv / asff
- Head : toods / rtoods
- Loss : siou / giou
在算法改進的基礎上,利用 PAI-Blade 對優化後的模型進行推理優化,開發了如下的 PAI-YOLOX 模型。篩選有效改進與現有主流算法的對比結果如下:
( -ASFF 代表使用了 NeckASFF, -TOODN 代表使用 N 個中間層的 TOODHead 取代原有的 YOLOXHead)
從結果中可以看到,相比目前同水準(1ms 以内)SOTA 的 YOLO6 模型,融合上述改進的 YOLOX-PAI 在同等精度/速度的條件下有一定的速度/精度優勢。
有關測評需要注意以下幾點:
- YOLOV6 release 測試速度不包含 decode 和 nms,是以我們為了公平對比,也進行了相關測速設定的關閉。(上表所示結果計算了 Blade 優化後的對應模型在 bs32 下平均一張圖像模型前向推理所用時間,關于端到端推理的時間(包含圖像前、後處理的總用時)見 PAI-EasyCV Export 一節)
- YOLOV6 release 的精度是在訓練過程中測試的,會出現部分 shape=672 的情況,然而測速是在導出到 image_size=(640, 640) 的完成,實際上社群也有相關同學補充了 YOLOV6 在 640 下的測試精度,是以上表放了兩個測試精度。
- 使用 EasyCV 的 Predictor 接口加載相關模型預測進行從圖檔輸入到結果的預測,由于包含了預處理和 NMS 後處理,相對應的時間會變慢一些,詳細參考端到端優化結果。
下面我們将詳細介紹每一個子產品的改進和消融實驗。
Backbone
RepConv
近期 YOLO6 [2],PP-YOLOE [3]等算法都改進了 CSPNet[4]的骨幹網絡,基于 RepVGG[5]的思想設計了可重參數化的骨幹網絡,讓模型在推理上具有更高效的性能。我們沿用了這一思想,利用 YOLO6 的 EfficientRep 代替 YOLOX 原來的 CSPDarkNet-53 骨幹網絡。得到的實驗結果與 YOLO6 相關模型對比如下(YOLOX-Rep 表示使用了 EfficientRep 作為骨幹網絡的 YOLOX 模型):
RepVGG 結構的網絡設計确實會增大參數量和計算量,但實際推理速度都更有優勢,是以我們選擇 YOLO6 EfficientRep 作為可以配置的 Backbone。
Neck
在更換了骨幹網絡的基礎上,我們對 Neck 部分分别進行了兩方面的探究。
- ASSF[6]:基于對 PAN 輸出特征次元變換後基于 SE-Attention 特征融合的特征增強,大幅提升參數量和精度,部分降低推理速度。
- ASSF-Sim : 我們選取了參數量更低的特征融合實作,用較少的參數量(ASFF:5M -> ASFF-Sim:380K)來保留了 84%的精度精度提升(+0.98map->+0.85map)。然而,這一改進會讓推理速度變慢,未來我們會針對這個 OP 實作對應的 Plugin 完成推理加速。
- GSNeck[7] :基于 DW Conv 對 Neck 資訊融合,降低 Neck 參數量,輕微提升精度,也會會降低推理速度。
ASFF 資訊融合
ASFF,通過進行不同 PAN 不同特征圖之間的資訊互動,利用 attention 機制完成 Neck 部分的資訊融合和增強,具體思想如下圖。
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
針對不同的特征圖,其融合機制如下:
GSConvNeck
采用 DWConv 降低參數量是一種常用技巧,在 YOLOX 中,GSconv 設計了一種新型的輕量級的卷積用來減少模型的參數和計算量。為了解決 Depth-wise Separable Convolution (DSC)在計算時通道資訊分離的弊端,GSConv(如下圖所示)采用 shuffle 的方式将标準卷積(SC)和 DSC 得到的特征圖進行融合,使得 SC 的輸出完全融合到 DSC 中。
此外,GSConv 原文指出,如果在整個網絡都使用 GSconv,則會大大加深網絡的深度,降低模型的推理速度,而僅在通道資訊次元最大,空間資訊次元最小的 Neck 處使用 GSConv 是一種更優的選擇。我們在 YOLOX 中利用 GSConv 優化模型,特别的我們采用了兩種方案分别進行實驗(a: 僅将 Neck 的部分用 GSConv,b: Neck 的所有子產品均使用 GSConv):
所得到的實驗結果如下(僅統計 Neck 部分的 Params, Flops)。可以看到 GSConv 對參數量進行了優化,且提升了模型的性能,降低 3%的推理速度可以換來 0.3mAP 的提升。
Head
TOOD
參考 PPYOLOE,我們同樣考慮利用 TOOD[9]算法中的 Task-aligned predictor 中的注意力機制(T-Head)分别對分類和回歸特征進行增強。如下圖所示,特征先通過解耦頭的 stem 層(1x1)進行通道壓縮,接着由通過堆疊卷積層得到中間的特征層,再分别對分類和回歸分支利用注意力機制進行特征的增強,來解耦兩個任務。
我們對堆疊的中間層個數進行消融實驗,每堆疊可以進一步提升一定的精度,并帶來速度上的一些損失。(下表的 Params 和 Flops 隻統計了檢測頭部分。測速及精度基于的基線方法為以 EfficientRep 為 backbone + ASFF 進行特征增強。)
此外,我們利用 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 上引入 SIoU 訓練模型的确能加快模型的收斂速度,但在最終精度上使用 GIoU[11]性能達到最優。
綜合上述 Backbone/Neck/Head/Loss 方向的改進,我們可以獲得如上的 YOLOX-PAI 模型。進一步,我們采用 PAI-Blade 對已經訓練好的模型進行推理優化,實作高性能的端到端推理。
YOLOX-PAI-推理優化
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 次推理的平均值):
下圖,我們展示了由 PAI-EasyCV 中內建的使用 PAI-Blade/JIT 優化的模型端到端推理速度與 YOLOX 官方原版的 不同模型(s/m/l/x)的推理速度對比:
可以看到 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 未來規劃:
- 基于 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.