視覺算法的工業(yè)部署及落地方面的技術(shù)知識,怎么學(xué)?
點擊下方卡片,關(guān)注“新機器視覺”公眾號
重磅干貨,第一時間送達
編輯:深度學(xué)習(xí)技術(shù)前沿
【導(dǎo)讀】目前人工智能技術(shù)在工業(yè)視覺領(lǐng)域的應(yīng)用逐漸火熱起來,但是高校關(guān)于具體算法的工業(yè)場景應(yīng)用的技術(shù)卻涉及較少,那么如何快速的學(xué)習(xí)以及成功地將視覺算法應(yīng)用到工業(yè)實際場景并完成模型的部署等一系列工作呢?本文整合了知乎上的優(yōu)秀回答,希望能幫助到大家!
作者:OLDPAN
鏈接:https://www.zhihu.com/question/428800593/answer/1560898134
來源:知乎
一看這個題目的關(guān)鍵字“部署”和“落地”就深深吸引到了我 。想想當(dāng)年(去年)秋招,神仙打架諸神黃昏的CV崗,大神們的簡歷上都是充滿頂會比賽top1等等,我不擅長算法(雖然我是算法工程師),簡歷上也就只能簡單水水top10的比賽,寫一些水水的項目。唯一感覺和大佬們簡歷稍微不同的也就落地和部署這塊了??戳饲懊鎺孜淮罄械幕卮?,感觸頗深,所以我也來簡單聊聊(大部分其他回答已經(jīng)說了,我再補充些吧)。
個人認為算法部署落地這個方向是比較踏實務(wù)實的方向,相比“設(shè)計模型提出新算法”,對于咱們這種并不天賦異稟來說,只要你肯付出,收獲是肯定有的(不像設(shè)計模型,那些巧妙的結(jié)果設(shè)計不出來就是設(shè)計不出來你氣不氣)。其實算法部署也算是開發(fā)了,不僅需要和訓(xùn)練好的模型打交道,有時候也會干一些粗活累活(也就是dirty work),自己用C++、cuda寫算子(預(yù)處理、op、后處理等等)去實現(xiàn)一些獨特的算子。算法部署最常用的語言是啥,當(dāng)然是C++了,C++雖然復(fù)雜,但是由于優(yōu)異的性能和各種特性(類對象、元編程等),被很多推理框架作為backbone的語言。
如果你想要自學(xué)但不知道學(xué)哪個,無從下手,哈哈恭喜你和當(dāng)初的我一毛一樣。不過你現(xiàn)在要是問,我還是不知道應(yīng)該跟你怎么說,因為部署落地這方面你需要學(xué)習(xí)需要做的事情還是蠻多的。最好還是以項目作為驅(qū)動,或者找一些開源的推理部署框架練練手,找一兩個開源項目玩玩,找找感覺,自己也就逐漸有方向了。
前面幾位大佬提到的NCNN(優(yōu)秀)、MNN(牛逼)等框架(還有很多框架這里不一一列舉了額),是針對移動端進行部署進行優(yōu)化的推理引擎,對ARM核進行了優(yōu)化,如果你想做和移動端或者嵌入式端有關(guān)系的,可以看看這兩個框架的源碼,跑一兩個demo找找感覺,另外還有Openvino和TensorRT,分別是對應(yīng)cpu和gpu端的首推框架(想詳細了解可以參考我之前的文章),可以找相關(guān)的項目去做做。
部署的流程一般就是:
訓(xùn)練一個模型,也可以是拿一個別人訓(xùn)練好的模型
針對不同平臺生成的模型進行轉(zhuǎn)換,也就是俗稱的parse、convert,前端解釋器
針對轉(zhuǎn)化后的模型進行優(yōu)化,這一步很重要,涉及到很多優(yōu)化的步驟
將轉(zhuǎn)化好的模型運行在特定的平臺(嵌入端或者服務(wù)端)
需要掌握什么技術(shù),學(xué)好C++很重要,起碼能看懂各種關(guān)于部署精巧設(shè)計的框架(再列一遍:Caffe、libtorch、ncnn、mnn、tvm、openvino、tensorrt,不完全統(tǒng)計,我就列過我用過的)。當(dāng)然并行計算編程語言也可以學(xué)一個,針對不同的平臺而不同,可以先學(xué)學(xué)cuda,資料更多一些,熟悉熟悉并行計算的原理,對以后學(xué)習(xí)其他并行語言都有幫助。
部署和落地的重要性...當(dāng)然是很重要呃,對于硬件公司來說,需要將深度學(xué)習(xí)算法部署到性能低到離譜的開發(fā)板上,因為成本能省就省,這時就需要部署了。在算法層面優(yōu)化模型是一方面,但更重要的是從底層優(yōu)化這個模型,這就涉及到部署落地方面的各個知識(手寫匯編算子加速、算子融合等等);對于軟件公司來說,我們往往需要將算法運行到服務(wù)器上,當(dāng)然服務(wù)器可以是布滿2080TI的高性能CPU機器,但是如果QPS請求足夠高的話,需要的服務(wù)器數(shù)量也是相當(dāng)之大的。這個要緊關(guān)頭,如果我們的模型運行的足夠快...可以省機器又可以騰一些buffer上新模型豈不很爽,這個時候也就需要優(yōu)化模型了,其實優(yōu)化手段也都差不多,只不過平臺從arm等嵌入式端變?yōu)間pu等桌面端了。
系統(tǒng)的知識嘛,有是有,不過實際中都是用到啥再看啥,有項目在push你,個人建議直接上手項目,沒有自己找找,按需學(xué)習(xí)。
這里簡單總結(jié)下可以選擇上手:
好用的開源推理框架:caffe NCNN、MNN、TVM
好用的開源推理框架:Openvino、TensorRT(infer不開源)
好用的開源服務(wù)器框架:triton-server
好用又不好用的編程語言:C++、CUDA、python
基礎(chǔ)知識:計算機原理 編譯原理等
作者:幻想家皮霸霸丶
鏈接:https://www.zhihu.com/question/428800593/answer/1560594742
來源:知乎
本人是20屆的渣渣碩士,剛剛上研的時候,和大多數(shù)“內(nèi)卷兒”一樣,我也很幸運被老板安排了“計算機視覺&圖像處理&模式識別”的研究方向。屁顛屁顛的開始看cvpr,iccv的paper?;叵肫疬^去,那時的我年幼無知,在地平線的一臺四卡服務(wù)器上非root權(quán)限一步一步的裝好了caffe,開始跑起來了openpose的訓(xùn)練,原本以為我的煉丹生涯就這樣正式開始了,沒想到怎么都復(fù)現(xiàn)不到paper上的精度,當(dāng)時對multi-scale的測試看半天還不懂怎么回事。經(jīng)常被leader push進度,真心覺得自己菜得扣腳,很多時候都想放棄煉丹。一步一步,在工業(yè)界,從單幀圖像上的目標檢測,語義分割,實例分割,到人體姿態(tài)估計。再遷移到視頻上的目標檢測,語義分割,關(guān)鍵點檢測。以及最后畢業(yè)論文的多目標跟蹤。算是把整個工業(yè)界能用的cv模型都摸了一遍,領(lǐng)域內(nèi)的經(jīng)典paper也能做到信手拈來?起碼,各種開源的檢測框架(商湯的mmdet, Facebook 最早的mask rcnn,detectron1 (caffe2), detectron2 (pytorch), gluonCV)都用過并完成了自定義的項目,其中的源碼也都是“隨心”看過一遍,但是自己太蠢了,寫不到這個水平的python和cuda代碼,以及每次用完,對很多細節(jié)的設(shè)計只能感慨作者的牛逼。
2018年:一個偶然的機會,我開始看mxnet的源碼(當(dāng)時還是使用的symbol接口),看著看著,覺得這玩意和caffe代碼好像,很多地方都是從caffe那里復(fù)用的,設(shè)計也比caffe靈活不少,畢竟粒度更細,安裝也更加友好。我一步一步的學(xué)習(xí)mxnet官網(wǎng)上放出來的所有有關(guān)framework設(shè)計的知識,包括從“怎樣設(shè)計一個高效的data loader”,“怎么樣設(shè)計一個engine把框架中的所有組件schedule起來”,“以及怎么樣更好的優(yōu)化memory和減少數(shù)據(jù)IO”,“包括怎么樣設(shè)計一套面向任何等級用戶都友好的API”。原本以為自己掌握了設(shè)計DL framework的大體奧義,發(fā)現(xiàn)還是想太多了,在面對讓自己從頭實現(xiàn)一個框架的時候,我也只會用python定義class 包來包去,性能什么的就別說了,我的菜還是沒辦法改變,最終還是想自己的愚蠢低下了頭。。。
2019年:又一個偶然的機會,我開始在大洋彼岸某個村的CSL做summer research,項目的需求是為他們實驗室的一款深度學(xué)習(xí)編譯器(target為fpga)去寫一套opencl的backend。什么是編譯器?什么是backend?什么是fpga?什么是opencl?一連串的問題對傻逼的我來說,一切都是未知。扒開這套編譯器的codebase,我發(fā)現(xiàn)大部分代碼都是從tvm那里借鑒來的, 于是,我又走上了tvm的學(xué)習(xí)之路,從tvm的design到完整的編譯flow,包括底層的c++到與上層的python交互,以及autoTVM(那會Ansor還沒出來)全部走了一遍。對于一個根本沒玩過硬件開發(fā)板的我,這一切在當(dāng)時來看是非常困難的,還好實驗室有給力的Ph.D.們,在他們的配合下,我也成功把基于xilinx和intel fpga的opencl backend全部添加了上去。那會的我,覺得自己算是掌握了 編譯器的大體奧義。可最終我還是想自己的傻逼低下了頭,涉及到傳統(tǒng)編譯器中的llvm的設(shè)計,codegen的很多細節(jié),我還是一無所知。。?;貒?,又加入了某條的mlsys組繼續(xù)做編譯器,我隨后又在glow的基礎(chǔ)上,為硬件組的自研芯片MVP開發(fā)profile-guided的quantization工具鏈以及針對網(wǎng)絡(luò)的每個layer開發(fā)了方便debug的可視化工具。
2020年:又又一個偶然的機會,被安排到了一家創(chuàng)業(yè)公司做intern,剛剛?cè)肼毜谝惶炀鸵笤?080ti上去優(yōu)化一個超分4k視頻。對于一行cuda代碼都沒寫過的我來說,那是不敢想象的,項目負責(zé)人每兩天催一次進度,連給我配tensorRT,學(xué)習(xí)如何寫高性能cuda代碼的機會都不給。我每天都活在自責(zé)與痛苦中,為什么我這么菜?這么垃圾啊?待我整完了從pytorch模型到onnx模型轉(zhuǎn)換,再到trt的編譯,以及為各種不支持的operator寫完tensorRT的plugin,再到關(guān)于image的前后處理全部手寫cuda kernel去和opencv硬碰硬。遺憾的是,整個inference還是沒有跑起來,當(dāng)我用盡了我當(dāng)時力所能及的cuda的debug工具(cuda-gdb,cuda-memcheck,...)最終發(fā)現(xiàn)還是敗在了模型的多張幀輸入沒辦法做到CPU和GPU上的memory 對齊。就這次偶然的機會,我竟然學(xué)會了tensorRT的部署。仗著這個經(jīng)驗,我又把組里其他模型:OCR,簡化版超清視頻到TX2,NX,AGX,智能相機等設(shè)備上,用盡了各種能優(yōu)化的框架ncnn,mnn (其中包括針對工業(yè)級的二階段的OCR模型,det用tensorRT,reg用mnn的vulkan后端聯(lián)合開多線程優(yōu)化在TX2上達到real-time)也熟悉了很多不同的backend和指令集架構(gòu)。原本以為,我已經(jīng)掌握了深度學(xué)習(xí)CV模型落地的要領(lǐng),直到這幾天接到了要在華為的atlas 500板子上部署算法團隊自己整的一套faster rcnn的二階段檢測模型以及tracking,幾乎所有套件都要從頭開始手寫c++(借助FFmpeg對RTSP拉流,解碼,udp報文傳送,前處理,rpn生成proposals,proposal變anchor,anchor到bbox,kalman filter, hungary, track ID篩選 ...),我才發(fā)現(xiàn)自己的無知,模型部署真的是個大坑。
以上內(nèi)容吹逼歸吹逼,且當(dāng)個故事聽聽就好。
其實我想表達的是 視覺算法的工業(yè)部署和落地是沒有你想得那么容易的,dirty work(手寫c++, cuda各種前后處理) 全靠你對于上層模型算法的理解,以及不同hardware backend設(shè)計的深刻認知。如果要利用編譯技術(shù),你又得對深度學(xué)習(xí)編譯器中如何在design space中搜optim的值和手寫template來達到半自動優(yōu)化有很好的掌握,你才能真正把一個paper里吹的“天花亂墜”的model部署到一個理論算力能跟得上的設(shè)備上( 當(dāng)然,real-time和power是很重要的指標)
從工業(yè)界的角度想要快速出活,真正要自學(xué)的話:
深度學(xué)習(xí)框架方面,讀一讀caffe的源碼和設(shè)計理念,看看其中的cpu/gpu上的op是怎么寫的。
深度學(xué)習(xí)編譯器方面,讀一讀tvm的源碼和設(shè)計理念,看看編譯器是怎么把一個dl model經(jīng)過relay IR 再到 tvm IR,再到不同backend的codegen。以及編譯器對計算圖的常見優(yōu)化(算子融合,data layout等)
深度學(xué)習(xí)模型部署方面,針對nvidia的gpu,看看cuda,tensorRT的document,自己嘗試著把一個檢測或者分割的模型部署到實驗室的機器上。針對移動端的cpu,gpu,看看mnn,學(xué)習(xí)下mnn的code design。很多非常好的profiling,可視化工具。針對fpga設(shè)備,可以看看hls,opencl,verilog。畢竟直接拿現(xiàn)成的tool把model中的op翻譯成hls,opencl代碼還不是非常高效,很多東西還是直接寫HDL所帶來的speed up才更直接。這就和很多時候在arm架構(gòu)的cpu上去優(yōu)化算法,直接手寫匯編所帶來的提升更加直接
從提升自己內(nèi)功的角度來看,認真啃好:“編譯器,計算機體系結(jié)構(gòu),并行計算,
編程語言設(shè)計,計算機系統(tǒng),計算機網(wǎng)絡(luò),C++程序設(shè)計” 來說是更好不過了。
當(dāng)然,一切的一切都得來源于你對上層DL算法都有了深入了解,知道每個layer是怎么跑的,輸入的feature和輸出的feature都是怎么存的,軟件和算法層面都經(jīng)歷過怎樣的加速,還有哪些加速是需要結(jié)合hardware來進行co-design的,你才能更好地把模型中的不同layer合理高效地部署到不同的hardware上。
給個結(jié)論:如果要真正想習(xí)得視覺算法的部署和落地,最快捷的方法,首先你需要有一個極為嚴格經(jīng)常push你并且還活躍在代碼一線的leader,然后還得有一個特定的業(yè)務(wù)場景和急迫的ddl。
本文僅做學(xué)術(shù)分享,如有侵權(quán),請聯(lián)系刪文。
