Yolov--3--TensorRT中yolov3性能優化加速(基於caffe)

Yolov-1-TX2上用YOLOv3訓練本身數據集的流程(VOC2007-TX2-GPU)html


Yolov--2--一文全面瞭解深度學習性能優化加速引擎---TensorRTpython


Yolov--3--TensorRT中yolov3性能優化加速(基於caffe)git


yolov-5-目標檢測:YOLOv2算法原理詳解github


yolov--8--Tensorflow實現YOLO v3算法


yolov--9--YOLO v3的剪枝優化api


yolov--10--目標檢測模型的參數評估指標詳解、概念解析數組


yolov--11--YOLO v3的原版訓練記錄、mAP、AP、recall、precision、time等評價指標計算緩存


yolov--12--YOLOv3的原理深度剖析和關鍵點講解性能優化


1、TX2中TensorRT的安裝微信

https://blog.csdn.net/haoqimao_hard/article/details/81001844


https://github.com/dusty-nv/jetson-inference


平臺:英偉達NVIDIA TX2開發板  環境:Ubuntu16.04, python2.7,cuda8.0,cudnn6.0.2.  OpenCV 2.4.13.1


caffe安裝教程:


https://www.jianshu.com/p/e78c5c321248?tdsourcetag=s_pcqq_aiomsg


https://github.com/Cw-zero/TensorRT_yolo3


Use TensorRT accelerate yolo3

1. How to run this project

a. Download yolo3.weight from this, and change the name to yolov3-608.weights.

b. python yolov3_to_onnx.py, you will have a file named yolov3-608.onnx

c. python onnx_to_tensorrt.py,you can get the result of detections.

2. Performance compare

a.You can download and run this project, which our project is changed from it. It detection speed is about 100ms per image.


b.Our project speed is about 62ms per image


3.Others

