【轉(zhuǎn)載】TensorRT 系列之入門篇

https://mp.weixin.qq.com/s/E5qbMsuc7UBnNmYBzq__5Q

TensorRT 系列之入門篇

原創(chuàng)?2018-01-28?子棐?子棐之GPGPU

這個(gè)世界沒有免費(fèi)的午餐,如果有---那就是TensorRT……

——子棐


Why TensorRT

訓(xùn)練對于深度學(xué)習(xí)來說是為了獲得一個(gè)性能優(yōu)異的模型,其主要的關(guān)注點(diǎn)在于模型的準(zhǔn)確度等指標(biāo)。推理則不一樣,其沒有了訓(xùn)練中的反向迭代過程驻售,是針對新的數(shù)據(jù)進(jìn)行預(yù)測,而我們?nèi)粘I钪惺褂玫腁I服務(wù)都是推理服務(wù)。相較于訓(xùn)練椭更,推理的關(guān)注點(diǎn)不一樣,從而也給現(xiàn)在有技術(shù)帶來了新的挑戰(zhàn):


需求現(xiàn)有框架的局限性影響

高吞吐率無法處理大量和高速的數(shù)據(jù)增加了單次推理的開銷

低響應(yīng)時(shí)間應(yīng)用無法提供實(shí)時(shí)的結(jié)果損害了用戶體驗(yàn)(語音識別蛾魄、個(gè)性化推薦和實(shí)時(shí)目標(biāo)檢測)

高效的功耗以及顯存消耗控制非最優(yōu)效能增加了推理的開銷甚至無法進(jìn)行推理部署

部署級別的解決方案非專用于部署使用框架復(fù)雜度和配置增加了部署難度以及生產(chǎn)率


根據(jù)上圖可知虑瀑,推理更關(guān)注的是高吞吐率湿滓、低響應(yīng)時(shí)間、低資源消耗以及簡便的部署流程舌狗,而TensorRT就是用來解決推理所帶來的挑戰(zhàn)以及影響的部署級的解決方案叽奥。


TensorRT部署流程

TensorRT的部署分為兩個(gè)部分:

[if !supportLists]1.??? [endif]優(yōu)化訓(xùn)練好的模型并生成計(jì)算流圖

[if !supportLists]2.??? [endif]使用TensorRT Runtime部署計(jì)算流圖

關(guān)于這個(gè)流程很自然我們會(huì)想到以下幾個(gè)問題:

[if !supportLists]1.??? [endif]TensorRT支持什么框架訓(xùn)練出來的網(wǎng)絡(luò)模型呢?

[if !supportLists]2.??? [endif]TensorRT支持什么網(wǎng)絡(luò)結(jié)構(gòu)呢痛侍?

[if !supportLists]3.??? [endif]TensorRT優(yōu)化器做了哪些優(yōu)化呢朝氓?

[if !supportLists]4.??? [endif]TensorRT優(yōu)化好的計(jì)算流圖可以運(yùn)行在什么設(shè)備上呢?

個(gè)中因果主届,諸位看官赵哲,稍安勿躁,待本文娓娓道來君丁。


TensorRT之大胃王

輸入篇之網(wǎng)絡(luò)框架:TensorRT3支持所有常見的深度學(xué)習(xí)框架包括Caffe枫夺、Chainer、CNTK绘闷、MXnet筷屡、PaddlePaddle、Pytorch簸喂、TensorFlow以及Theano毙死。

輸入篇之網(wǎng)絡(luò)層:TensorRT3支持的網(wǎng)絡(luò)層包括

Convolution

LSTM and GRU

Activation: ReLU, tanh,? sigmoid

Pooling: max and average

Scaling

ElementWise

LRN

Fully-connected

SoftMax

Deconvolution

Concatenation

Flatten

Padding

Plugin

RNN: RNN, GRU, LSTM

Scale

Shuffle

Softmax

Squeeze

Unary

輸入篇之接口方式:TensorRT3支持模型導(dǎo)入方式包括C++ API、Python API喻鳄、NvCaffeParser和NvUffParser

輸出篇之支持系統(tǒng)平臺:TensorRT3支持的平臺包括Linux x86扼倘、Linux aarch64、Android aarch64和QNX aarch64除呵。

