主講人 | 何琨 英偉達
陳銘林 編輯整理
量子位編輯 | 公眾號 QbitAI
近日,愛奇藝技術沙龍“多模態(tài)視頻人物識別的關鍵技術及應用”成功舉辦,英偉達開發(fā)者社區(qū)經理何琨出席并作出精彩分享,以下為分享實錄:
今天,我給大家介紹兩個工具,分別是DeepStream和TensorRT。我想給大家介紹這兩個工具,并不是因為它們是針對于特定的產品或場景,而是因為這兩個工具真正能在視覺領域幫助大家加速一些任務或者應用程序。
DeepStream
深度學習應用在很多領域,如視覺、語音、NLP等,有各種各樣的學習框架,在深度學習框架底層,NVIDIA提供了大量的硬件以及相關的軟件庫的支持,包括cuDNN、DeepStream、TensorRT、cuBLAS等基礎庫,這些庫都是讓程序運行起來更快的基礎生態(tài)工具。
DeepStream是基于NVIDIA運行的工具,它主要應用于視覺整個流程的解決方案,它跟其他視覺庫(比如OpenCV)不一樣的地方在于,它建立一個完整的端到端的支持方案,換句話說你的源無論是Camera、Video還是云服務器上的視頻,從視頻的編解碼到后臺的圖像Inference再到展示出來的畫面的完整pipeline上的各個細節(jié)它都能幫助大家,包括參數的設置。
在這個過程中,大家只需要加上自己的內容。比如視頻檢索,我們需要train出一個model來識別或檢測其中的人臉,將這幾個不同model添加到里面就好了。而視頻源的設置完整流程DeepStream都可以幫你做好,包括記錄的視頻、服務器上多路視頻。
在這過程中,DeepStream是如何去做的?我們可以看到,從最開始的視頻的編解碼,到整個流程地完成,這個過程中有兩個東西是最重要的,一個是Gstreamer編解碼工具,一個是TensorRT工具。在AI中它是一個加速GPU的推理引擎。DeepStream中,視頻的編解碼就是依靠Gstreamer,而內容的Inference過程中就用TensorRT來實現(xiàn)的。
可以看到每一個模塊是用什么樣的硬件設備來跑的,因為有一些可能還用到了CPU,但更多用到GPU的加速。特別地,有些情況下我們需要在計算能力有限的設備上,如小尺寸的GPU設備、無人機或者自動駕駛汽車等,我們需要加速一個完整的流程時,DeepStream也可以幫助我們這樣的事。
DeepStream現(xiàn)在支持NVIDIA的Xavier系列、Tegra系列和最新出的Nano系列等產品,在這個過程中用一些GPU調度的情況下,比傳統(tǒng)視覺庫的加速效果要好很多。
舉兩個例子,現(xiàn)在跑的是一個大家耳熟能詳的模型,就是Yolo v3的,它跑在我們的Tegra的產品上,只有不到半個手掌大的計算芯片設備,我做了一個目標檢測任務,前提是Batch Size我都設為了1,因為在那樣Memory的情況下,如果Batch Size設為更多,比如2或者4的話,如果不用DeepStream的話它是跑不了的,Out of Memory了。
我們可以看一下左上角,這個是沒有用DeepStream和TensorRT產品來優(yōu)化的,結果是大概一幀一秒的過程。而右下角使用了TensorRT或DeepStream來做優(yōu)化,大概是四點多的范圍。
就是說在相同的一個算法上,我們在Batch Size都設置為1的情況下,速度提升比大概是四倍,這種情況下,我們不需要做任何的優(yōu)化,不需要修改網絡模型,不需要改數量級,只需要把模型給到DeepStream或者TensorRT就可以做速度加速比。
GitHub上有一個非常好的開源代碼,利用DeepStream在GPU上進行加速的一個案例,推薦給大家:https://github.com/vat-nvidia/deepstream-plugins。
DeepStream還支持一些新的特性。比如一個服務器上要接很多路攝像頭,這種情況要接很多路Pipeline。比如汽車上,在停車的時候需要啟用后端的攝像頭,這時需要Create新的Pipeline;在自動行駛的過程中,為了避撞,汽車兩邊的攝像頭的精度需要更多的關注,這時DeepStream會自動管理或刪減Pipeline。當然還根據自動駕駛提供的360度攝像頭全景拼接,在需要使用的時候直接include庫就可以了,非常簡單方便。
TensorRT
說到DeepStream,除了視頻的編解碼以外,最核心的內容就是推理工具,推理是深度學習真正把模型部署到產品中非常重要的一部分。DeepStream的底層推理任務基于TensorRT,核心任務是GPU推理引擎。它是一種高性能深度學習推理優(yōu)化器和運行時加速庫,調用的時候直接include,可以優(yōu)化神經網絡模型以及其他功能。
后面畫出這些圖表是TensorRT當前的Performance一個優(yōu)化的程度,這個是4.0版本,最新數值還要更高。我們什么都不需要做,只要用這個工具來Inference這個模型就OK了,可以達到這樣一個高度。
而隨著最新的TensorRT 5.0的推出,對于python的支持,對于NLP、RNN等基于時間序列的模型的支持也都非常好,特別是還有基于移動端類似于無人機、無人車等平臺。
TensorRT有一個標準的Work Flow,給它一個訓練好的網絡模型(包括網絡結構、權重參數),它會自動進行優(yōu)化,而在這個優(yōu)化完成后會生成一個可執(zhí)行的推理引擎,只要把需要推理的數據實例,如圖片、語音信息、文字等內容直接給它,它就可以加速你的模型推理。
而在模型推理過程中,我們需要它自動做這五件事:
第一個是權重參數類型的優(yōu)化,比如目前半精度和八位整形的推理,如果當數據的大小或位寬減少之后,數據傳輸、計算、配合最新的Tensor Core等硬件結構做推理時,整體速度會提升很多。
接下來是動態(tài)的Tensor Memory。做視覺的同學應該都接觸過GPU,GPU里邊有很多l(xiāng)evel級的 Memory,Global Memory、Share Memory等,如何把數據從低速度帶寬到一個高精度的Memory,這些TensorRT都可以做到。
接下來是多流的執(zhí)行。GPU最大的特點是并行計算,并行計算一個新的Level,除了不同的多個線程、Block以外,還有不同的Stream,多流的執(zhí)行可以幫你隱藏數據傳輸的時間。例如把一個大塊數據放到GPU里進行inference時,數據傳輸時所有的計算核心都需要等待,等待的時間就浪費了,或者GPU的使用率降低。
這個時候我們要把一大塊數據切分成不同的小塊進行計算。第一塊數據在傳輸的時候,后面所有任務都在等待,當第一塊傳輸完了之后第二塊開始傳輸。與此同時,第一塊數據開始計算,就可以把傳輸時間隱藏在計算時間里了。
大家做一些基于視覺應用時,一個服務器可能要同時開N個實例。比如一個V100,16G Memory,ResNet-50需要1.3GB的GPU Memory。這時一個GPU可以同時開12個實例,每個示例對應一定的攝像頭,這樣管理這些GPU資源的時候能充分利用。
然后還有內核調用。不同產品的內核,它的核多、核少、不同的核的大小,或者寄存器的個數,它會自動優(yōu)化到每個kernel里。
最后是網絡層的融合。TensorRT不會改變或者裁剪網絡層,但它可以幫我們做一些優(yōu)化。
上圖是大家比較熟悉的GoogleNet Inception結構,首先我們可以看到有很多個網絡層,比如類似于Caffe或者TensorFlow等底層代碼,它調用一個網絡層時,會把上一層的Tensor數據拿來傳到這個函數里,如果你做GPU優(yōu)化,它會把這個數據放到GPU進行計算,GPU計算完成后再返回給CPU。每個網絡層都是同樣的過程。
或者說你把整個的網絡層的數據全都Load到GPU里,GPU會把它放在Global Memory里,然后使用時會把它調到每個Kernel或SM多流處理器里。在這過程中,每一層都是“寫-計算-讀”。我們可以把三個網絡層進行融合,CBR,是Convolution、Bias、ReLU的縮寫。
這樣有什么好處?如果當前Memory足夠Load數據之后,把這三個網絡層融合到一起,就能夠節(jié)省四次的訪存次數。隨著網絡層越來越深,網絡層的讀寫次數越少,加速時間就會越來越多。
除了上面的融合之外,我們把三個1×1 CBR還可以融合在一起,因為它們進行相同的操作。同時自動拼接也可以省掉,因為GPU里計算完就直接執(zhí)行了,可以直接消減掉。
最后,可以看到這個過程中,這個兩條線彼此之間是并不相關的,數據之間沒有相互的交流。我們可以單獨啟動兩個Stream,分別走這兩條線。
就是把左側兩個數據來計算的同時,同時計算第三塊數據,也就是把需要時間較少的那一部分隱藏到另一部分的時間里,當然這都是TensorRT幫我們完成的。
TensorRT在整個過程中支持了網絡層,使用TensorRT的時候,需要把訓練好的數據或網絡模型給到TensorRT工具。通過ONNX的操作,TensorRT基本上支持了現(xiàn)在市面上常見的網絡框架訓練出的模型,Caffe、TensorFlow、ONNX、DarkNet的數據都是可以的。
最后介紹一下英偉達開發(fā)者社區(qū):https://developer.nvidia-china.com,大家有什么問題可以在上面提問,謝謝大家。