If you are more familiar with Chinese, you can refer to this blog(https://www.cnblogs.com/justcoder/), which has more details.

1、TensorRT支持的模型: 

TensorRT 直接支持的model有ONNX、Caffe、TensorFlow,其餘常見model建議先轉化成ONNX。總結以下:


1 ONNX(.onnx) 


2 Keras(.h5) --> ONNX(.onnx) (https://github.com/onnx/keras-onnx)


3 Caffe(.caffemodel)


4 Darknet(.cfg) --> ONNX(.onnx) (Our tutorial : yolo-v3)


5 TensorFlow(.uff)


 


2、TensorRT支持的常見運算:


 Activation(激活函數)、Convolution(卷積運算)、Deconvolution(反捲積運算)、FullConnected(全鏈接)、Padding(填充)、Pooling(池化)、RNN(遞歸神經網絡)、SoftMax()等。


更詳細的API可參考:


https://docs.nvidia.com/deeplearning/sdk/tensorrt-api/c_api/classnvinfer1_1_1_i_network_definition.html


 


3、TensorRT加速yolo3:

yolo3由CNN網絡和detection模塊組成,TensorRT只對CNN網絡進行Inference加速。即:


TensorRT input is:608*608 image


TensorRT output is:array


  (array[0].shape = 255 *19*1九、


   array[1].shape = 255*38*3八、


   array[2].shape = 255 *76*76)


具體實現過程:


 1 Darknet(.cfg) --> ONNX(.onnx)


 2 ONNX(.onnx) --> TensorRT model(.trt)


 3 TensorRT加速CNN部分,執行detection模塊獲得最終結果。


pytorch-yolo3:https://github.com/ayooshkathuria/pytorch-yolo-v3


本項目地址:https://github.com/Cw-zero/TensorRT_yolo3


(注:本項目是對pytorch-yolo3進行改寫加速的)


 


4、性能比較:



More about TensorRT 可參考官方指導:


https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#python_example_unsupported

Yolov--2--一文全面瞭解深度學習性能優化加速引擎---TensorRT


目標:讓你們能更好地利用GPU,使其在作深度學習訓練的時候達到更好的效果。


1、TensorRT理論解釋

 TensorRT是什麼?作了哪些優化?

TensorRT項目立項的時候名字叫作GPU Inference Engine(簡稱GIE)

Tensor表示數據流動以張量的形式。所謂張量你們能夠理解爲更加複雜的高維數組,通常一維數組叫作Vector(即向量),二維數組叫作Matrix,再高緯度的就叫Tensor(三位及以上的數組運算),Matrix實際上是二維的Tensor。 

在TensoRT中,全部的數據都被組成最高四維的數組,若是對應到CNN中其實就是{N, C, H, W},

N表示batch size,即多少張圖片或者多少個推斷(Inference)的實例;C表示channel數目;H和W表示圖像或feature maps的高度和寬度。TR表示的是Runtime。

爲何在有了框架的基礎上還須要TensorRT來優化加速?  

若是你們對深度學習有些瞭解的話可能會知道,它分爲訓練和部署兩部分,


訓練部分首先也是最重要的是構建網絡結構,準備數據集,使用各類框架進行訓練,訓練要包含validation和test的過程,最後對於訓練好的模型要在實際業務中進行使用。訓練的操做通常在線下,實時數據來以後在線訓練的狀況比較少,大多數狀況下數據是離線的,已經收集好的,數據更新不頻繁的一天或一週一收集,數據更新頻繁的可能幾十分鐘,在線下有大規模的集羣開始對數據或模型進行更新,這樣的訓練須要消耗大量的GPU,相對而言通常會給一個比較大的batchsize,由於它的實時性要求相對較低,通常訓練模型給的是128,甚至有些極端的1024,大的batch的好處是能夠充分的利用GPU設備。


可是到推斷(Inference)的時候就是不一樣的概念了,推斷(Inference)的時候只須要作一個前向計算,將輸入經過神經網絡得出預測的結果。而推斷(Inference)的實際部署有多種可能,可能部署在Data Center(雲端數據中心),好比說你們常見的手機上的語音輸入,目前都仍是雲端的,也就是說你的聲音是傳到雲端的,雲端處理好以後把數據再返回來;還可能部署在嵌入端,好比說嵌入式的攝像頭、無人機、機器人或車載的自動駕駛,固然車載的自動駕駛多是嵌入式的設備,也多是一臺完整的主機,像這種嵌入式或自動駕駛,它的特色是對實時性要求很高。


一樣的,Data Center也是對實時性要求很高,作一個語音識別,不能說說完了等很長時間尚未返回,因此在線的部署最大的特色是對實時性要求很高,它對latency很是敏感,要咱們能很是快的給出推斷(Inference)的結果。作一個不一樣恰當的比方,訓練(Training)這個階段若是模型比較慢,實際上是一個砸錢能夠解決的問題,咱們能夠用更大的集羣、更多的機器,作更大的數據並行甚至是模型並行來訓練它,重要的是成本的投入。


而部署端不僅是成本的問題,若是方法不得當,即便使用目前最早進的GPU,也沒法知足推斷(Inference)的實時性要求。


由於模型若是作得很差,沒有作優化,可能須要二三百毫秒才能作完一次推斷(Inference),再加上來回的網絡傳輸,用戶可能一秒後才能獲得結果。在語音識別的場景之下,用戶能夠等待;可是在駕駛的場景之下,可能會有性命之庾。



 


在部署階段,latency是很是重要的點,而TensorRT是專門針對部署端進行優化的,目前TensorRT支持大部分主流的深度學習應用,固然最擅長的是CNN(卷積神經網絡)領域,可是的TensorRT 3.0也是有RNN的API,也就是說咱們能夠在裏面作RNN的推斷(Inference)。


 




 


最典型的應用是圖片的分類,這也是最經典的,實際上也是深度學習目前解決的比較好的一些問題。其餘的例如,圖片的語義分割、目標檢測等都是以圖片分類網絡爲基礎進行改進的。目標檢測是比較典型的例子(以下圖),訓練(Training)是對已經打好框的圖片進行前向計算,得出的框和實際的框(ground truth)進行對比,而後再作後向更新,更新模型。真正作推斷(Inference)的時候,好比一個攝像頭,基本上要保證是實時的,也就是提及碼要保證每秒25-30幀的速度,鑑於實際應用多是二三十路攝像頭同時進來的數據,這時候必須保證一塊卡作到實時處理,仍是比較有挑戰性的工做。


 




 


總結一下推斷(Inference)和訓練(Training)的不一樣:


1. 推斷(Inference)的網絡權值已經固定下來,無後向傳播過程,所以能夠


1)模型固定,能夠對計算圖進行優化


2) 輸入輸出大小固定,能夠作memory優化(注意:有一個概念是fine-tuning,即訓練好的模型繼續調優,只是在已有的模型作小的改動,本質上仍然是訓練(Training)的過程,TensorRT沒有fine-tuning


2. 推斷(Inference)的batch size要小不少,仍然是latency的問題,由於若是batch size很大,吞吐能夠達到很大,好比每秒能夠處理1024個batch,500毫秒處理完,吞吐能夠達到2048,能夠很好地利用GPU;可是推斷(Inference)不能作500毫秒處理,能夠是8或者16,吞吐下降,沒有辦法很好地利用GPU.


3. 推斷(Inference)可使用低精度的技術,訓練的時候由於要保證先後向傳播,每次梯度的更新是很微小的,這個時候須要相對較高的精度,通常來講須要float型,如FP32,32位的浮點型來處理數據,可是在推斷(Inference)的時候,對精度的要求沒有那麼高,不少研究代表能夠用低精度,如半長(16)的float型,即FP16,也能夠用8位的整型(INT8)來作推斷(Inference),研究結果代表沒有特別大的精度損失,尤爲對CNN。更有甚者,對Binary(二進制)的使用也處在研究過程當中,即權值只有0和1。目前FP16和INT8的研究使用相對來講比較成熟。低精度計算的好處是一方面能夠減小計算量,原來計算32位的單元處理FP16的時候,理論上能夠達到兩倍的速度,處理INT8的時候理論上能夠達到四倍的速度。固然會引入一些其餘額外的操做,後面的講解中會詳細介紹FP18和INT8;另外一方面是模型須要的空間減小,無論是權值的存儲仍是中間值的存儲,應用更低的精度,模型大小會相應減少。


下圖展現的是TensorRT的效果,固然這是一個比較極端的例子,由於該例中使用的是最早進的GPU卡V100,V100添加了專門針對深度學習優化的TensorCore,TensorCore能夠完成4×4矩陣的半精度乘法,也就是能夠完成一個4×4的FP16矩陣和另一個4×4的FP16矩陣相乘,固然能夠再加一個矩陣(FP16 或FP32),獲得一個FP32或者FP16的矩陣的過程。TensorCore在V100上理論峯值能夠達到120 Tflops.(開個玩笑,電影終結者中整個天網的計算能力至關於兩塊V100)。回到圖中,先看一下若是隻是用CPU來作推斷(Inference),首先它的吞吐只能達到140,也就是說每秒只能處理140張圖片,同時整個處理過程須要有14ms的延遲,也就是說用戶提交請求後,推斷(Inference)階段最快須要14ms才能返回結果;若是使用V100,在TensorFlow中去作推斷(Inference),大概是6.67ms的延時,可是吞吐只能達到305;若是使用V100加TensorRT,在保證延遲不變的狀況下,吞吐能夠提升15倍,高達5700張圖片每秒,這個差異是很大的。十幾倍的吞吐的提高其實是在保證延遲的狀況下成本的縮減 。


 




 


回到TensorRT的主題,以前你們廣泛存在的一個疑問是在訓練過程當中可使用不一樣的框架,爲何推斷(Inference)不能用各類框架,好比TensorFlow等。固然是能夠用的,可是問題是靈活性和性能是一種trade-off的關係,這是在作深度學習或訓練過程當中常常會遇到的一個問題。好比像TensorFlow的設計初衷是爲各類各樣的操做來作準備的,在早期的框架,例如Caffe中不少先後處理並不在框架裏面完成,而是經過額外的程序或腳本處理,可是TensorFlow支持將全部的操做放入框架之中來完成,它提供了操做(Operation)級別的支持,使得靈活性大大提升,可是靈活性多是以犧牲效率爲代價的。TensorFlow在實現神經網絡的過程當中能夠選擇各類各樣的高級庫,如用nn來搭建,tf.nn中的convolution中能夠加一個卷積,能夠用slim來實現卷積,不一樣的卷積實現效果不一樣,可是其對計算圖和GPU都沒有作優化,甚至在中間卷積算法的選擇上也沒有作優化,而TensorRT在這方面作了不少工做。


在講TensorRT作了哪些優化以前, 想介紹一下TensorRT的流程, 首先輸入是一個預先訓練好的FP32的模型和網絡,將模型經過parser等方式輸入到TensorRT中,TensorRT能夠生成一個Serialization,也就是說將輸入串流到內存或文件中,造成一個優化好的engine,執行的時候能夠調取它來執行推斷(Inference)。


 




 


如上圖所示TensorRT整個過程能夠分三個步驟,即模型的解析(Parser),Engine優化和執行(Execution)。暫時拋開TensorRT,若是讓你們從頭寫一個深度學習模型的前向過程,具體過程應該是


1)  首先實現NN的layer,如卷積的實現,pooling的實現。