輸出篇之支持硬件平臺:TensorRT3可以運(yùn)行在每一個(gè)GPU平臺再菊,從數(shù)據(jù)中心的Tesla P4/V100到自動(dòng)駕駛和嵌入式平臺的DrivePX及TX1/TX2。


TensorRT 模型導(dǎo)入流程

如上圖所示颜曾,模型的導(dǎo)入方法可以根據(jù)框架種類分成三種:Caffe纠拔、TensorFlow和其他。

Caffe

[if !supportLists]1.??? [endif]使用C++/Python API導(dǎo)入模型:通過代碼定義網(wǎng)絡(luò)結(jié)構(gòu)泛豪,并載入模型weights的方式導(dǎo)入稠诲;

[if !supportLists]2.??? [endif]使用NvCaffeParser導(dǎo)入模型:導(dǎo)入時(shí)輸入網(wǎng)絡(luò)結(jié)構(gòu)prototxt文件及caffemodel文件即可。

TensorFlow

[if !supportLists]1.??? [endif]訓(xùn)練完成后诡曙,使用uff python接口將模型轉(zhuǎn)成uff格式臀叙,之后使用NvUffParaser導(dǎo)入;

[if !supportLists]2.??? [endif]對于TensorFlow或者keras(TensorFlow后端)的价卤,利用Freeze graph來生成.pb(protobuf)文件劝萤,之后使用convert-to-uff工具將.pb文件轉(zhuǎn)化成uff格式,然后利用NvUffParaser導(dǎo)入慎璧。

其他框架

使用C++/Python API導(dǎo)入模型:通過代碼定義網(wǎng)絡(luò)結(jié)構(gòu)床嫌,載入模型weights的方式導(dǎo)入跨释。以Pytorch為例,在完成訓(xùn)練后厌处,通過stat_dict()函數(shù)獲取模型的weights煤傍,從而在定義網(wǎng)絡(luò)結(jié)構(gòu)時(shí)將weights載入。

[if !supportLineBreakNewLine]

[endif]

[if !supportLineBreakNewLine]

[endif]

注:weights文件是保存的C++ Map對象嘱蛋,該對象定義為:

std::map

其中Weights類型是在NvInfer.h中定義蚯姆,為存儲(chǔ)weights的array。


TensorRT 優(yōu)化細(xì)節(jié)

網(wǎng)絡(luò)模型在導(dǎo)入至TensorRT后會(huì)進(jìn)行一系列的優(yōu)化洒敏,主要優(yōu)化內(nèi)容如下圖所示龄恋。

Layer & Tensor Fusion

TensorRT在獲得網(wǎng)絡(luò)計(jì)算流圖后會(huì)針對計(jì)算流圖進(jìn)行優(yōu)化,這部分優(yōu)化不會(huì)改變圖中最底層計(jì)算內(nèi)容凶伙,而是會(huì)去重構(gòu)計(jì)算圖來獲得更快更高效的執(zhí)行方式郭毕,即計(jì)算不變優(yōu)化計(jì)算方法。

以下圖為例:

深度學(xué)習(xí)框架在做推理時(shí)函荣,會(huì)對每一層調(diào)用多個(gè)/次功能函數(shù)显押。而由于這樣的操作都是在GPU上運(yùn)行的,從而會(huì)帶來多次的CUDA Kernel

launch過程傻挂。相較于Kernel launch以及每層tensor data讀取來說乘碑,kernel的計(jì)算是更快更輕量的,從而使得這個(gè)程序受限于顯存帶寬并損害了GPU利用率金拒。

TensorRT通過以下三種方式來解決這個(gè)問題:

[if !supportLists]1.??? [endif]Kernel縱向融合:通過融合相同順序的操作來減少Kernel Launch的消耗以及避免層之間的顯存讀寫操作兽肤。如上圖所示,卷積绪抛、Bias和Relu層可以融合成一個(gè)Kernel资铡,這里稱之為CBR。

[if !supportLists]2.??? [endif]Kernel橫向融合:TensorRT會(huì)去挖掘輸入數(shù)據(jù)且filter大小相同但weights不同的層幢码,對于這些層不是使用三個(gè)不同的Kernel而是使用一個(gè)Kernel來提高效率笤休,如上圖中超寬的1x1 CBR所示。

