戰(zhàn):從YOLO模型轉(zhuǎn)換到部署避坑指南)
如果你最近也在看 AI 推理硬件應(yīng)該能在各種評測和規(guī)格表里高頻刷到“Atlas 300V 24G”這個名字。有人問它到底是不是運(yùn)算加速卡有人直接把手頭的 YOLO 模型往這塊卡上搬然后對著“算子不支持”“容器里找不到 NPU”之類的報錯懷疑人生。作為一個在昇騰生態(tài)里摸爬過幾個推理項(xiàng)目的工程師我先給出一個明確的結(jié)論Atlas 300V 24G 是昇騰生態(tài)里的 AI 推理加速卡它不是通用 GPU但在“固定推理任務(wù)”這個自己擅長的領(lǐng)域里它確實(shí)是一塊性價比很高的運(yùn)算加速卡。這篇文章就圍繞這塊卡聊聊它的真實(shí)定位、為什么適合跑 YOLO、從零部署的完整鏈路以及在實(shí)操中那些常規(guī)文檔不會寫的問題。1. 先搞清楚Atlas 300V 24G 到底是一塊什么卡1.1 它“算不算”運(yùn)算加速卡拆開“運(yùn)算加速卡”這個詞大部分人的第一反應(yīng)是 NVIDIA 的計算卡比如 V100、A100 這種可以跑科學(xué)計算、AI 訓(xùn)練、通用 CUDA 程序的 GPGPU。Atlas 300V 24G 和它們在邏輯上有一個核心差異它是一塊 NPU而且是一塊定位非常明確的推理卡?!巴评砑铀佟焙汀巴ㄓ糜嬎恪钡膮^(qū)別在哪用工廠類比GPU 是全能型選手既能做訓(xùn)練、又能做推理還能跑渲染而 Atlas 300V 更像一條專項(xiàng)流水線它對神經(jīng)網(wǎng)絡(luò)推理做了大量優(yōu)化但對其他通用計算任務(wù)幾乎幫不上忙。你沒法把一段 CUDA 代碼拿到昇騰上直接跑也沒法拿它當(dāng)無腦的并行計算卡用。它支持的編程接口是 AscendCL模型的執(zhí)行單位是經(jīng)過 ATC 工具轉(zhuǎn)換后的離線模型文件OM 格式而不是像 GPU 那樣動態(tài)加載一個 PyTorch 模型就能跑。所以如果你問“Atlas 300V 24G 是運(yùn)算加速卡嗎”我的回答是它是 AI 推理加速卡在 AI 推理這個狹義場景下是一塊運(yùn)算加速卡但它不是通用計算卡。這個定位決定了它的選型思路和部署路徑也決定了它適合哪些項(xiàng)目、不適合哪些項(xiàng)目。1.2 硬件規(guī)格與產(chǎn)品線對照Atlas 300V 的命名里“300V”代表這是一張半高半長、主打視頻和視覺推理的 PCIe 卡。它基于昇騰 310P 處理器提供的 24GB 內(nèi)存對推理場景來說非常充裕。我自己在做選型時比較在意的幾個規(guī)格點(diǎn)整理成了表格方便你對照項(xiàng)目典型參數(shù)選型說明處理器昇騰 310P 系列不同 SoC 版本在 ATC 轉(zhuǎn)換時需指定對應(yīng) soc_version內(nèi)存24GB可以容納較大的模型也適合多路視頻流并發(fā)推理接口PCIe半高半長單槽對服務(wù)器空間友好放普通工作站里也比較容易功耗官方標(biāo)稱約 70W 級別比同級別 GPU 低不少但也需要保證機(jī)箱風(fēng)道散熱執(zhí)行方式離線模型OM推理不支持實(shí)時解釋執(zhí)行 PyTorch 模型必須先做模型轉(zhuǎn)換開發(fā)接口AscendCL / pyACL類似 CUDA 的上層接口用于加載 OM、傳輸數(shù)據(jù)、執(zhí)行推理昇騰 300 系列里還有幾個容易混淆的型號。比如 Atlas 300V Pro帶 Pro 后綴內(nèi)存更高通常配置 48GBAtlas 300I Pro 則是面向服務(wù)器內(nèi)部集成場景的推理卡。它們在驅(qū)動、CANN 和 ATC 的 soc_version 參數(shù)上可能不一樣如果拿錯了配置文件最典型的表現(xiàn)就是模型轉(zhuǎn)換時報“SoC version not support”之類的錯。所以我建議你拿到卡之后第一件事不是急著裝環(huán)境而是用 npu-smi info 看芯片實(shí)際型號再對著版本確認(rèn)后續(xù)命令參數(shù)。1.3 適合什么場景不適合什么場景這塊卡最適合的場景一句話總結(jié)單路或多路視頻流上的目標(biāo)檢測、分類、分割等固定推理任務(wù)。在我接過的項(xiàng)目里Atlas 300V 出鏡率最高的幾個方向是智慧交通的車輛和行人檢測、安防場景的視頻結(jié)構(gòu)化、工業(yè)質(zhì)檢里的缺陷定位、OCR 文字識別。這些任務(wù)有一個共同點(diǎn)模型結(jié)構(gòu)基本固定、輸入尺寸基本固定、軟件??梢园汛蟛糠謨?yōu)化工作放到離線階段完成。這正是推理卡的舒適區(qū)。但不適合的場景也很明顯。如果你需要頻繁迭代模型結(jié)構(gòu)三天兩頭換新網(wǎng)絡(luò)或者要做大模型訓(xùn)練那 Atlas 300V 并不是好選擇。訓(xùn)練場景應(yīng)該考慮昇騰的 Atlas 800 訓(xùn)練服務(wù)器或者傳統(tǒng) GPU而快速實(shí)驗(yàn)階段用 GPU 也更省心。還有一個容易被忽略的限制現(xiàn)有基于 CUDA 寫成的推理服務(wù)遷移到昇騰上幾乎不可能做到零改動至少模型導(dǎo)出、算子適配、預(yù)處理管線都要重新過一遍。2. 為什么“Atlas 300V YOLO”這個組合這么多人做2.1 YOLO 在邊緣推理里的地位YOLO 系列在目標(biāo)檢測領(lǐng)域算是最“皮實(shí)”的模型之一。YOLOv5 和 YOLOv8 的訓(xùn)練生態(tài)很成熟導(dǎo)出 ONNX 的路徑清晰部署到各類 AI 加速硬件上都有現(xiàn)成方案。這樣的特性正好契合 Atlas 300V 的部署邏輯訓(xùn)練階段你仍然可以使用 PyTorch 生態(tài)推理階段把模型轉(zhuǎn)換成 OM 文件交給昇騰執(zhí)行。另一個原因是 YOLO 的結(jié)構(gòu)相對規(guī)整主干網(wǎng)絡(luò)和檢測頭的算子基本都是卷積、歸一化、激活、拼接這類通用算子。昇騰的推理卡對這類算子的支持度很高很少遇到 GPU 上能跑、但轉(zhuǎn)換時“算子不支持”的尷尬情況。所以現(xiàn)在很多國產(chǎn)化推理項(xiàng)目的第一批模型清單里YOLO 總是排在最前面不是沒有道理的。2.2 昇騰跑 YOLO 的幾條主流路線昇騰生態(tài)里部署 YOLO大致有四條路可以走。我在項(xiàng)目里都嘗試過分別說一下它們的適用場景。第一條是 PyTorch 訓(xùn)練后導(dǎo)出 ONNX再用 ATC 轉(zhuǎn)成 OM最后用 AscendCL 推理。這是我最推薦的一條路線也是現(xiàn)在昇騰社區(qū)里資料最多的路線。它把訓(xùn)練框架和推理平臺解耦ONNX 作為中間格式方便做精度對比和算子排查。第二條是 MindSpore 訓(xùn)練導(dǎo)出 MindIR 再轉(zhuǎn) OM適合鐵了心使用全自研生態(tài)的團(tuán)隊(duì)但社區(qū)資料相對少遇到問題需要自己啃文檔。第三條是 PyTorch torch_npu在 PyTorch 里直接把模型搬到 NPU 上推理適合不想重寫推理框架的原型驗(yàn)證但性能不一定比純 OM AscendCL 方案有優(yōu)勢。第四條是從 Darknet 權(quán)重轉(zhuǎn) ONNX 再轉(zhuǎn) OMYOLOv4 時代的老項(xiàng)目可能用到現(xiàn)在新項(xiàng)目基本不需要考慮了。路線技術(shù)棧適合人群缺點(diǎn)ONNX → ATC → OM ACLPyTorch / ONNX / ATC大多數(shù)生產(chǎn)項(xiàng)目需要適配預(yù)處理和后處理MindSpore → MindIR → OMMindSpore / C 或 Python全昇騰生態(tài)團(tuán)隊(duì)文檔少上手門檻高PyTorch torch_npuPyTorch / NPU 加速快速驗(yàn)證原型性能上限不明確算子兼容性偶發(fā)Darknet → ONNX → OMDarknet / ONNX維護(hù) YOLOv4 老項(xiàng)目鏈路長轉(zhuǎn)換容易踩坑2.3 部署方案的選擇邏輯在確定技術(shù)路線之后接下來要決定的是模型實(shí)例和 batch 的部署方式。這個選擇直接影響吞吐和延遲GPU 里的那套經(jīng)驗(yàn)在昇騰上依然大致成立。如果只有一路視頻流模型 batch 設(shè)成 1 就夠延遲最低邏輯最簡單。如果有多路視頻流要做實(shí)時檢測我建議不要開多個進(jìn)程各跑一個 batch1 的模型而是盡量把多幀數(shù)據(jù)拼成一個 batch 喂給同一個模型實(shí)例。比如 4 路視頻流每一輪取 4 幀拼成 batch4 輸入推理一次得到 4 個結(jié)果。這樣做的好處是最大化利用 310P 的算力也避免多進(jìn)程搶資源時的不穩(wěn)定。24GB 內(nèi)存對 YOLO 系列目標(biāo)檢測模型來說剩余量很大。即使在 batch8 的前提下同時加載好幾個模型實(shí)例也完全夠用。實(shí)際項(xiàng)目中真正的瓶頸往往不在 NPU 算力而在視頻解碼鏈路。如果每路視頻流都用 OpenCV 的 VideoCapture 在 CPU 上解碼高分辨率高幀率的視頻很可能讓 CPU 先跑滿。這時候就需要考慮硬件解碼或者減少單機(jī)視頻路數(shù)。3. 實(shí)操在 Atlas 300V 24G 上把 YOLOv5/v8 跑起來3.1 環(huán)境準(zhǔn)備驅(qū)動、固件、CANN 與容器掛載這套環(huán)境的安裝順序我建議是安裝 NPU 驅(qū)動和固件也叫 HDK再安裝 CANN Toolkit最后創(chuàng)建運(yùn)行環(huán)境。驅(qū)動和固件的安裝包在昇騰社區(qū)都可以下載一般是一個 Ascend-hdk 之類的 run 包執(zhí)行后會自動安裝到 /usr/local/Ascend 目錄下。這里要特別提醒一句驅(qū)動、固件和 CANN 三者的版本必須配套。昇騰的東西對版本匹配相當(dāng)敏感很多時候“莫名其妙”的問題其實(shí)都是版本不一致導(dǎo)致的。我踩過最典型的一次坑是固件升級之后CANN 沒跟著升結(jié)果模型加載時一直報錯看了半天日志才發(fā)現(xiàn)是版本不匹配。如果不想污染宿主機(jī)環(huán)境推薦用官方容器鏡像。啟動容器的命令里沒有把設(shè)備節(jié)點(diǎn)掛載進(jìn)去是最常見的容器內(nèi)找不到 NPU 的原因。我常用的啟動參數(shù)是這樣的docker run -itd --name ascend_yolo \ --device/dev/davinci0 \ --device/dev/davinci_manager \ --device/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64 \ -v /etc/ascend_install.info:/etc/ascend_install.info \ --cap-addSYS_RAWIO \ your-ascend-image:tag容器起來之后第一件事是執(zhí)行 npu-smi info確認(rèn)能正??吹娇ǖ男畔?。如果這個命令無法輸出正常的設(shè)備信息后面所有步驟都不用繼續(xù)了先回環(huán)境配置找問題。整個環(huán)境準(zhǔn)備階段我一般預(yù)留半天時間比較穩(wěn)妥別指望一次成功。3.2 模型導(dǎo)出PyTorch 模型轉(zhuǎn) ONNX我以 YOLOv5 為例因?yàn)樗?export 腳本最成熟。導(dǎo)出命令本身很簡單但有幾個細(xì)節(jié)決定后續(xù) ATC 轉(zhuǎn)換能不能一次通過。首先是 opset 版本。建議設(shè)置成 12 或 13不要用太高也不要太低。其次是輸入尺寸。如果你不需要動態(tài)輸入我強(qiáng)烈建議在導(dǎo)出時就固定為 640x640這樣后續(xù) ATC 轉(zhuǎn)換簡單推理性能也最穩(wěn)定。如果你需要支持不同分辨率就得在導(dǎo)出時開啟 dynamic但這會讓很多推理卡的算子優(yōu)化無從下手性能往往不如固定 shape。還有一個非常關(guān)鍵的步驟導(dǎo)出時不要帶 NMS 后處理。YOLO 在 PyTorch 里運(yùn)行時通常會執(zhí)行檢測頭輸出、置信度過濾、NMS 等后處理邏輯但 AT C 對 NMS 這類復(fù)雜邏輯支持有限最佳實(shí)踐是只導(dǎo)出前向網(wǎng)絡(luò)把 NMS 放到推理之后用 OpenCV 或 NumPy 自己實(shí)現(xiàn)。具體操作上YOLOv5 可以用下面的命令python export.py --weights yolov5s.pt --include onnx --opset 12 --img-size 640 640導(dǎo)出完成后建議先用 onnxruntime 在 CPU 上跑一張測試圖把這個 ONNX 的輸出和 PyTorch 模型的輸出對比一下確認(rèn)精度沒有損失再進(jìn)入下一步。這一步雖然花費(fèi)十幾分鐘但能把 ATC 轉(zhuǎn)換時的“算子錯誤”和“模型本身的問題”區(qū)分開省下后面排查的大把時間。3.3 ATC 模型轉(zhuǎn)換詳解ATC 是昇騰工具鏈里最核心的模型轉(zhuǎn)換工具。它的作用是把 ONNX、MindIR、TensorFlow 模型轉(zhuǎn)成昇騰硬件能高效執(zhí)行的離線模型 OM 文件。我以 ONNX 為例給出一版可以直接參考的轉(zhuǎn)換命令atc --modelyolov5s.onnx \ --framework5 \ --outputyolov5s_bs1 \ --soc_versionAscend310P3 \ --input_shapeimages:1,3,640,640 \ --output_typeFP16 \ --insert_op_confaipp.cfg各參數(shù)的含義拆開來看--framework5 表示輸入模型是 ONNX--output 是輸出文件名前綴--soc_version 必須和你的卡匹配Atlas 300V 24G 通常對應(yīng) Ascend310P3但這個參數(shù)一定要根據(jù)你機(jī)器上 npu-smi 展示的實(shí)際芯片信息來定--input_shape 指定輸入 tensor 的名字和形狀注意這里的名字必須和 ONNX 模型里的輸入名一致YOLOv5 一般是 images--output_type 設(shè)置為 FP16推理時能獲得更好的性能--insert_op_conf 用來配置 AIPP 預(yù)處理算子。AIPP 配置文件長這樣aipp_op { aipp_mode: static input_format: RGB888_U8 src_image_size_w: 640 src_image_size_h: 640 csc_switch: false rbuv_swap_switch: true min_chn_0: 0 max_chn_0: 255 min_chn_1: 0 max_chn_1: 255 min_chn_2: 0 max_chn_2: 255 mean_chn_0: 123.675 mean_chn_1: 116.28 mean_chn_2: 103.53 var_chn_0: 58.395 var_chn_1: 57.12 var_chn_2: 57.375 }設(shè)置 AIPP 的核心目的是把圖像的歸一化操作下沉到硬件上減少 CPU 的預(yù)處理壓力。但這里有一個非常容易踩坑的地方如果 PyTorch 模型里的預(yù)處理已經(jīng)包含了歸一化或者你在導(dǎo)出 ONNX 之前已經(jīng)把歸一化層放進(jìn)了網(wǎng)絡(luò)結(jié)構(gòu)那么在 AIPP 里再設(shè)置 mean/var 就會導(dǎo)致雙重歸一化輸出結(jié)果會直接崩掉。我的建議是要么把歸一化邏輯全部放到 AIPP要么全部放到網(wǎng)絡(luò)內(nèi)部千萬不要兩邊都做。3.4 使用 AscendCL 寫一個最簡推理腳本模型轉(zhuǎn)成 OM 之后推理階段主要和 AscendCL 打交道。AscendCL 提供 C 接口和 Python 接口pyACL。Python 接口適合快速驗(yàn)證C 接口適合生產(chǎn)環(huán)境。下面是一個最簡推理流程的骨架import acl import numpy as np ret acl.init() ret acl.rt.set_device(0) context, ret acl.rt.create_context(0) model_path b./yolov5s_bs1.om model_id, ret acl.mdl.load_from_file(model_path) desc acl.mdl.create_desc() acl.mdl.get_desc(desc, model_id) # 獲取輸入輸出尺寸 num_inputs acl.mdl.get_num_inputs(desc) num_outputs acl.mdl.get_num_outputs(desc) input_size acl.mdl.get_input_size_by_index(desc, 0) output_size acl.mdl.get_output_size_by_index(desc, 0) # 準(zhǔn)備輸入數(shù)據(jù)注意要和 AIPP 配置一致 image np.fromfile(frame.bin, dtypenp.uint8).reshape(1, 3, 640, 640) input_data image.astype(np.float16) # 分配到 Device 內(nèi)存并拷貝 input_ptr acl.rt.malloc(input_size, 2) acl.rt.memcpy(input_ptr, input_size, input_data.ctypes.data, input_data.nbytes, 1) output_ptr acl.rt.malloc(output_size, 2) output_np np.zeros(output_size, dtypenp.int8) # 執(zhí)行推理 ret acl.mdl.execute(model_id, [input_ptr], [input_size], [output_ptr], [output_size]) # 拷回 Host 內(nèi)存 acl.rt.memcpy(output_np.ctypes.data, output_np.nbytes, output_ptr, output_size, 2) acl.rt.free(input_ptr) acl.rt.free(output_ptr)需要注意上面代碼里的內(nèi)存分配方式、memcpy 的類型枚舉值在不同 CANN 版本里可能有所不同具體接口簽名要以你安裝版本的 API 文檔為準(zhǔn)。但整個流程是通用的初始化設(shè)備、加載模型、申請 Device 內(nèi)存、拷貝輸入、執(zhí)行推理、拷貝輸出、釋放資源。推理拿到的輸出后處理和 GPU 版本完全一樣。YOLO 輸出的是檢測頭的原始預(yù)測需要做置信度過濾、類別篩選、NMS然后把檢測框坐標(biāo)還原到原圖尺寸。這部分建議直接用 NumPy 和 OpenCV 實(shí)現(xiàn)穩(wěn)定且容易調(diào)試不必強(qiáng)行放到 NPU 上跑。3.5 運(yùn)行驗(yàn)證與性能觀察整個流程打通后我習(xí)慣先用一張測試圖做端到端驗(yàn)證確保輸出框和 PyTorch GPU 版的結(jié)果一致再看性能。我自己在 Atlas 300V 24G 上跑 YOLOv5s、640x640、FP16、batch1 的端到端推理單幀延遲在 10 毫秒到 20 毫秒這個量級CANN 版本和驅(qū)動版本不同會有波動。這個量級跑一路視頻流綽綽有余即使要跑多路只要 batch 拼上去吞吐提升也很明顯。性能觀察階段可以一邊跑推理一邊執(zhí)行 npu-smi info看芯片利用率、內(nèi)存占用和溫度。如果利用率長期打不滿基本可以確定瓶頸不在 NPU而在數(shù)據(jù)讀取或解碼側(cè)。4. 部署中的坑問題排查與調(diào)優(yōu)記錄4.1 常見報錯速查表昇騰工具鏈的報錯信息風(fēng)格比較“工程化”很多錯誤可以直接從錯誤碼查文檔但也有一些隱藏比較深的問題要結(jié)合經(jīng)驗(yàn)判斷。我把常見的現(xiàn)象、原因和解決思路整理成了表格方便你快速定位。報錯現(xiàn)象常見原因解決思路npu-smi info 找不到設(shè)備驅(qū)動或固件未安裝成功版本不匹配重裝配套的驅(qū)動和固件確認(rèn) lspci 能看到設(shè)備容器里 import acl 失敗容器啟動時沒有掛載設(shè)備節(jié)點(diǎn)加上 --device/dev/davinci0 和 davinci_manager報錯 100000 或 ACL_ERROR_RT_PARAM_INVALID設(shè)備初始化失敗Context 創(chuàng)建失敗檢查 set_device 參數(shù)確認(rèn)能正常打開設(shè)備ATC 報 E40001算子不支持模型中有不支持的算子嘗試更換 opset、用 onnx-simplifier 簡化模型模型輸出全是 0 或全 NaN預(yù)處理歸一化重復(fù)或缺失檢查 AIPP 配置與訓(xùn)練預(yù)處理是否一致推理結(jié)果檢測框偏移圖像縮放或 letterbox 參數(shù)不一致確保推理輸入的預(yù)處理與訓(xùn)練保持一致程序運(yùn)行一段時間后內(nèi)存持續(xù)上漲推理循環(huán)里沒有釋放 Device 內(nèi)存緩存輸出 buffer復(fù)用而不是每幀重新分配4.2 性能調(diào)優(yōu)的幾條實(shí)操經(jīng)驗(yàn)先把固定 shape 這件事再強(qiáng)調(diào)一遍。動態(tài) shape 雖然在靈活性上有優(yōu)勢但在昇騰推理卡上會嚴(yán)重限制算子優(yōu)化空間。如果你的產(chǎn)品就是固定 1080p 輸入、固定 640x640 模型輸入那就老老實(shí)實(shí)用靜態(tài) shape簡單又高效。然后是輸入輸出的內(nèi)存復(fù)用。很多新手寫的推理腳本會在每次循環(huán)里重新申請 Device 內(nèi)存推理完再釋放。這種做法在低幀率下問題不大但幀率一高內(nèi)存分配的開銷就非??捎^。我一般會一次性申請一塊足夠大的輸入 buffer 和輸出 buffer只在程序初始化時申請一次之后一直復(fù)用。這樣既減少了系統(tǒng)調(diào)用也避免了頻繁分配導(dǎo)致的碎片。如果你要跑多卡最簡單的方案不是在一個進(jìn)程里管理多塊卡而是多進(jìn)程每個進(jìn)程綁定一塊卡。通過環(huán)境變量 ASCEND_DEVICE_ID 或代碼里的 set_device 指定卡號互相之間不受影響。這種模式在部署上更好理解也更容易擴(kuò)展。4.3 和 GPU 部署的幾個關(guān)鍵差異昇騰部署和 GPU 部署最大的差異在生態(tài)工具和使用習(xí)慣。GPU 上有成熟的 CUDA、cuDNN、TensorRT社區(qū)資料多第三方庫齊全昇騰上雖然也有 CANN、MindIE、ModelBox 等一系列組件但整體成熟度和資料豐富度還有差距。這意味著你不能直接把網(wǎng)上的 GPU 教程往昇騰上套也不能期望每個 PyTorch 算子都能在昇騰上無痛運(yùn)行。另一個差異是調(diào)試體驗(yàn)。GPU 上出了錯可以輕易打印中間張量用 Nsight 做性能分析昇騰上雖然也能打印和 dump 數(shù)據(jù)但步驟相對繁瑣。所以我的習(xí)慣是在進(jìn)入昇騰流程之前先把模型在 CPU 或 GPU 上用 ONNX Runtime 驗(yàn)證一遍把模型本身的問題排除掉到了昇騰環(huán)節(jié)更多關(guān)注格式、shape、內(nèi)存這些工程問題。5. 這份方案能擴(kuò)展到什么程度5.1 從單機(jī)單卡到多卡多路Atlas 300V 24G 的 24GB 內(nèi)存決定了它的擴(kuò)展空間相當(dāng)可觀。單卡單模型跑 YOLOv5s 時內(nèi)存占用很小你可以在一張卡上同時加載檢測、分類、關(guān)鍵點(diǎn)等多個模型實(shí)例按照業(yè)務(wù)邏輯串聯(lián)起來。比如先檢測目標(biāo)再對目標(biāo)區(qū)域做分類這種多模型流水線在 24GB 內(nèi)存下完全可行。多卡場景下進(jìn)程綁卡的方案可以把業(yè)務(wù)水平擴(kuò)展。一個常見的架構(gòu)是視頻接入服務(wù)負(fù)責(zé)解碼然后把幀數(shù)據(jù)分發(fā)給多臺機(jī)器或多塊卡上的推理服務(wù)推理結(jié)果再統(tǒng)一匯總。這個架構(gòu)和 GPU 集群沒有本質(zhì)區(qū)別只是把每次推理替換成了昇騰的推理調(diào)用。5.2 其他能跑的模型YOLO 系列之外很多典型的視覺模型也可以遷移到昇騰上。YOLOX、YOLOv7、YOLOv8、RT-DETR、SSD、RetinaNet 這類目標(biāo)檢測模型只要訓(xùn)練時導(dǎo)出成 ONNX 再轉(zhuǎn) OM基本都能跑。分割模型比如 DeepLabV3 和 OCR 模型比如 PaddleOCR 的檢測和識別模型也有現(xiàn)成的落地案例。每一類模型第一次遷移時都要走一遍“導(dǎo)出 ONNX、驗(yàn)證精度、ATC 轉(zhuǎn)換、AscendCL 推理”的流程。第二遍、第三遍就會發(fā)現(xiàn)套路高度一致真正花時間的不是轉(zhuǎn)換本身而是預(yù)處理、后處理和性能調(diào)優(yōu)。5.3 哪些項(xiàng)目建議先遷移到 Atlas如果項(xiàng)目完全從零開始沒有歷史包袱推理場景和模型相對固定又對功耗和成本敏感那 Atlas 300V 是一個值得認(rèn)真考慮的選項(xiàng)。如果項(xiàng)目已經(jīng)有成熟的 GPU 推理服務(wù)短期內(nèi)沒有國產(chǎn)化要求我覺得不必急著遷移先用小流量試跑把算子兼容性、性能差異和運(yùn)維流程摸清楚再決定。還有一種情況非常適合 Atlas項(xiàng)目需要在很多臺設(shè)備上做分布式推理每一臺設(shè)備對功耗和體積都有嚴(yán)格要求。這一場景下Atlas 300V 這類半高半長、低功耗的推理卡比大塊頭的 GPU 靈活得多。最后再分享一個我在實(shí)際項(xiàng)目中反復(fù)驗(yàn)證過的小技巧模型轉(zhuǎn)換遇到不支持的算子時不要急著換模型結(jié)構(gòu)先回到模型導(dǎo)出的步驟用 onnx-simplifier 對 ONNX 做一次圖優(yōu)化。很多“算子不支持”的報錯本質(zhì)上是模型中殘留了一些冗余算子或不規(guī)范的圖結(jié)構(gòu)簡化之后就能正常通過 ATC 轉(zhuǎn)換。這個技巧在 YOLO 以外的模型上也一樣好用我后來幾乎每次遷移模型都會先跑一遍。