2) 管理memory,數據在各層之間如何流動。


3) 推斷(Inference)的engine來調用各層的實現。


 


以上三個步驟在TendorRT都已經實現好了,用戶須要作的是如何將網絡輸入到TensorRT中。目前TensorRT支持兩種輸入方式:


1. 一種是Parser的方式,即模型解析器,輸入一個caffe的模型,能夠解析出其中的網絡層及網絡層之間的鏈接關係,而後將其輸入到TensorRT中,可是TensorRT是如何知道這些鏈接關係呢?答案是API。


2.  API接口能夠添加一個convolution或pooling。而Parser是解析模型文件,好比TensorFlow轉換成的uff,或者是caffe的模型,再用API添加到TensorRT中,構建好網絡。構建好後就能夠作優化。


a) 考慮到一個狀況,若是有一個網絡層不支持,這個有可能,TensorRT只支持主流的操做,好比說一個神經網絡專家開發了一個新的網絡層,新型卷積和之前的卷積都不同,TensorRT是不知道是作什麼的。好比說最多見的檢測網絡,有一些網絡層也是不支持的,這個時候涉及到customer layer的功能,即用戶自定義層,構建用戶自定義層須要告訴TensorRT該層的鏈接關係和實現方式,這樣TensorRT才能去作。


b) 目前API支持兩種接口實現方式,一種是C++,另外一種是Python,Python接口可能在一些快速實現上比較方便一些。