[if !supportLists]3.??? [endif]消除concatenation層症副,通過預(yù)分配輸出緩存以及跳躍式的寫入方式來避免這次轉(zhuǎn)換店雅。

通過這樣的優(yōu)化,TensorRT可以獲得更小瓦糕、更快底洗、更高效的計(jì)算流圖腋么,其擁有更少層網(wǎng)絡(luò)結(jié)構(gòu)以及更少Kernel Launch次數(shù)咕娄。下表列出了常見幾個(gè)網(wǎng)絡(luò)在TensorRT優(yōu)化后的網(wǎng)絡(luò)層數(shù)量,很明顯的看到TensorRT可以有效的優(yōu)化網(wǎng)絡(luò)結(jié)構(gòu)珊擂、減少網(wǎng)絡(luò)層數(shù)從而帶來性能的提升圣勒。

NetworkLayersLayers after fusion

VGG194327

Inception V3309113

ResNet-152670159

FP16 & INT8 精度校準(zhǔn)

大多數(shù)的網(wǎng)絡(luò)都是使用FP32進(jìn)行模型訓(xùn)練费变,因此模型最后的weights也是FP32格式。但是一旦完成訓(xùn)練圣贸,所有的網(wǎng)絡(luò)參數(shù)就已經(jīng)是最優(yōu)挚歧,在推理過程中是無需進(jìn)行反向迭代的,因此可以在推理中使用FP16或者INT8精度計(jì)算從而獲得更小的模型吁峻,低的顯存占用率和延遲以及更高的吞吐率滑负。

TensorRT可以采用FP32、FP16和INT8精度部署模型用含,只需要在uff_to_trt_engine函數(shù)中指定相應(yīng)數(shù)據(jù)類型即可:

[if !supportLists]o???[endif]對于FP32, 使用 trt.infer.DataType.FLOAT.

[if !supportLists]o???[endif]對于FP16 指令 以及 Volta GPU內(nèi)的Tensor Cores, 使用trt.infer.DataType.HALF

[if !supportLists]o???[endif]對于INT8, 使用 trt.infer.DataType.INT8.

更多詳細(xì)的信息會(huì)在未來幾期公眾號解釋矮慕,如有興趣請保持關(guān)注。

Kernel Auto-Tuning

TensorRT會(huì)針對大量的Kernel進(jìn)行參數(shù)優(yōu)化和調(diào)整啄骇。例如說痴鳄,對于卷積計(jì)算有若干種算法,TensorRT會(huì)根據(jù)輸入數(shù)據(jù)大小缸夹、filter大小痪寻、tensor分布、batch大小等等參數(shù)針對目標(biāo)平臺GPU進(jìn)行選擇和優(yōu)化虽惭。

Dynamic Tensor Memory

TensorRT通過為每一個(gè)tensor在其使用期間設(shè)計(jì)分配顯存來減少顯存的占用增加顯存的復(fù)用率橡类,從而避免了顯存的過度開銷以獲得更快和高效的推理性能。

優(yōu)化結(jié)果

上圖為基于Resnet50網(wǎng)絡(luò)芽唇,分別在CPU猫态、V100+TensorFlow、V100+TensorRT上進(jìn)行推理時(shí)的性能比較披摄,縱軸為每秒處理的圖片數(shù)量亲雪。相較于CPU和TensorFlow,TensorRT可以帶來40倍和18倍的吞吐率的提升疚膊,而這部分的提升只需要在擁有GPU的前提下使用TensorRT即可免費(fèi)獲得义辕。


TensorRT 部署方法

完成TensorRT優(yōu)化后可以得到一個(gè)Runtime

inference engine,這個(gè)文件可以被系列化保存至硬盤中寓盗,而這個(gè)保存的序列化文件我們稱之為“Plan”(流圖)灌砖,之所以稱之為流圖,因此其不僅保存了計(jì)算時(shí)所需的網(wǎng)絡(luò)weights也保存了Kernel執(zhí)行的調(diào)度流程傀蚌。TensorRT提供了write_engine_to_file()函數(shù)以來保存流圖基显。


