<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          嘮一嘮對(duì)AI煉丹師的模型部署的探索

          共 7465字,需瀏覽 15分鐘

           ·

          2023-04-28 13:27

          點(diǎn)擊下方卡片,關(guān)注「集智書(shū)童」公眾號(hào)

          點(diǎn)擊加入??「集智書(shū)童」交流群

          作者丨matrix明仔@知乎 來(lái)源丨h(huán)ttps://zhuanlan.zhihu.com/p/557709588 編輯丨小書(shū)童

          1、內(nèi)容介紹

          這期內(nèi)容是@走走大佬關(guān)于目標(biāo)檢測(cè)模型End to End推理方案的探索和嘗試。其實(shí)說(shuō)到推理和部署,其實(shí)怎么也繞不開(kāi)ONNX,ONNX在成立的初衷就是希望解決神經(jīng)網(wǎng)絡(luò)在不同的訓(xùn)練框架、推理框架上的轉(zhuǎn)換問(wèn)題。 所以本期的內(nèi)容會(huì)從如何玩轉(zhuǎn)ONNX出發(fā),嘮一嘮,我們?cè)谀繕?biāo)檢測(cè)部署遇到的那些事情。因?yàn)槠约坝胁糠謨?nèi)容我不太了解不敢亂說(shuō)的關(guān)系,我會(huì)在這里對(duì)開(kāi)放麥的內(nèi)容做一點(diǎn)順序和內(nèi)容上進(jìn)行一點(diǎn)的調(diào)整,我也會(huì)加入自己的一些經(jīng)歷和看法,讓大家看得更加輕松有趣一點(diǎn)。

          2、ONNX是什么,如何生成ONNX(ONNX簡(jiǎn)要的介紹)?

          預(yù)告:下面用三種方法向大家介紹如何生成Relu的ONNX模型,那么哪種方法才是最強(qiáng)的ONNX的生成方法呢?大家可以思考一下,我們繼續(xù)往下看~

          2.1、ONNX的組成

          ONNX的靜態(tài)圖主要由「Node」(節(jié)點(diǎn)),「Input」(輸入)和「initializer」(初始化器)但部分所組成的。

          • 節(jié)點(diǎn)就代表了神經(jīng)網(wǎng)絡(luò)模型一層的layer
          • 輸入代表了輸入矩陣的維度信息
          • 初始化器通常是存儲(chǔ)權(quán)重/權(quán)值的。
          • 每個(gè)組件元素都是hierarchical的結(jié)構(gòu),都是有著相互依賴關(guān)系的;
          • 這是一個(gè)雙向的鏈表。(Node、Graph彼此關(guān)聯(lián)有相互關(guān)系的);

          大家覺(jué)得難改,其實(shí)很大一部分也是因?yàn)镺NNX的結(jié)構(gòu),邊與邊是一個(gè)穩(wěn)定的結(jié)構(gòu)關(guān)系,彼此很大程度上是相互依賴的。所以我們具體要怎么轉(zhuǎn)化模型,怎么修改模型呢?我們接著看下去~

          2.2、Pytorch導(dǎo)出ONNX模型

          Pytorch是可以直接導(dǎo)出ONNX的模型,然后我們可以把導(dǎo)出的模型使用Netron的工具進(jìn)行可視化工具。

          d6bbd3bd2c357eb347f0d44841c4997b.webpPytorch -> ONNX

          2.3、Numpy出發(fā),揉一個(gè)數(shù)據(jù)結(jié)構(gòu)是可行嗎?

          ONNX可以在Pytorch,通過(guò)轉(zhuǎn)換得到。那么我們假如我們不用Pytorch上的轉(zhuǎn)換,從零開(kāi)始直接用Numpy人手揉一個(gè)ONNX模型是可行的嗎?答案是可行的。

          ONNX是用protobuf數(shù)據(jù)格式進(jìn)行保存的。而protobuf本身也是跨語(yǔ)言的可以支持C, C++, C#, Java, Javascript, Objective-C, PHP, Python, Ruby,使用ONN下的helper fuction就可以幫助我們順利的完成這些跨語(yǔ)言的轉(zhuǎn)變,所以Numpy也自然可以使用helper函數(shù)揉出輸入、節(jié)點(diǎn)以及初始化權(quán)值。

          2f9170906535d5ad68b677fd7b73234f.webp

          根據(jù)上圖展示的情況,可想而知要想實(shí)現(xiàn)一個(gè)能用的模型整體的代碼量是非常恐怖的。單一個(gè)Relu結(jié)構(gòu)的代碼量就要比Pytorch的轉(zhuǎn)化(最上面的圖)實(shí)現(xiàn)要多將近三倍左右。(其實(shí)最大的代碼量還是出現(xiàn)在輸入的數(shù)據(jù)類型轉(zhuǎn)化上)如果要實(shí)現(xiàn)一個(gè)完整的深度模型轉(zhuǎn)化,工作量可想而知,所以我們有沒(méi)有其他的更科學(xué)高效一點(diǎn)的做法呢?

          2.4、ONNX GraphSurgeon Basics

          如果我們從ONNX出發(fā)要修改ONNX,其實(shí)是一個(gè)比較復(fù)雜的過(guò)程。那自然我們就會(huì)思考,那如果直接ONNX轉(zhuǎn)ONNX困難的化,能不能借助點(diǎn)工具,也就是有沒(méi)有更好的IR(中間表達(dá))來(lái)幫助修改ONNX模型呢?

          沒(méi)錯(cuò)「TensorRT」就已經(jīng)做出來(lái)一套有效幫助Python用戶修改ONNX的工具GraphSurgeon(圖手術(shù)刀)

          這款I(lǐng)R主要有三部分組成

          • Tensor——分為兩個(gè)子類:變量和常量。
          • 節(jié)點(diǎn)——在圖中定義一個(gè)操作??梢苑湃魏蔚腜ython 原始類型(list、dict),也可以放Graph或者Tensor。
          • 圖表——包含零個(gè)或多個(gè)節(jié)點(diǎn)和輸入/輸出張量。

          目的就是為了更好的編輯ONNX

          0a1ab51ea8b17c43074c7ab9d8055026.webpONNX GraphSurgeon轉(zhuǎn)化Relu結(jié)構(gòu)

          有了輸入,再使用圖手術(shù)刀對(duì)模型的結(jié)構(gòu)進(jìn)行組合,最后完成了Relu在ONNX上的轉(zhuǎn)化。

          3、如何在 ONNX 上進(jìn)行圖手術(shù)

          因?yàn)镺NNX本身是一種hierarchical的設(shè)計(jì),這種其實(shí)就是一種經(jīng)典的計(jì)算機(jī)思路。當(dāng)我們打算動(dòng)其中一層的時(shí)候,因?yàn)樯舷掠蔚年P(guān)聯(lián),下游的框架也會(huì)跟著被修改。

          3.1、ONNX的IR,我們需要一個(gè)友好的中間表達(dá)!

          比如在目標(biāo)檢測(cè)的場(chǎng)景中,我們有兩種數(shù)據(jù)標(biāo)注表達(dá)「txt」「mscoco」。如果是一個(gè)區(qū)分train集和val集的工作的話,txt直接把標(biāo)簽隨機(jī)分開(kāi)兩組就行。但是在coco數(shù)據(jù)集上,如果需要?jiǎng)澐講al集的時(shí)候,就要對(duì)json格式進(jìn)行劃分,還需要遵循一個(gè)圖片和標(biāo)注信息一一對(duì)應(yīng)的關(guān)系,就會(huì)更加復(fù)雜。那ONNX的轉(zhuǎn)化也是同理,所以理論上為了簡(jiǎn)便這個(gè)整個(gè)修改的工程,我們需要一個(gè)IR工具的一個(gè)中間表達(dá)來(lái)幫助我們進(jìn)行修改。

          3.2、GraphSurgeon IR

          提供了豐富的API來(lái)幫我們進(jìn)行表達(dá)。

          沒(méi)有邊的信息,邊的信息存在了輸入輸出中,所以O(shè)NNX需要對(duì)模型的信息進(jìn)行拓?fù)渑判?。平時(shí)的手,我們?cè)谑褂肞ytorch導(dǎo)出ONNX模型的時(shí)候會(huì)發(fā)現(xiàn)有孤立的節(jié)點(diǎn)。如果對(duì)這個(gè)模型進(jìn)行拓?fù)渑判虻脑?,?huì)發(fā)現(xiàn)這個(gè)孤立算子是沒(méi)有意義的,應(yīng)該是需要處理掉這個(gè)冗余的算子。

          3.3、TorchScript (具體的使用)

          首先Pytorch是一個(gè)動(dòng)態(tài)圖,我們需要把Pytorch轉(zhuǎn)變?yōu)镺NNX的靜態(tài)圖!

          Torchscript模式主要分為T(mén)racing和Script,區(qū)分是用「Tracing」還是「Script」,主要是看是否是動(dòng)態(tài)流。

          Tracing會(huì)從頭到腳執(zhí)行一遍,記錄下來(lái)所有的函數(shù)

          如果遇到動(dòng)態(tài)控制流「(if-else)Script」 會(huì)走其中的一條,執(zhí)行哪條就會(huì)記錄哪條,另一條就會(huì)忽略。并且Script對(duì)不同大小的輸入有效。

          「一般都建議Trace,因?yàn)槌薕NNX_runtime,別的都不會(huì)人if這個(gè)動(dòng)態(tài)算子?!?/strong>

          3.4、Symbolic

          某些情況下,幫助模型在端側(cè)落地,在轉(zhuǎn)換后也能夠達(dá)到很好的效果。Python語(yǔ)言和c++本質(zhì)上不一致,找到所以還是希望找到一種方式可以直接轉(zhuǎn)換,不用自己再手動(dòng)寫(xiě)C++算子,這算是一件很棒的事情。

          92f42ac2260980bfd61e466aeea16342.webp

          NMS_F是一個(gè)很平常的一個(gè)算子,在上圖的實(shí)現(xiàn)。如果我們用Symbolic的函數(shù)會(huì)直接轉(zhuǎn)出,整個(gè)后處理都可以用ONNX轉(zhuǎn)出來(lái),但是這種方法

          3.5、ONNX GraphSurgeon

          272bfff38c976bc1cdb5b62876d70e9d.webp

          如何把上面的結(jié)構(gòu)轉(zhuǎn)換為下面的結(jié)構(gòu),大概需要做到是吧x0的輸入分支給去掉,然后再加入LeakyReLU和Identity的節(jié)點(diǎn),最后完成輸出。

          1. 先找到add的算子,把a(bǔ)dd的名字改成LeakyReLU

          2. 補(bǔ)充attribute屬性,加入alpha

          3. 指定一個(gè)輸出屬性identuty_out

          4. 然后再把identity節(jié)點(diǎn)加入到結(jié)構(gòu)當(dāng)中

          5. 先clean一些,再進(jìn)行拓?fù)渑判颉?/p>

          5ee71e348379d886927f4837b1bf3fdf.webp操作的代碼展示

          這個(gè)任務(wù)其實(shí)也可以用ONNX原生的IR來(lái)做,但是原生IR沒(méi)有太多的幫助函數(shù),很多工具鏈還是不太完善的,所以還是建議使用ONNX GraphSurgeon,因?yàn)橛迷腎R的代碼量一頁(yè)肯定是寫(xiě)不完的了。

          3.6、torch.fx

          因?yàn)檫@塊沒(méi)有聽(tīng)太懂,所以就直接簡(jiǎn)單的吹一些沒(méi)啥用的,大家可以放松一下看看!

          從以前的量化進(jìn)化到現(xiàn)在也能涉及一部分的圖手術(shù)。其實(shí)為了能夠在python上也能進(jìn)行圖手術(shù)上,在symbolic tracer的底層上也做了很多不一樣的工作,但是在轉(zhuǎn)化過(guò)程中也是有很多坑的,但是因?yàn)镻ython-to-Python會(huì)更加有利于模型訓(xùn)練師的開(kāi)發(fā),Pytorch的工程師也正在繼續(xù)發(fā)展,「正在逐步舍棄TorchScript」。

          利用torch.fx+ONNX做量化可以極大的節(jié)省代碼量,是一個(gè)很棒的工作。

          86a346a7e332a8b418d2968f244fa5dd.webp

          4、Focus模塊替換(部署的技巧)

          Focus在yolov5提出來(lái)的!

          Focus包括了兩部分組成「Space2Depth + Conv3」。有一點(diǎn)值得注意的是,F(xiàn)ocus在實(shí)現(xiàn)過(guò)程focus_transform中會(huì)用到Slice的動(dòng)態(tài)的操作,而這種動(dòng)態(tài)的操作在部署的時(shí)候往往是會(huì)出大問(wèn)題的。但是有意思的一點(diǎn)是,Space2Depth和Pytorch中的nn.PixelUnShuffle物理意義是一致的,但是實(shí)現(xiàn)的過(guò)程卻有點(diǎn)不太相同,這也是這一版本YoloV5比較坑的點(diǎn)。

          但是實(shí)現(xiàn)上一般有 CRD/DCR mode 方式, 由排列順序決定, focus的實(shí)現(xiàn)跟這兩種常用的mode 均不一致

          「nn.PixelUnShuffle」是我們分割任務(wù)的老朋友了,在這里的出現(xiàn),其更多的是在說(shuō)明,其實(shí)下游任務(wù)正常逐步的進(jìn)行一個(gè)統(tǒng)一和兼容。FPN到現(xiàn)在也轉(zhuǎn)變?yōu)镻AN,這樣的轉(zhuǎn)變也說(shuō)明了很多。

          08dcb7041b173d4f2eadc176e1c309c3.webp48c33240f2b7fa508f8a324396ce6cca.webp

          仔細(xì)看看右邊的Focus2的內(nèi)容,其實(shí)只是一個(gè)reshape+conv+reshape的操作,這在雖然物理含義上是Space2Depth,但是與ONNX和Pytorch對(duì)應(yīng)的實(shí)現(xiàn)都是不一致的。

          mmdepoly有提供一系列的轉(zhuǎn)換,可以幫助我們更好的解釋這一點(diǎn),大家可以看看。

          在yolov5-6.0的時(shí)候已經(jīng)沒(méi)有人再使用Focus,這個(gè)操作也被替換成了一個(gè)6x6的卷積操作了。

          再到現(xiàn)在6x6的卷積會(huì)轉(zhuǎn)換為3x3的卷積拼接出來(lái),這樣會(huì)讓整體的推理速度會(huì)更快。

          4.1、Torch.FX對(duì)Focus進(jìn)行替換

          6a252812c8a905148ad328cbc5cbe8c5.webp

          主要是用自己的卷積的實(shí)現(xiàn)替換focus_transform和Focus的實(shí)現(xiàn)。把中間層展開(kāi)來(lái)看的,就可以發(fā)現(xiàn)還需要自己手寫(xiě)去補(bǔ)充buffer的算子。

          一個(gè)比較新的圖手術(shù)的方法,大家可以看一看,代碼量也不是很大。

          5、給目標(biāo)檢測(cè)網(wǎng)絡(luò)插入EfficientNMS結(jié)構(gòu)(如何做后處理會(huì)更加的高效?。?/span>

          其實(shí)EfficientNMS是trt8.0的一個(gè)插件,以前是BatchedNMS,這個(gè)操作還沒(méi)有手寫(xiě)的插件快。

          下面就展開(kāi)的講講EfficientNMS。

          EfficientNMS原本是來(lái)自谷歌的EfficientDet 來(lái)的,能提速,而且與BatchedNMS一致,這么好用,我們?yōu)樯恫挥媚兀?/p>

          Yolo系列中,卷積后會(huì)加一個(gè)Box的解碼,最后再加上NMS的操作。Box解碼需要我們?nèi)ブ攸c(diǎn)的優(yōu)化,如果想要在C++實(shí)現(xiàn),就要自己手寫(xiě)一個(gè)實(shí)現(xiàn)。但是在我們的實(shí)現(xiàn)中,我們會(huì)更多的加速方法,這里就不展開(kāi)說(shuō)了。但是總的來(lái)說(shuō)現(xiàn)在的新版本的Yolo都基本都固定了前處理跟NMS部分,卷積部分和編解碼一直在變,不過(guò)現(xiàn)在也基本被RepVGG統(tǒng)治了。

          07c5d1e8572502ccff3c8d17b1759bfb.webp

          大家也可以看看上面實(shí)現(xiàn)的yolov7后處理的方法。這是一個(gè)日本的一個(gè)項(xiàng)目實(shí)現(xiàn)出的一個(gè)整體的結(jié)構(gòu),我們其實(shí)也還有另一種方式可以用pytorch+onnx直接拼出來(lái)這樣一個(gè)graph出來(lái)的。主要還是為了解決這種動(dòng)態(tài)性,轉(zhuǎn)化為靜態(tài)去部署。

          6、小小的概括一下

          「EfficientNMS」該插件主要用于在 「TensorRT」 上與 「EfficientDet」 一起使用,因?yàn)檫@個(gè)網(wǎng)絡(luò)對(duì)引入的延遲特別敏感較慢的 NMS 實(shí)現(xiàn)。 但是,該插件對(duì)于其他檢測(cè)架構(gòu)也足夠的適用,例如 SSD 或Faster RCNN。

          1. 標(biāo)準(zhǔn) NMS 模式:僅給出兩個(gè)輸入張量,

          (1)邊界框坐標(biāo)和

          (2)和每個(gè)Box的對(duì)應(yīng)的分?jǐn)?shù)。

          1. 融合盒解碼器模式:給出三個(gè)輸入張量,

          (1)原始每個(gè)盒子的定位預(yù)測(cè)直接來(lái)自網(wǎng)絡(luò)的定位頭,

          (2)相應(yīng)的分類來(lái)自網(wǎng)絡(luò)分類頭的分?jǐn)?shù)

          (3)認(rèn)錨框坐標(biāo)通常硬編碼為網(wǎng)絡(luò)中的常數(shù)張量

          7、項(xiàng)目的實(shí)驗(yàn)結(jié)果

          這里的實(shí)驗(yàn)結(jié)果大家可以看一看,這里值得注意的是居然時(shí)間要比以前沒(méi)有加操作的結(jié)構(gòu)要快。其實(shí)主要原因是沒(méi)有把后處理的時(shí)間給加上,顯然這樣的快就沒(méi)有啥意義。大家要記得對(duì)比后處理的時(shí)間,如果不對(duì)比這樣的比較是不公平的,也不具有啥意義!

          7cbfc15cb15dd52e20b675430f86d1d3.webp

          8、總結(jié)

          感覺(jué)這個(gè)筆記還是沒(méi)有記錄得很到位,因?yàn)橛行┬畔⒋_實(shí)也是我的盲區(qū),但是整個(gè)講解過(guò)程,其實(shí)巨棒,我這里小小一篇雜談,其實(shí)還不足以記錄這么多內(nèi)容,建議大家去看看開(kāi)放麥的錄播,以及去了解YOLORT和MMDeploy的代碼哦~!

          https://link.zhihu.com/?target=https%3A//github.com/zhiqwang/yolov5-rt-stack

          https://link.zhihu.com/?target=https%3A//github.com/open-mmlab/mmdeploy

          c74d84bd8365e61cf2fcb63b058145ec.webp afd1184e09ad0cdf26db7fcf5896e6ae.webp

          小目標(biāo)檢測(cè)技巧 | 全局上下文自適應(yīng)稀疏卷積CEASA | 助力微小目標(biāo)檢測(cè)漲點(diǎn)


          f7cab0b32cd0ae2416060925743b183f.webp

          車道線模型落地技巧 | LGAD注意力蒸餾讓模型更魯棒


          1b18a271e2bb1df2fc0ca5e2a6680dc9.webp

          目標(biāo)檢測(cè)落地必備Trick | 結(jié)構(gòu)化知識(shí)蒸餾讓RetinaNet再漲4個(gè)點(diǎn)


          掃碼加入??「集智書(shū)童」交流群

          (備注: 方向+學(xué)校/公司+昵稱

          e83f407f7633b606e30a979e1628741b.webpf7b28a4879b8bb65ad4f81906f4d6d40.webp

          18fd6a756a0ae7f9b5e5dbaf9235a80c.webp7b5f73bc58a89fbd25808010a90f67f8.webp想要了解更多:

          前沿AI視覺(jué)感知全棧知識(shí)??「分類、檢測(cè)、分割、關(guān)鍵點(diǎn)、車道線檢測(cè)、3D視覺(jué)(分割、檢測(cè))、多模態(tài)、目標(biāo)跟蹤、NerF

          行業(yè)技術(shù)方案??AI安防、AI醫(yī)療、AI自動(dòng)駕駛 AI模型部署落地實(shí)戰(zhàn)??CUDA、TensorRT、NCNN、OpenVINO、MNN、ONNXRuntime以及地平線框架」

          歡迎掃描上方二維碼,加入集智書(shū)童-知識(shí)星球,日常分享論文、學(xué)習(xí)筆記、問(wèn)題解決方案、部署方案以及全棧式答疑,期待交流!

          免責(zé)聲明 凡本公眾號(hào)注明“來(lái)源:XXX(非集智書(shū)童)”的作品,均轉(zhuǎn)載自其它媒體,版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系我們刪除,謝謝。
          點(diǎn)擊下方“閱讀原文”, 了解更多AI學(xué)習(xí)路上的 「武功秘籍」
          瀏覽 132
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  北条麻妃中文字幕在线 | 娇小小小泬BBB亚洲 | 天堂网www啊啊啊啊啊啊 | 国产无码免费在线 | 3344gc在线观看免费下载视频 |