c) Parser目前有三個,一個是caffe Parser,這個是最古老的也是支持最完善的;另外一個是uff,這個是NV定義的網絡模型的一種文件結構,如今TensorFlow能夠直接轉成uff;另外下一個版本3.5或4.0會支持的onnx,是Facebook主導的開源的可交換的各個框架均可以輸出的,有點相似於文檔編輯中的word格式或AutoCAD中CAD的格式,雖然是由一個公司提出,可是有但願成爲一個標準,各個APP去支持這個標準。像pytorch和caffe 2都是支持這個格式的,這個目前只在NGC (NVDIA GPU Cloud)上支持,可是下一個版本發行都會支持。若是某個公司新推出一個特別火的框架不支持怎麼辦,仍然能夠採用API的方式,一層一層的添加進去,告訴TensorRT鏈接關係,這也是OK的。


模型解析後,engine會進行優化,具體的優化稍後會介紹。獲得優化好的engine能夠序列化到內存(buffer)或文件(file),讀的時候須要反序列化,將其變成engine以供使用。而後在執行的時候建立context,主要是分配預先的資源,engine加context就能夠作推斷(Inference)。


以上是TensorRT的整個過程,你們在疑惑TensorRT是否支持TensorFlow,首先你們寫的網絡計算層可能都是支持的,可是有些網絡層可能不支持,在不支持的狀況下能夠用customer layer的方式添加進去,可是有時候爲了使用方便,可能沒辦法一層一層的去添加,須要用模型文件形式,這個取決於Parser是否徹底支持。相對而言,你們在框架有過比較後會發現,caffe這個框架的特色是很是不靈活,若是要添加一個新的網絡層,須要修改源代碼;TensorFlow的優勢倒是很是的靈活。