在獲得了流圖之后就可以使用TensorRT部署應(yīng)用。為了進(jìn)一步的簡化部署流程善炫,TensorRT提供了TensorRT Lite API撩幽,它是高度抽象的接口會(huì)自動(dòng)處理大量的重復(fù)的通用任務(wù)例如創(chuàng)建一個(gè)Logger,反序列化流圖并生成Runtime inference engine,處理輸入的數(shù)據(jù)窜醉。以下代碼提供了一個(gè)使用TensorRT Lite

API的范例教程宪萄,只需使用API創(chuàng)建一個(gè)Runtime Engine即可完成前文提到的通用任務(wù),之后將需要推理的數(shù)據(jù)載入并送入Engine即可進(jìn)行推理榨惰。

from tensorrt.lite import Engine

from tensorrt.infer import LogSeverity

import tensorrt


# Create a runtime engine from plan file using TensorRT Lite API?

engine_single = Engine(PLAN="keras_vgg19_b1_FP32.engine",


? ?postprocessors={"dense_2/Softmax":analyze})


images_trt, images_tf = load_and_preprocess_images()


results = []

for image in images_trt:

? ? result = engine_single.infer(image) # Single function for

inference

? ? results.append(result)


敲黑板0萦ⅰ!琅催!TensorRT3Highlight

TensorRT3帶來的三個(gè)重大更新為:

[if !supportLists]1.??? [endif]TensorFlow Model

Importer - 便捷的API用于導(dǎo)入TensorFLow訓(xùn)練的模型居凶,優(yōu)化并生成推理Engine。

[if !supportLists]2.??? [endif]Python API -

Python API用于進(jìn)一步提高開發(fā)效率藤抡。

[if !supportLists]3.??? [endif]Volta Tensor

Core支持 - 帶來相較于Tesla P100高達(dá)3.7倍的更快的推理性能排监。



以上 & 未完待續(xù)~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市杰捂,隨后出現(xiàn)的幾起案子舆床,更是在濱河造成了極大的恐慌,老刑警劉巖嫁佳,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挨队,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒿往,警方通過查閱死者的電腦和手機(jī)盛垦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓤漏,“玉大人腾夯,你說我怎么就攤上這事∈叱洌” “怎么了蝶俱?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饥漫。 經(jīng)常有香客問我榨呆,道長,這世上最難降的妖魔是什么庸队? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任积蜻,我火速辦了婚禮,結(jié)果婚禮上彻消,老公的妹妹穿的比我還像新娘竿拆。我一直安慰自己,他們只是感情好宾尚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布丙笋。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪不见。 梳的紋絲不亂的頭發(fā)上澳化,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天崔步,我揣著相機(jī)與錄音稳吮,去河邊找鬼。 笑死井濒,一個(gè)胖子當(dāng)著我的面吹牛灶似,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瑞你,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼酪惭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了者甲?” 一聲冷哼從身側(cè)響起春感,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虏缸,沒想到半個(gè)月后鲫懒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刽辙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年窥岩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宰缤。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡颂翼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慨灭,到底是詐尸還是另有隱情朦乏,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布氧骤,位于F島的核電站集歇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏语淘。R本人自食惡果不足惜诲宇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惶翻。 院中可真熱鬧姑蓝,春花似錦、人聲如沸吕粗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宙暇,卻和暖如春输枯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背占贫。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工桃熄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人型奥。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓瞳收,卻偏偏與公主長得像,于是被迫代替她去往敵國和親厢汹。 傳聞我的和親對象是個(gè)殘疾皇子螟深,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 我的閨蜜,小學(xué)到初中烫葬,我們一直都是同學(xué)界弧,至今已經(jīng)17年,這奠定 了我們無話不說的良好基礎(chǔ)搭综。 就在剛剛我們才通完話...
    末花紛紛開且落閱讀 178評論 0 0
  • 01 “林宇垢箕,開門啦∩璋迹” 我放下正在復(fù)習(xí)的英語書舰讹,挪開椅子,走到門口闪朱。 門口月匣,謝飛和他的小女友李青捧著一個(gè)10寸的...
    四點(diǎn)半的洛杉磯閱讀 1,070評論 11 33