)
如果把“atlas 300v 24g 是運算加速卡嗎”這個問題扔到任何一個AI技術群里十有八九會吵起來。有人說是推理卡有人說是加速卡還有人直接把它當顯卡用結果發(fā)現(xiàn)連個顯示器接口都沒有。我剛拿到這塊卡的時候也是一臉懵翻了半天文檔才搞清楚它真正的定位。這篇東西我不講官方PPT上的套話就從一個實際部署過YOLO的人的角度把atlas 300v 24g 是什么、能不能跑YOLO、怎么跑、以及過程中踩過的坑都攤開聊一遍。1. Atlas 300V 24G到底是什么卡1.1 一張卡三種身份先說結論Atlas 300V 24G是華為昇騰旗下的AI推理加速卡官方定位是“面向推理場景的PCIe加速卡”。它不是一個通用計算卡更不是傳統(tǒng)意義上的顯卡。很多人第一次接觸這個卡是被“300V”和“24G”這兩個數(shù)字吸引的以為24G顯存能直接當大顯存顯卡用這是個常見的誤區(qū)。這個卡的真實身份有三個層次。第一層它是一塊PCIe接口的擴展卡插在服務器的標準PCIe插槽上就能工作不需要專門的整機這點和訓練用的Atlas 800訓練服務器那種整機形態(tài)有本質區(qū)別。第二層它是一塊異構計算卡板載昇騰AI處理器也就是大家常說的Ascend芯片專門用來跑神經(jīng)網(wǎng)絡推理。第三層它是一塊“半高半長”的工業(yè)級板卡功耗和散熱設計都按服務器機箱的工況來不是給個人PC用的。很多人把它劃分到“運算加速卡”這個類別里邏輯上沒問題但不夠準確。準確的叫法是“AI推理加速卡”它的核心能力集中在深度神經(jīng)網(wǎng)絡的推理階段而不是訓練階段。這個區(qū)別直接決定了它的硬件設計思路顯存不小、帶寬很高、INT8算力很強但FP32通用算力并不突出也沒有視頻輸出接口不能當游戲顯卡用。1.2 規(guī)格參數(shù)怎么看我建議拿到任何一塊加速卡第一步都是去看官方的規(guī)格表而不是聽別人怎么說。Atlas 300V 24G的關鍵參數(shù)大概是這樣參數(shù)項典型規(guī)格說明形態(tài)PCIe 3.0 x16半高半長無外接供電顯存24GB HBM2E帶寬很高比同容量GDDR方案強不少INT8算力百TOPS級別只看推理任務INT8是關鍵指標功耗70W左右不需要外接供電PCIe插槽供電即可接口無顯示輸出純計算卡不帶視頻接口架構昇騰AI處理器內(nèi)置AI Core 向量計算單元這里我要專門說下顯存。24GB的HBM2E顯存在推理卡里屬于比較大的配置這意味著它可以載入?yún)?shù)量比較大的模型或者在單卡上同時跑多個模型實例這對工業(yè)場景非常實用。比如用YOLOv5m做多路視頻流檢測24GB顯存能支撐幾十路并發(fā)推理而不會出現(xiàn)OOM。還有一個容易被忽略的參數(shù)是功耗。300V 24G的設計功耗控制在75W以內(nèi)不需要外接6pin或8pin供電對服務器部署來說非常友好。對比一下動輒兩三百瓦的GPU推理卡同樣做YOLO推理Atlas的單卡功耗低了一個量級這意味著同樣的機房電力預算下能部署更多的卡綜合吞吐量反而更高。1.3 為什么會有“是不是運算加速卡”的疑問我仔細看了下這個熱搜詞的語境提問者大概率是在選型階段看到“300V 24G”這種命名方式和NVIDIA的A100、V100、T4這類GPU型號放一起對比自然會產(chǎn)生疑惑?!癡”在GPU命名里經(jīng)常代表計算卡比如Tesla V100所以“300V”聽起來就像某個計算卡型號。再加上“24G”這種顯存標注方式也完全是GPU的叫法所以很多人第一反應是“這是個GPU吧”。實際上昇騰的命名體系和NVIDIA完全不是一回事。Atlas 300V的“300”是系列號指的是面向推理場景的300系列“V”代表是PCIe形態(tài)的推理卡24G則是板載顯存。它和NVIDIA的定位對比大概是這樣的NVIDIA T428GB顯存版推理卡功耗70W和Atlas 300V 24G的定位高度重合。NVIDIA A1024GB顯存功耗150W性能和功耗都比300V高一個臺階。NVIDIA GTX/RTX游戲卡完全不適用因為沒有驅動支持和數(shù)據(jù)中心特性??吹竭@個對比你應該能理解為什么“是不是運算加速卡”這個問題會讓人困惑了。它的外形像計算卡、功耗像計算卡、接口像計算卡但它其實是專用在AI推理上的加速卡不是通用計算卡。理解這一點后續(xù)做部署選型就不會走彎路。2. 用Atlas跑YOLO思路先理清2.1 YOLO模型到底在算什么YOLO全稱是You Only Look Once是一種單階段目標檢測算法。它的核心思想是把目標檢測當做一個回歸問題來處理輸入一張圖片直接輸出所有目標的邊界框和類別概率。相比兩階段的Faster R-CNNYOLO沒有顯式的“候選區(qū)域提取”階段所以檢測速度快很多特別適合視頻流、實時監(jiān)控這類推理場景。但YOLO也不是一個簡單的模型。以YOLOv5為例它包含了Backbone主干網(wǎng)絡、Neck特征融合和Head檢測頭三大部分。Backbone負責提取圖像特征Neck負責融合不同尺度的特征Head負責在每個特征圖上預測目標框和類別。整個模型推理一次涉及大量的卷積、BatchNorm、激活函數(shù)、上采樣操作如果沒有專門的硬件加速在CPU上跑一個YOLOv5m模型一張1080P圖片可能要幾百毫秒甚至更久。推理加速卡干的事情就是把這些重復計算的卷積和矩陣運算用專門的硬件單元來執(zhí)行。GPU用CUDA核心做這件事昇騰卡用AI Core做這件事。原理都是并行計算但實現(xiàn)方式有差異這也是為什么你不能把GPU的模型文件直接搬到Atlas上跑。2.2 Atlas加速的底層邏輯昇騰AI處理器的核心是AI Core一個AI Core內(nèi)部包含了多個計算單元比如Cube單元負責矩陣計算、Vector單元負責向量運算、Scalar單元負責標量運算。當你在Atlas上跑YOLO的時候整個模型會被編譯成一系列算子任務分發(fā)到AI Core上執(zhí)行。我拿矩陣運算打個比方。一個卷積層本質上就是輸入特征圖和卷積核之間的矩陣乘加運算。Cube單元對這類運算做了深度定制能在單個時鐘周期內(nèi)完成大規(guī)模的矩陣乘法。相比之下通用CPU的指令集沒有針對矩陣乘法做專門優(yōu)化所以效率差距很大。據(jù)統(tǒng)計在相同功耗下專用推理卡做INT8推理的吞吐量一般能比通用GPU高出一定比例主要就是因為專門優(yōu)化了算子。Atlas上跑YOLO模型里的卷積層、池化層會被映射到Cube和Vector單元激活函數(shù)、上采樣等操作也有對應的算子庫支持。昇騰提供了一整套算子庫CANN把底層的硬件細節(jié)封裝成了統(tǒng)一的API開發(fā)者不需要直接操作硬件寄存器只要調用API就行。2.3 和NVIDIA GPU比差異在哪很多人在選型Atlas之前都用過GPU跑YOLO我自己也是。GPU和昇騰卡在跑YOLO這件事上差異主要體現(xiàn)在三個方面。第一是模型格式。GPU上跑YOLO最常見的方式是PyTorch CUDA模型文件是.pt或者.onnx運行時由CUDA動態(tài)編譯和加載算子。Atlas不支持直接跑PyTorch模型它需要把模型轉換成昇騰專用的OM格式轉換過程由ATCAscend Tensor Compiler工具完成。OM格式相當于一個編譯好的二進制里面包含了算子調度信息、內(nèi)存分配策略等等。第二是算子支持。YOLO模型里用到的算子比如Conv、Relu、MaxPool、Upsample昇騰算子庫都有支持但版本不同支持情況可能不一樣。如果用了一個庫里面沒有的算子ATC轉換的時候就會報錯。這塊在后面的常見問題部分我會詳細說。第三是數(shù)據(jù)預處理。GPU方案一般用OpenCV做圖像縮放、歸一化然后在GPU上做TensorRT加速。Atlas方案里有一個叫DVPP的硬件模塊專門負責圖像縮放、格式轉換、摳圖等預處理操作可以釋放AI Core的算力讓AI Core專心做模型推理。合理使用DVPP整體吞吐量能有非常明顯的提升。3. 從零部署YOLOv5到Atlas 300V3.1 環(huán)境準備CANN和驅動部署的第一步是裝環(huán)境這一步最容易勸退新手因為步驟多、版本匹配要求嚴格。我在這個環(huán)節(jié)反復折騰了一整天下面把能簡化的都幫你整理出來。Atlas 300V 24G的軟件棧分為三層驅動、固件、CANN工具包。驅動是內(nèi)核模塊負責讓操作系統(tǒng)識別到硬件固件是板卡上的底層控制程序一般由驅動包一并安裝CANN是昇騰的計算架構包含算子庫、圖編譯工具ATC、運行時Runtime和推理應用開發(fā)接口。安裝順序必須是先裝驅動和固件再裝CANN。反過來裝會報錯。我用的是Ubuntu 20.04系統(tǒng)Python 3.8CANN版本是6.3.RC2配套的驅動版本可以在昇騰社區(qū)下載中心找到選擇對應芯片型號和操作系統(tǒng)版本即可。裝好后驗證環(huán)境是否正常npu-smi info這個命令類似NVIDIA的nvidia-smi能看到卡的溫度、顯存占用、算力利用率。執(zhí)行成功而且能看到設備信息說明驅動和固件沒問題。接下來設置環(huán)境變量。CANN安裝完成后需要把toolkit的bin目錄加到PATH里把so庫目錄加到LD_LIBRARY_PATH里。官方提供了設置腳本直接source一下就行source /usr/local/Ascend/ascend-toolkit/set_env.sh我建議把這個source命令寫進~/.bashrc否則每次開終端都得手動執(zhí)行。3.2 模型轉換從PyTorch權重到OM模型環(huán)境準備好之后第一步不是直接寫推理代碼而是先把PyTorch訓練好的YOLOv5權重轉換成OM格式。這個轉換動作官方叫ATC轉換核心任務是做圖編譯和算子映射。我用的YOLOv5是官方的6.0版本訓練好的權重文件是best.pt。轉換流程是先導出ONNX再用ATC把ONNX轉成OM。導出ONNX的步驟在YOLOv5的官方倉庫里已經(jīng)有現(xiàn)成的腳本python export.py --weights best.pt --include onnx --opset 11這一步會生成best.onnx文件。有幾個細節(jié)要留意。一是opset版本建議用11或者12太新的版本昇騰工具鏈支持可能不到位二是導出時要加上--simplify參數(shù)用onnx-simplifier對圖結構做簡化可以減少一些冗余算子三是YOLOv5的導出腳本會自動做模型推理驗證確保導出的ONNX結果和PyTorch一致。ONNX拿到之后用ATC工具轉OMatc --modelbest.onnx \ --framework5 \ --outputyolov5s_om \ --input_shapeimages:1,3,640,640 \ --soc_versionAscend310P3 \ --output_typeFP32參數(shù)含義我給新手解釋一下--model輸入的ONNX模型路徑。--framework框架類型5表示ONNX。--output輸出OM文件名。--input_shape指定輸入張量的形狀。YOLOv5的輸入是images形狀是NCHW即batch大小、通道數(shù)、高、寬。--soc_version指定芯片型號。Atlas 300V 24G對應的soc_version一般是Ascend310P3具體可以用npu-smi info查看芯片型號。--output_type輸出精度類型默認FP32。如果模型里有算子在昇騰算子庫中不支持ATC會明確報錯告訴你哪個算子不支持、在圖的哪一層。這時候需要看模型是否用了特殊算子或者嘗試更高版本的CANN實在不行就得對模型做算子替換。轉換成功后會生成yolov5s_om.om文件這個文件就是Atlas可以直接加載運行的模型。轉換這一步是整個流程中最容易出現(xiàn)問題的環(huán)節(jié)后面第4節(jié)我單獨講排錯經(jīng)驗。3.3 推理代碼實戰(zhàn)OM模型拿到手之后寫推理代碼就是純粹調用CANN的Python API。昇騰提供了一套名為AscendCLAscend Computing Language的編程接口類似CUDA的運行時API。整體流程是初始化設備、加載模型、準備輸入輸出內(nèi)存、執(zhí)行推理、解析結果。下面是一段最簡單的推理代碼實現(xiàn)了讀一張圖片、轉成模型輸入格式、執(zhí)行推理、拿到輸出import numpy as np import cv2 from ais_bench.infer.interface import InferSession # 初始化推理會話 session InferSession(device_id0, model_pathyolov5s_om.om) # 讀取圖片并做預處理 img cv2.imread(test.jpg) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (640, 640)) img img.astype(np.float32) / 255.0 img np.transpose(img, (2, 0, 1))[None] # 執(zhí)行推理 outputs session.infer(feeds[img]) # 拿到輸出 output outputs[0]如果你是用官方昇騰社區(qū)提供的ais_bench推理工具上面這段代碼基本可以直接跑。但如果你是想在正式項目里用我建議直接基于CANN的pyacl庫來寫這樣對內(nèi)存管理和模型輸入輸出控制得更精細。使用pyacl的核心步驟import acl import numpy as np # 初始化 acl.init() ret acl.rt.set_device(0) # 加載模型 model_id, ret acl.mdl.load_from_file(yolov5s_om.om) # 查詢模型輸入輸出維度 input_desc acl.mdl.get_input_desc(model_id) output_desc acl.mdl.get_output_desc(model_id) # 創(chuàng)建數(shù)據(jù)緩沖區(qū) input_data np.random.randn(1, 3, 640, 640).astype(np.float32) input_ptr acl.util.np_to_ptr(input_data) # 執(zhí)行推理 output_ptr acl.mdl.execute(model_id, [input_ptr], [output_size])這段代碼我簡化了很多細節(jié)實際開發(fā)時還要處理設備內(nèi)存的申請和釋放、輸出數(shù)據(jù)的拷貝等操作。建議剛上手的人先用ais_bench驗證模型轉換是否正確再考慮用pyacl做二次開發(fā)。推理結果拿到之后還需要做后處理也就是把YOLO輸出的原始張量解析成檢測框、類別和置信度。YOLOv5的檢測頭輸出形狀通常是(batch, 25200, 85)其中25200是三個尺度特征圖的錨框總數(shù)85代表4個邊界框坐標、1個目標置信度和80個類別置信度。后處理要做的是置信度過濾、非極大值抑制NMS、坐標映射回原圖。這部分代碼比較長網(wǎng)上有很多參考實現(xiàn)核心思路不變。3.4 調優(yōu)讓吞吐量再高一點模型能跑通只是第一步實際部署中我們更關心吞吐量和延遲。我在部署時對幾個方向做了調整吞吐量提升比較明顯。第一個方向是batch size。Atlas 300V 24G顯存大單張圖推理的時候AI Core利用率往往上不去可以通過設置更大的batch size來提升吞吐量。在ATC轉換時指定batch size為4或者8推理時一次性輸入4張或者8張圖推理總耗時只比單張圖稍微多一點但吞吐量接近翻倍。這里有個小細節(jié)ATC轉換時指定的input_shape里的batch維度必須和推理時傳入的數(shù)據(jù)保持一致。如果模型是用batch 4轉換的推理時就必須一次傳入4張圖。如果動態(tài)batch版本可以在不同的batch size之間切換但ATC轉換時要用--dynamic-batch參數(shù)開啟。開啟動態(tài)batch之后ATC需要在轉換時預留不同的batch size對應的內(nèi)存顯存占用會更高但靈活性更好。第二個方向是數(shù)據(jù)預處理硬件化。剛才提到DVPP模塊可以硬件完成圖像縮放、格式轉換而不是用OpenCV在CPU上做。如果你的瓶頸在CPU預處理好就要考慮把圖像resize和顏色轉換挪到DVPP上執(zhí)行。用DVPP做一次1080P圖像的resize和格式轉換耗時大概在幾毫秒級別CPU上做OpenCV的resize可能要十幾毫秒在高并發(fā)時這個差異非常明顯。第三個方向是輸出后處理。YOLO的NMS后處理在CPU上做如果檢測目標比較多耗時也會成為瓶頸。一些項目會選擇直接把網(wǎng)絡的輸出層改掉把NMS放進模型里或者用AI Core加速NMS。但這樣改動量大剛上手時不建議直接搞。更好的做法是先確保前處理和推理本身沒有性能浪費再考慮優(yōu)化后處理。4. 常見問題與排查技巧4.1 ATC轉換失敗ATC轉換失敗是所有人都會遇到的第一道坎報錯信息五花八門但我整理了一下大致分三類。第一類是模型輸入的opset版本問題。ONNX模型里用了較高版本的算子而CANN工具鏈還不支持這部分就會報Unsupported Op。解決辦法是導出ONNX時把opset降到11或者12或者用onnx-simplifier把圖簡化一遍。我遇到的絕大多數(shù)Unsupported Op問題都是在onnx-simplifier簡化之后解決的。第二類是輸入shape不匹配。ATC轉換時指定的input_shape和模型實際輸入不一致會報input shape does not match之類的錯誤。這時候用netron工具打開ONNX模型看看輸入端口的準確名稱和shape再對著改ATC命令即可。YOLOv5的輸入名一般是images但定制過的模型可能叫input.1或者別的名字不能想當然。第三類是內(nèi)存和資源不足。ATC轉換本身是個比較吃內(nèi)存和CPU資源的過程大模型轉換時如果服務器內(nèi)存不夠會出現(xiàn)進程被kill掉的狀況。建議轉換時關掉其他占用內(nèi)存的服務或者在一臺至少有16GB內(nèi)存的機器上進行轉換。順便多說一句ATC轉換不是在Atlas卡上進行的它是個純軟件編譯過程在CPU上完成和顯卡是不是插在機器上沒有直接關系。4.2 顯存和內(nèi)存相關Atlas 300V 24G雖然顯存大但也不是無限使用。經(jīng)常出現(xiàn)的問題是模型轉換時指定的batch size太大導致推理時顯存不足報acl.mdl execute failed, error code 507018之類錯誤。這種情況一般是顯存分配失敗解決辦法是降低batch size或者用--dynamic-batch參數(shù)讓模型按需分配顯存。還有一種情況是內(nèi)存泄漏。用pyacl做長時間推理時如果每次推理都申請設備內(nèi)存而不釋放顯存會慢慢被耗盡。我建議在推理循環(huán)里復用內(nèi)存緩沖區(qū)而不是每次都重新申請# 說的直白點這條循環(huán)不要寫在while True里面 input_data np.random.randn(1, 3, 640, 640).astype(np.float32) input_ptr acl.util.np_to_ptr(input_data) for i in range(1000): session.infer(feeds[input_data]) # 復用input_data這樣每次推理都走同一塊內(nèi)存不會造成內(nèi)存碎片和泄漏。如果發(fā)現(xiàn)自己每次推理顯存占用都在漲優(yōu)先檢查是不是循環(huán)內(nèi)重復申請了內(nèi)存。4.3 精度對不上部署YOLO時經(jīng)常遇到的一個問題OM模型推理的結果和PyTorch推理的結果對不上明明輸入同一張圖輸出的檢測框卻不一樣。這個問題多半出在圖像預處理上。PyTorch訓練時用的預處理是resize到640x640、歸一化到[0,1]、按ImageNet的mean和std做標準化。如果你在Atlas側推理時預處理流程和訓練時不一致精度就一定會漂移。尤其是DVPP做圖像縮放時默認的縮放算法可能和OpenCV的INTER_LINEAR不完全一致導致輸入數(shù)據(jù)的像素值和訓練時不同。解決辦法是要么在推理前用OpenCV在CPU上做預處理保證和訓練時一致要么在DVPP配置時指定和訓練一致的縮放算法。我的經(jīng)驗是如果對精度要求很高先用CPU OpenCV預處理把整個流程跑通驗證精度后面再優(yōu)化成DVPP。另外一個精度問題出在做INT8量化的時候。ATC默認用FP32精度轉換精度損失很小。但如果你為了追求性能用了INT8量化那精度會有一定損失。量化需要在轉換時提供校準數(shù)據(jù)集如果校準數(shù)據(jù)集和實際場景分布差異大檢測準確率會下降得很厲害。這塊我的建議是先用FP32模型把業(yè)務跑通再考慮量化的收益是否值得。4.4 性能不及預期有些讀者可能遇到一種情況ATLAS卡的INT8算力標稱很高但實際跑YOLO的幀率卻沒有想象中高。這里面有幾個隱藏因素。第一個因素是模型沒有編譯到最優(yōu)。ATC轉換時如果模型里有動態(tài)shape、動態(tài)分支或者圖優(yōu)化空間被約束住了推理性能會打折扣。解決辦法是盡量保證模型的輸入是固定shape減少圖結構中的動態(tài)節(jié)點。第二個因素是調度開銷。模型輸入太小的時候比如一張640x640的圖模型推理本身可能只要幾毫秒但數(shù)據(jù)從內(nèi)存拷貝到設備內(nèi)存、推理結果拷貝回來的時間反而占了大頭。解決思路是增大batch size攤薄每次調度的固定開銷。第三個因素是CPU瓶頸。前面說過如果數(shù)據(jù)預處理和后處理都在CPU上跑CPU忙不過來AI Core只能在那等數(shù)據(jù)。排查的時候可以先用npu-smi info看看卡上AI Core的利用率再用top看看CPU占用。如果AI Core空轉、CPU跑滿說明瓶頸在數(shù)據(jù)管道而不是推理本身。遇到性能問題不要急著怪硬件先用工具定位瓶頸是哪個環(huán)節(jié)再針對性地優(yōu)化。這條路子在任何推理卡上都適用。5. 回看這個卡的定位到底適合誰用如果把Atlas 300V 24G放到整個AI推理硬件生態(tài)里看它的定位其實非常清晰面向邊緣計算和數(shù)據(jù)中心推理場景主打低功耗、高能效比、大顯存。適合它的場景有這么幾類。一類是智慧園區(qū)、智慧交通這類視頻分析項目?,F(xiàn)場有很多路攝像頭需要在邊緣側做實時檢測對功耗和穩(wěn)定性要求高。300V的低功耗和無外接供電設計讓它能輕松塞進普通服務器不需要改造機房供電。另一類是算法公司做私有化交付??蛻舡h(huán)境五花八門不一定有NVIDIA的卡為了避免版權和供應鏈風險使用昇騰生態(tài)同時兼容訓練和推理是比較穩(wěn)妥的選擇。Atlas 300V 24G能部署YOLO系列、OpenPose、OCR等常見模型可以覆蓋大多數(shù)視覺AI需求。還有一類是高校和研究機構的模型驗證場景。買不起動輒幾萬的GPU訓練卡但又要跑AI實驗300V的價格和功耗都友好得多。雖然不能訓練大模型但做推理驗證、算法評估完全夠用。如果要說它的短板那就是生態(tài)成熟度和GPU生態(tài)沒法比。社區(qū)資料少、踩坑經(jīng)驗要靠自己積累很多在GPU上隨手能跑的東西搬到昇騰上就要自己折騰。但換個角度想正因為折騰你才會對模型編譯、算子映射、內(nèi)存管理這些東西理解得更深。我從GPU轉到Atlas之后對推理引擎的理解反而提升了一個檔次。最后分享一個我自己裝機時的小習慣拿到卡先別急著裝驅動先用npu-smi info確認板卡能被系統(tǒng)識別再裝上CANN寫個最簡單的resnet50推理demo把整條鏈路跑通之后再上YOLO這種復雜模型。這樣一步步來遇到問題也好定位到底是硬件的問題還是軟件的問題。部署推理這行慢就是快。