剛纔講到TensorRT所作的優化,總結下來主要有這麼幾點:


第一,也是最重要的,它把一些網絡層進行了合併。你們若是瞭解GPU的話會知道,在GPU上跑的函數叫Kernel,TensorRT是存在Kernel的調用的。在絕大部分框架中,好比一個卷積層、一個偏置層和一個reload層,這三層是須要調用三次cuDNN對應的API,但實際上這三層的實現徹底是能夠合併到一塊兒的,TensorRT會對一些能夠合併網絡進行合併;再好比說,目前的網絡一方面愈來愈深,另外一方面愈來愈寬,可能並行作若干個相同大小的卷積,這些卷積計算其實也是能夠合併到一塊兒來作的。


第二,好比在concat這一層,好比說這邊計算出來一個1×3×24×24,另外一邊計算出來1×5×24×24,concat到一塊兒,變成一個1×8×24×24的矩陣,這個叫concat這層這實際上是徹底沒有必要的,由於TensorRT徹底能夠實現直接接到須要的地方,不用專門作concat的操做,因此這一層也能夠取消掉。


第三,Kernel能夠根據不一樣的batch size 大小和問題的複雜程度,去選擇最合適的算法,TensorRT預先寫了不少GPU實現,有一個自動選擇的過程。


第四,不一樣的batch size會作tuning。


第五,不一樣的硬件如P4卡仍是V100卡甚至是嵌入式設備的卡,TensorRT都會作優化,獲得優化後的engine。


下圖是一個原始的GoogleNet的一部分,首先input後會有多個卷積,卷積完後有Bias和ReLU,結束後將結果concat(鏈接拼接)到一塊兒,獲得下一個input。




 


以上的整個過程能夠作些什麼優化呢?首先是convolution, Bias和ReLU這三個操做能夠合併成CBR,合併後的結果以下所示,其中包含四個1×1的CBR,一個3×3的CBR和一個5×5的CBR。




 


接下來能夠繼續合併三個相連的1×1的CBR爲一個大的1×1的CBR(以下圖),這個合併就能夠更好地利用GPU。


 




 


繼而concat層能夠消除掉,直接鏈接到下一層的next input(以下圖)。


 




 


另外還能夠作併發(Concurrency),以下圖左半部分(max pool和1×1 CBR)與右半部分(大的1×1 CBR,3×3 CBR和5×5 CBR)彼此之間是相互獨立的兩條路徑,本質上是不相關的,能夠在GPU上經過併發來作,來達到的優化的目標。


 




 


2、TensorRT高級特徵介紹


 


前面介紹了TesorRT的基礎,更多信息能夠查詢官網,或者反饋給我。接下來和你們分享一些TensorRT比較高級的特徵,這塊主要針對有必定經驗或者作過一些線上部署的人。


 


1. 插件支持


首先TensorRT是支持插件(Plugin)的,或者前面提到的Customer layer的形式,也就是說咱們在某些層TensorRT不支持的狀況下,最主要是作一些檢測的操做的時候,不少層是該網絡專門定義的,TensorRT沒有支持,須要經過Plugin的形式本身去實現。實現過程包括以下兩個步驟:


1)   首先須要重載一個IPlugin的基類,生成本身的Plugin的實現,告訴GPU或TensorRT須要作什麼操做,要構建的Plugin是什麼樣子,其實就是相似於開發一個應用軟件的插件,須要在上面實現什麼功能。


2)   其次要將插件添加到合適的位置,在這裏是要添加到網絡裏去。


注意,只有TensorRT 2.1和更高的版本支持插件的功能(該視頻講的時候的版本是3.0.2,支持插件功能)。


2. 低精度支持


