:從環(huán)境部署到Y(jié)OLOv5全流程跑通)
最近好幾個做視覺落地的朋友都在問同一件事Atlas 300V 24G 到底是不是運算加速卡能不能拿它來部署 YOLO說實話第一次看到“運算加速卡”這個叫法時我也愣了一下因為這個說法容易讓人往通用 GPU 或訓(xùn)練卡上靠。但 Atlas 300V 的官方定位其實非常明確——AI 推理加速卡也叫智能加速卡。我最近剛好在一臺 Atlas 300V 24G 上把 YOLOv5 跑通了這篇文章就用這次實操記錄把硬件定位、環(huán)境搭建、模型轉(zhuǎn)換、離線推理、常見坑一次講清楚。如果你剛拿到昇騰推理卡或者正在猶豫要不要在項目里用它來替換現(xiàn)有服務(wù)器這篇內(nèi)容值得看完。1. 先搞清楚 Atlas 300V 24G 的真實定位1.1 它是推理加速卡不是訓(xùn)練卡也不是通用運算卡很多人看到“加速卡”三個字第一反應(yīng)是“這不就是類似 NVIDIA 那種加速卡嗎”然后習(xí)慣性想往上裝 CUDA、跑 PyTorch 訓(xùn)練。這其實是最大的理解偏差。Atlas 300V 24G 確實是加速卡但它加速的是“推理”不是“訓(xùn)練”更不是通用的并行數(shù)值計算。從硬件形態(tài)上看它是一張 PCIe 接口的插卡板載 24GB 顯存主要面向數(shù)據(jù)中心和邊緣側(cè)的視頻分析、圖像分類、目標(biāo)檢測等推理場景。從算力結(jié)構(gòu)上看它用的是昇騰芯片的 AI Core突出 INT8 算力來做定點推理和視頻解碼這類高吞吐任務(wù)。你可以把它理解成“專門跑已訓(xùn)練好模型的執(zhí)行器”模型訓(xùn)練完、導(dǎo)出來、轉(zhuǎn)成 .om 格式之后由它來高效地跑前向計算。為了讓你更直觀地理解我拿它和常見的幾類加速設(shè)備做個對比設(shè)備類型典型形態(tài)主要用途生態(tài)/開發(fā)方式是否適合跑 YOLO 訓(xùn)練訓(xùn)練卡NVIDIA A100/H100、昇騰 Atlas 300T模型訓(xùn)練、大規(guī)模并行計算CUDA、CANN 訓(xùn)練棧適合通用計算卡NVIDIA 數(shù)據(jù)中心 GPU、部分 FPGA 卡科學(xué)計算、數(shù)據(jù)分析、通用并行算力CUDA/OpenCL生態(tài)豐富可以但成本高推理加速卡NVIDIA T4、Atlas 300V/300I模型部署、視頻流分析、批量前向推理TensorRT、CANN/ACL、MindX SDK不適合受算子與驅(qū)動限制邊緣 AI 盒子Atlas 200I DK、Jetson 系列端側(cè)實時推理各家 SDK不適合訓(xùn)練所以“Atlas 300V 24G 是運算加速卡嗎”這個問題如果“運算”指的是 AI 推理運算那答案是肯定的如果“運算”指的是像 CUDA 那樣隨便拿去做通用并行計算那答案是否定的。它的軟件棧是 CANN/昇騰體系沒有 CUDA也不建議拿去做科學(xué)計算或模型訓(xùn)練。這一點在立項選型時非常重要能幫你少走很多彎路。1.2 它最適合干的活是視頻流和批量推理那 Atlas 300V 24G 到底適合干什么以我這次部署 YOLO 的經(jīng)驗來看它最拿手的場景有三類。第一類是視頻流目標(biāo)檢測。Atlas 300V 系列的特色之一就是硬件視頻解碼能力強支持 H.264/H.265 硬解碼搭配 YOLO 類模型做實時目標(biāo)檢測非常順手。比如二三十路攝像頭畫面同時接入硬件解碼之后直接送進 AI Core 做推理瓶頸往往不在卡上而在你的后處理代碼寫得好不好。第二類是批量離線推理。比如你有一個圖片庫需要批量打標(biāo)、過濾、質(zhì)檢把 YOLO 模型轉(zhuǎn)成 .om 之后用多 batch 方式喂數(shù)據(jù)24G 顯存能塞下不小的 batch整體吞吐非常可觀。第三類是資源敏感的邊緣/數(shù)據(jù)中心混合部署。300V 的功耗和體積比訓(xùn)練卡小很多又可以插在普通 x86 服務(wù)器上適合在機房里的推理節(jié)點批量部署一塊卡負責(zé)一路或多路業(yè)務(wù)。24G 顯存聽起來很大但對于單張 640x640 輸入的 YOLOv5s 來說其實用不到這么多。24G 的價值在于多路并發(fā)、大分辨率輸入、或者同時常駐多個模型。后文我會專門講怎么把這 24G 用起來。2. 部署 YOLO 前先把路線選對2.1 為什么值得在 Atlas 300V 上跑 YOLO現(xiàn)在做目標(biāo)檢測部署大家的第一選擇往往是 NVIDIA 的 TensorRT或者是直接用 PyTorch 的 GPU 推理。為什么還要考慮昇騰卡我這次的體會有三點。第一是成本與功耗。在沒有現(xiàn)成 NVIDIA 卡的機房單獨采購一塊大顯存 GPU 的成本和功耗都不低。Atlas 300V 作為推理卡單卡功耗相對友好24G 版本在顯存容量上有明顯優(yōu)勢適合需要大 batch 或大分辨率輸入的業(yè)務(wù)。第二是國產(chǎn)化與合規(guī)需求。不少政企項目明確要求算力平臺使用國產(chǎn)化方案昇騰系列是主流的國產(chǎn) AI 芯片選擇之一。如果你的客戶對此有硬性要求那 Atlas 300V 就是很現(xiàn)實的候選。第三是推理吞吐穩(wěn)定。昇騰的 ACL 推理流程是“模型先轉(zhuǎn) .om再加載執(zhí)行”一旦轉(zhuǎn)換完成單次推理的算子調(diào)度路徑非常固定延遲波動比想象中小適合對穩(wěn)定性要求高的線上服務(wù)。當(dāng)然代價也很明顯生態(tài)沒有 CUDA 那么成熟網(wǎng)上資料相對少坑要自己踩。所以我這篇更值得你收藏至少把路給你蹚了一遍。2.2 ACL、MindX SDK、MindSpore Lite 三條路線怎么選在 Atlas 300V 上部署 YOLO主要有三條技術(shù)路線。很多初學(xué)者上來就懵不知道該學(xué)哪個這里我說清楚。第一條路線是直接用 ACLAscendCL也就是昇騰計算語言。這是最底層、最靈活的方式可以自己寫 Python 或 C 代碼加載 .om 模型控制輸入輸出內(nèi)存手動做后處理??梢岳斫鉃椤笆謩訐酢边m合想完全掌控流程、深入理解推理機制的人。第二條路線是 MindX SDK也叫 mxVision。它在 ACL 之上封裝了很多現(xiàn)成組件比如視頻解碼插件、圖像預(yù)處理插件、模型推理插件甚至內(nèi)置了 YOLO 系列的后處理插件??梢岳斫鉃椤白詣訐酢边m合快速出效果、不想糾結(jié)底層細節(jié)的人。第三條路線是 MindSpore Lite。如果你整個訓(xùn)練到部署都在 MindSpore 體系里這條路最順。但如果你想快速把現(xiàn)有的 PyTorch YOLOv5 遷過來中間還要經(jīng)歷 ONNX 轉(zhuǎn)換或多框架轉(zhuǎn)換反而繞了遠路。我這次選擇的是 ACL 路線。原因很簡單第一我希望把模型轉(zhuǎn)換、輸入預(yù)處理、輸出解析每一個環(huán)節(jié)都搞清楚這樣后續(xù)遇到問題能自己排查第二ACL 路線的性能上限最高方便做精細調(diào)優(yōu)第三MindX SDK 雖然方便但版本更新快不同版本插件行為有差異有時候反而浪費時間。如果你時間緊、任務(wù)單一完全可以用 MindX SDK 快速驗證如果你想長期維護一個推理項目我建議從 ACL 入手。3. 環(huán)境準(zhǔn)備與工具鏈搭建3.1 硬件安裝、驅(qū)動固件與 npu-smi 驗證拿到 Atlas 300V 24G 之后第一步不是急著裝軟件而是把它物理插到服務(wù)器上確認系統(tǒng)能識別到硬件。一般來說服務(wù)器需要預(yù)留 PCIe 插槽和供電插好之后開機在 Linux 系統(tǒng)里執(zhí)行l(wèi)spci | grep -i ascend如果能看板卡信息說明硬件鏈路已經(jīng)通了。接下來安裝驅(qū)動和固件這一步直接決定了后面的 CANN 能不能正常識別卡。驅(qū)動和固件的安裝包一般從昇騰社區(qū)下載注意驅(qū)動版本和固件版本要配套否則會出現(xiàn)“驅(qū)動已安裝但 npu-smi 看不到卡”的詭異問題。安裝完成并重啟后最關(guān)鍵的一步是用 npu-smi 工具驗證npu-smi info正常情況下它會列出卡的型號、芯片編號、顯存用量、溫度、當(dāng)前算力占用等信息。我之前就遇到過一臺上電后 npu-smi 里看不到卡的情況排查到最后是固件沒刷成功驅(qū)動裝得再干凈也沒用。所以我現(xiàn)在的習(xí)慣是先裝固件再裝驅(qū)動最后重啟再執(zhí)行一遍 npu-smi info每一步都驗證完再繼續(xù)。另外一個容易忽略的點是Atlas 300V 的芯片型號會影響后面的模型轉(zhuǎn)換參數(shù)。用 npu-smi info 查到的芯片型號比如 Ascend 310 系列或 Ascend 310P 系列必須記下來后文 ATC 模型轉(zhuǎn)換時的 --soc_version 參數(shù)就要靠它。3.2 安裝 CANN 工具包并配置環(huán)境變量硬件識別正常之后開始裝 CANN 工具包。CANN 是昇騰的計算架構(gòu)相當(dāng)于 CUDA 在 NVIDIA 體系里的角色提供了運行時、算子庫、ATC 模型轉(zhuǎn)換工具、pyACL 等能力。下載時要注意版本和驅(qū)動版本的配套關(guān)系昇騰社區(qū)每個版本都會給出兼容性說明照著選就行。安裝過程不復(fù)雜一般是解壓后執(zhí)行安裝腳本。真正容易踩坑的是環(huán)境變量配置。CANN 裝好后需要把 set_env.sh 里的變量加載到當(dāng)前 shell常見配置如下source /usr/local/Ascend/ascend-toolkit/set_env.sh然后驗證一下 ATC 工具是否可用atc --help如果提示找不到命令通常是環(huán)境變量沒配好或者裝的是 Mini 包缺少 ATC 組件。還有一點如果你同時裝了多個版本的 CANN環(huán)境變量里路徑一定別配錯否則 atc 用的可能是舊版本轉(zhuǎn)換模型時行為會很奇怪。等 atc 能正常執(zhí)行后再確認 pyACL 可用。在 Python 環(huán)境里執(zhí)行import acl不報錯就說明 ACL 的 Python 接口已經(jīng)就緒。我這里用的是 Python 3.7 CANN 5.x/6.x 的常見組合實際請按你的版本調(diào)整。這個環(huán)節(jié)踩的坑十有八九是“驅(qū)動、固件、CANN、Python 版本”四者不匹配所以前面每步都驗證后面就順暢得多。4. 實操YOLOv5 從 PyTorch 到 .om 到推理4.1 先導(dǎo)出 ONNX 并做結(jié)構(gòu)校驗在昇騰上部署 YOLO標(biāo)準(zhǔn)的輸入格式是 .om 離線模型。.om 不能直接從 .pt 轉(zhuǎn)通常要先經(jīng)過 ONNX。我這里以 YOLOv5s 為例其他 YOLO 版本流程大同小異。在 PyTorch 環(huán)境里官方倉庫已經(jīng)提供了導(dǎo)出腳本。為了減少算子兼容性問題我建議導(dǎo)出時指定 opset 版本為 11 或 13并開啟 simplifypython export.py --weights yolov5s.pt --include onnx --opset 11 --simplify導(dǎo)出后會得到 yolov5s.onnx。在繼續(xù)之前最好用 Netron 打開看一眼模型結(jié)構(gòu)確認輸入節(jié)點的名字一般是 images和輸出節(jié)點的數(shù)量。YOLOv5 原始導(dǎo)出的輸出是三維的形狀類似 [1, 25200, 85]也就是把所有預(yù)測框和 80 類得分都壓在一個節(jié)點里輸出。這個信息后面寫后處理代碼時要用到。還有一個細節(jié)YOLOv5 的預(yù)處理包含 letterbox、顏色通道轉(zhuǎn)換、歸一化。導(dǎo)出 ONNX 時這些邏輯還在 Python 端沒有進模型。所以推理時必須在 host 側(cè)把輸入圖片處理好再送給模型。如果你想把這部分預(yù)處理也合并到模型里可以用 ATC 的 AIPP 功能但為了先跑通流程我建議先在代碼里做。4.2 使用 ATC 轉(zhuǎn)換為昇騰離線模型 .om拿到 ONNX 之后核心操作就是用 ATC 工具把它轉(zhuǎn)成 .om。ATC 會讀取 ONNX 的算子圖將其映射到昇騰芯片支持的算子并在這個階段做圖優(yōu)化、算子融合和內(nèi)存分配。以我這次為例命令大概長這樣atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_ascend \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640參數(shù)說明--model輸入 ONNX 文件路徑。--framework5表示輸入模型格式是 ONNX。--output輸出 .om 文件的前綴名。--soc_version芯片型號。我這邊查到的是 Ascend310P 系列你務(wù)必用 npu-smi info 查到的實際型號填寫。填錯的話轉(zhuǎn)換可能成功但加載到卡上會報模型與設(shè)備不匹配。--input_shape固定輸入為 1 張 3x640x640靜態(tài) shape 最簡單也最穩(wěn)。如果你需要不同 batch可以改成 --dynamic_batch_size1,2,4,8但動態(tài) shape 在部分算子上的支持沒有靜態(tài)好能固定就固定。轉(zhuǎn)換成功后目錄下會出現(xiàn) yolov5s_ascend.om。這一步如果報算子不支持往往是因為 ONNX 里帶了不太常見的算子或者 opset 版本太高??梢韵仍囍?opset 降到 11或者換一個簡化導(dǎo)出的方式把 Focus、slice 等特殊結(jié)構(gòu)替換成更容易映射的卷積組合。4.3 使用 pyACL 加載 .om 完成推理.om 就緒后接下來就是寫推理程序。這里我用 pyACL 給你一個最精簡的骨架方便理解整個流程import acl import numpy as np # 初始化 acl.init() acl.rt.set_device(0) # 加載模型 model_path yolov5s_ascend.om model_id acl.mdl.load_from_file(model_path) model_desc acl.mdl.create_desc() acl.mdl.get_desc(model_desc, model_id) # 獲取輸入輸出大小 input_size acl.mdl.get_input_size_by_index(model_desc, 0) output_size acl.mdl.get_output_size_by_index(model_desc, 0) # 申請 device 內(nèi)存 input_ptr acl.rt.malloc(input_size, 2) output_ptr acl.rt.malloc(output_size, 2) # 準(zhǔn)備輸入數(shù)據(jù)這里 input_data 是 shape(1,3,640,640) 的 np.float32 數(shù)組 # 注意要和導(dǎo)出 ONNX 時的預(yù)處理完全一致 acl.rt.memcpy(input_ptr, input_size, input_data.ctypes.data, input_size, 1) # 創(chuàng)建 dataset input_dataset acl.mdl.create_dataset() output_dataset acl.mdl.create_dataset() acl.mdl.add_dataset_buffer(input_dataset, acl.create_data_buffer(input_ptr, input_size)) acl.mdl.add_dataset_buffer(output_dataset, acl.create_data_buffer(output_ptr, output_size)) # 同步推理 ret acl.mdl.execute(model_id, input_dataset, output_dataset) # 拷貝結(jié)果回 host output_data np.zeros(output_size, dtypenp.uint8) acl.rt.memcpy(output_data.ctypes.data, output_size, output_ptr, output_size, 2) # 解析 output_data因為實際是 float 數(shù)據(jù)需要按 float32 解析 result np.frombuffer(output_data, dtypenp.float32) # 后續(xù)做后處理...這只是最基礎(chǔ)的流程實際生產(chǎn)里還要加上多 batch、多線程、異步推理、內(nèi)存復(fù)用等優(yōu)化。但核心步驟就是這幾步初始化、加載模型、準(zhǔn)備輸入、執(zhí)行、取回輸出。只要把這條鏈路跑通你已經(jīng)完成 80% 的工作了。4.4 后處理與 NMS 的注意點模型輸出的一堆 float 數(shù)值并不能直接畫框必須做解碼和 NMS。YOLOv5 輸出的原始格式是 [batch, 25200, 85]其中 25200 3 個特征層 × 每個特征層的格子數(shù)85 4 個坐標(biāo) 1 個目標(biāo)置信度 80 個類別概率。你需要先把坐標(biāo)信息還原成原圖坐標(biāo)系過濾掉低置信度的框再做 NMS。后處理代碼通常在 CPU 上跑在幀率要求不高時問題不大。但如果你的目標(biāo)是高并發(fā)視頻流NMS 會成為明顯瓶頸。我常用的方案是先用置信度閾值把絕大部分候選框過濾掉只留少量高分框再做 NMS這樣能省下大量 sort 和循環(huán)時間?;蛘咧苯佑?OpenCV 的 NMSBoxesimport cv2 keep cv2.dnn.NMSBoxes(boxes, scores, conf_thres0.25, iou_thres0.45)一個容易踩坑的地方是預(yù)處理不一致。比如 YOLOv5 官方訓(xùn)練時用的是 RGB、像素縮放到 0~1、letterbox 填充灰色。如果你用 OpenCV 讀圖默認是 BGR順序不對會導(dǎo)致檢測精度嚴重下降。我在第一次跑通了代碼但檢測結(jié)果全是垃圾框時就卡在這里。所以請務(wù)必確認三處顏色通道順序、歸一化方式、letterbox 的填充值和導(dǎo)出模型時保持一致。5. 常見問題與調(diào)優(yōu)思路5.1 五個高頻報錯速查表部署昇騰卡的過程里有些問題出現(xiàn)頻率極高我直接整理成速查表希望能幫你快速定位?,F(xiàn)象可能原因解決思路npu-smi info 看不到卡固件沒刷成功、驅(qū)動版本不對重新刷固件核對驅(qū)動/固件配套表重啟后再驗證atc 命令找不到環(huán)境變量未配置、CANN 組件缺失重新 source set_env.sh確認安裝的是完整版 CANN 而非精簡包ATC 轉(zhuǎn)換報算子不支持ONNX opset 版本過高、特殊算子無法映射降低 opset 到 11或換簡化導(dǎo)出方式或調(diào)整模型結(jié)構(gòu)繞過該算子加載 .om 報模型與設(shè)備不匹配--soc_version 填錯用 npu-smi info 查實際芯片型號重新執(zhí)行 ATC推理結(jié)果全是亂框或精度差預(yù)處理和導(dǎo)出時不匹配檢查 RGB/BGR、歸一化、letterbox 尺寸與填充值其中“模型與設(shè)備不匹配”是我見過最多的用戶問題。很多人會拿網(wǎng)上的 ATC 命令直接抄但不同昇騰卡對應(yīng)的 soc_version 不一樣填錯就會出現(xiàn)怪問題。最穩(wěn)妥的辦法是執(zhí)行 npu-smi info 看第一行或芯片信息再對著官方支持的 soc_version 列表填。5.2 推理速度上不去按這個順序排查部署完第一版大家最關(guān)心的就是性能。如果你發(fā)現(xiàn)推理速度不如預(yù)期我建議按這個順序排查比盲目調(diào)參高效得多。第一查預(yù)處理是不是在 CPU 上耗時過多。很多人把圖片 resize、歸一化、通道轉(zhuǎn)換全寫在 Python 里圖稍微大一點預(yù)處理時間可能比推理還長。解決辦法是用 AIPP 把預(yù)處理合并進模型或者用硬件解碼模塊DVPP來替代 OpenCV 的 imread/resize。第二查是不是動態(tài) shape 觸發(fā)了額外重編譯。如果用動態(tài) batch 或動態(tài)分辨率模型在不同尺寸切換時可能觸發(fā) weight 重編排導(dǎo)致某幾次推理延遲特別高。盡量用固定 shape或者用動態(tài)分檔方式把常見尺寸固定成幾檔。第三查內(nèi)存拷貝是否頻繁。host 和 device 之間來回拷貝大數(shù)組非常費時尤其是多路視頻場景。建議統(tǒng)一用 device 內(nèi)存池輸入輸出數(shù)據(jù)盡量在 device 側(cè)流轉(zhuǎn)減少 memcpy。第四看卡是否真的在滿負荷工作。執(zhí)行 npu-smi info如果發(fā)現(xiàn) AI Core 利用率很低大概率是數(shù)據(jù)供給跟不上也就是“卡在等數(shù)據(jù)”瓶頸在預(yù)處理、解碼或后處理環(huán)節(jié)而不是模型本身。最后如果模型允許可以考慮 INT8 量化。昇騰卡的 INT8 算力往往比 FP16 高很多量化后推理速度提升明顯前提是你要在驗證集上評估精度損失不能無腦量化。5.3 24G 顯存怎么用才不虧Atlas 300V 24G 的顯存不同場景下的用法完全不一樣。我看到不少人拿它跑單路 640x640 小模型結(jié)果顯存占用不到 2G這就有點浪費了。想讓這 24G 真正發(fā)揮價值我建議從三個方向切入。第一是多路視頻流并發(fā)。一個常見做法是每路視頻一個獨立線程解碼后送入同一個 .om 模型進行 batch 推理。顯存足夠時batch 可以開大吞吐量成倍上漲。我做多路測試時的經(jīng)驗是先確定單路解碼和預(yù)處理的 CPU 開銷留出一部分核給后處理剩下的資源盡量都壓在推理上。第二是大分辨率輸入。傳統(tǒng)小模型對顯存需求低但如果你要做小目標(biāo)檢測輸入分辨率可能要提到 1280 甚至更高這時候顯存占用會明顯上升。24G 版本就比 8G/16G 版本寬裕得多不用為了省顯存被迫降分辨率。第三是模型常駐。24G 可以同時放下好幾個模型比如白天跑 YOLOv5、晚上跑一個行為識別模型或者在同一個進程里加載檢測、分類、分割三個模型避免頻繁切換模型帶來的加載開銷。當(dāng)然如果你的業(yè)務(wù)就是單路 640 小模型那 24G 確實綽綽有余。這時候不必硬湊并發(fā)穩(wěn)定、低功耗地跑好你現(xiàn)有業(yè)務(wù)本身就是正確用法。我個人在實際操作中的體會是昇騰這套工具鏈和 CUDA 生態(tài)比確實不夠順滑文檔版本差異也大但只要把 ONNX 到 .om 這條路走通一次后面換模型基本就是改改參數(shù)的事。如果你手頭正好有 Atlas 300V 24G別急著拿它去和訓(xùn)練卡比算力它的戰(zhàn)場是視頻流、批量推理、邊緣部署這類場景。最后再分享一個小技巧正式上生產(chǎn)前一定用 profiling 工具把每個算子耗時拉出來看一遍太多性能問題都藏在預(yù)處理和內(nèi)存拷貝里不跑一次 profile 你根本想不到瓶頸在哪。祝部署順利。