低精度指的是以前所說過的FP16和INT8,其中FP16主要是Pascal P100和V100(tensor core)這兩張卡支持;而INT8主要針對的是 P4和P40這兩張卡,P4是專門針對線上作推斷(Inference)的小卡,和IPhone手機差很少大,75瓦的一張卡,功耗和性能很是好。


3. Python接口和更多的框架支持


TensorRT目前支持Python和C++的API,剛纔也介紹瞭如何添加,Model importer(即Parser)主要支持Caffe和Uff,其餘的框架能夠經過API來添加,若是在Python中調用pyTouch的API,再經過TensorRT的API寫入TensorRT中,這就完成了一個網絡的定義。


TensorRT去作推斷(Inference)的時候是再也不須要框架的,用Caffe作推斷(Inference)須要Caffe這個框架,TensorRT把模型導進去後是不須要這個框架的,Caffe和TensorFlow能夠經過Parser來導入,一開始就不須要安裝這個框架,給一個Caffe或TensorFlow模型,徹底能夠在TensorRT高效的跑起來。


 


3、用戶自定義層


 


使用插件建立用戶自定義層主要分爲兩個步驟:


第一步是建立使用IPlugin接口建立用戶自定義層,IPlugin是TensorRT中預約義的C++抽象類,用戶須要定義具體實現了什麼。


第二步是將建立的用戶自定義層添加到網絡中,若是是Caffe的模型,不支持這一層,將名字改爲IPlugin是能夠識別的,固然還須要一些額外的操做,說明這一層的操做是對應哪一個Plugin的實現;而對於Uff是不支持Plugin的Parser,也就是說TensorFlow的模型中有一個Plugin的話,是不能從模型中識別出來的,這時候須要用到addPlugin()的方法去定義網絡中Plugin的相關信息。


 


IPlugin接口中須要被重載的函數有如下幾類:


1) 肯定輸出:一個是經過int getNbOutput()獲得output輸出的數目,即用戶所定義的一層有幾個輸出。另外一個是經過Dims getOutputDimensions (int index, const Dims* inputs, int nbInputDims) 獲得整個輸出的維度信息,你們可能不必定遇到有多個輸出,通常來說只有一個輸出,可是你們在作檢測網絡的時候可能會遇到多個輸出,一個輸出是實際的檢測目標是什麼,另外一個輸出是目標的數目,可能的過個輸出須要設定Dimension的大小。


2) 層配置:經過void configure() 實現構建推斷(Inference) engine時模型中相應的參數大小等配置,configure()只是在構建的時候調用,這個階段肯定的東西是在運行時做爲插件參數來存儲、序列化/反序列化的。


3)  資源管理:經過void Initialize()來進行資源的初始化,void terminate()來銷燬資源,甚至中間可能會有一些臨時變量,也可使用這兩個函數進行初始化或銷燬。須要注意的是,void Initialize()和void terminate()是在整個運行時都被調用的,並非作完一次推斷(Inference)就去調用terminate。至關於在線的一個服務,服務起的時候會調用void Initialize(),而服務止的時候調用void terminate(),可是服務會進進出出不少sample去作推斷(Inference)。


4)  執行(Execution):void enqueue()來定義用戶層的操做


5) 序列化和反序列化:這個過程是將層的參數寫入到二進制文件中,須要定義一些序列化的方法。經過size_t getSerializationSize()得到序列大小,經過void serialize()將層的參數序列化到緩存中,經過PluginSample()從緩存中將層參數反序列化。須要注意的是,TensorRT沒有單獨的反序列化的API,由於不須要,在實習構造函數的時候就完成了反序列化的過程


6)  從Caffe Parser添加Plugin:首先經過Parsernvinfer1::IPlugin* createPlugin()實現nvcaffeparser1::IPlugin 接口,而後傳遞工廠實例到ICaffeParser::parse(),Caffe的Parser才能識別


7) 運行時建立插件:經過IPlugin* createPlugin()實現nvinfer1::IPlugin接口,傳遞工廠實例到IInferRuntime::deserializeCudaEngine()


 


4、用戶自定義層-YOLOv2實例


 


咱們用一個例子YOLOv2來給你們講一下完整的流程:


 


準備:首先要準備 Darknet framework(https://github.com/pjreddie/darknet.git),它是一個很是小衆的cfg的形式,而後須要準備須要訓練的數據集(VOC 2007 & VOC 2012),測試的指令以下:


./darknet detector test cfg/voc.data cfg/yolo-voc-relu.cfg \


backup/yolo-voc-relu_final.weights \ data/dog.jpg


 


模型轉換:以下圖所示,根據darknet的配置文件生成caffe的prototxt文件,注意使用ReLu而不是leaky-ReLu;另外darknet中存儲順序不一樣,首先存儲偏移;darknet的配置文件中padding的意義不一樣,pad = 1表示有padding,darknet中padding的大小是Kernel的大小除以2。


 




 


如下是darknet cuDNN和TensorRT FP32的性能對比,FP32是4.8ms,而Darknet是11.3ms。


 




 


5、低精度的推斷(Inference)


 


TensorRT經過使用Pascal GPU低精度的技術,實現高性能。如下是FP16和INT8兩種類型的性能對比。


 




 


1.  FP16 推斷(Inference)


TensorRT支持高度自動化的FP16推斷(Inference),解析模型要將模型的的數據類型設置爲DataType::kHALF,同時經過builder- >setHalf2Mode(true)指令將推斷(Inference)設置爲FP16的模式。須要注意兩點,一點是FP16推斷(Inference)不須要額外的輸入,只須要輸入預先訓練好的FP32模型,另外一點是目前只有Tesla P100/V100支持原生的FP16。


下圖展現了將模型從FP32轉換成FP16,並以FP16的形式存儲的過程:


 




 


2.  INT8 推斷(Inference)


 


對於INT8 推斷(Inference),須要生成一個校準表來量化模型。接下來主要關注INT8推斷(Inference)的幾個方面,即:如何生成校準表,如何使用校準表,和INT8推斷(Inference)實例。


 


1)  如何生成校準表?


校準表的生成須要輸入有表明性的數據集, 對於分類任務TensorRT建議輸入五百張到一千張有表明性的圖片,最好每一個類都要包括。生成校準表分爲兩步:第一步是將輸入的數據集轉換成batch文件;第二步是將轉換好的batch文件喂到TensorRT中來生成基於數據集的校準表,能夠去統計每一層的狀況。


 


2)   如何使用校準表?


校準這個過程若是要跑一千次是很昂貴的,因此TensorRT支持將其存入文檔,後期使用能夠從文檔加載,其中存儲和加載的功能經過兩個方法來支持,即writeCalibrationCache和readCalibrationCache。最簡單的實現是從write()和read()返回值,這樣就必須每次執行都作一次校準。若是想要存儲校準時間,須要實現用戶自定義的write/read方法,具體的實現能夠參考TensorRT中的simpleINT8實例。


 


3)   INT8推斷(Inference)實例


經過下圖的實例能夠發現,在YOLOv2實例中,使用TensorRT INT8作推斷(Inference)的性能能夠達到2.34ms。


 




 


下圖展現了用ResNet50中FP32和INT8的性能對比,能夠發現,對於P4卡,在bachsize是64的時候,INT8推斷(Inference)大概能夠達到1720fps,相對於FP32有3.6倍的加速,這個是至關可觀的。


 




 


至於你們關心的精度問題對比(以下圖),INT8經過用5張圖,10張圖,50張圖去修正,精度相差基本上都是在百分之零點零幾,這個效果是很是好的。


 




 


最後總結一下TensorRT的優勢:


1. TensorRT是一個高性能的深度學習推斷(Inference)的優化器和運行的引擎;


2. TensorRT支持Plugin,對於不支持的層,用戶能夠經過Plugin來支持自定義建立;


3. TensorRT使用低精度的技術得到相對於FP32二到三倍的加速,用戶只須要經過相應的代碼來實現。

————————————————

版權聲明:本文爲CSDN博主「hy-lscj」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。

原文連接:https://blog.csdn.net/qq_33869371/article/details/87929419


本文分享自微信公衆號 - IT民工技術之路(python_er)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索