用NVIDIA-TensorRT构造深度神经网络
用NVIDIA-TensorRT構(gòu)造深度神經(jīng)網(wǎng)絡(luò)
Deploying Deep Neural Networks with NVIDIA TensorRT
NVIDIA TensorRT是一個(gè)用于生產(chǎn)環(huán)境的高性能深度學(xué)習(xí)推理庫(kù)。電源效率和響應(yīng)速度是部署的深度學(xué)習(xí)應(yīng)用程序的兩個(gè)關(guān)鍵指標(biāo),因?yàn)橹苯佑绊懹脩趔w驗(yàn)和所提供服務(wù)的成本。Tensor RT為運(yùn)行時(shí)性能自動(dòng)優(yōu)化訓(xùn)練的神經(jīng)網(wǎng)絡(luò),在Tesla P100 GPU上提供高達(dá)16倍的能效(性能/瓦),而普通的CPU專用深度學(xué)習(xí)推理系統(tǒng)(見(jiàn)圖1)。圖2顯示了NVIDIA Tesla P100和K80使用TensorRT和相對(duì)復(fù)雜的GoogLenet神經(jīng)網(wǎng)絡(luò)架構(gòu)運(yùn)行推理的性能。
在本文中,將向展示如何在基于GPU的部署平臺(tái)上使用Tensor RT從經(jīng)過(guò)訓(xùn)練的深層神經(jīng)網(wǎng)絡(luò)中獲得最佳的效率和性能。
深度學(xué)習(xí)訓(xùn)練和部署
用深層神經(jīng)網(wǎng)絡(luò)求解有監(jiān)督機(jī)器學(xué)習(xí)問(wèn)題涉及兩步過(guò)程。
第一步是利用gpu對(duì)海量標(biāo)記數(shù)據(jù)進(jìn)行深層神經(jīng)網(wǎng)絡(luò)訓(xùn)練。在這一步中,神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)數(shù)以百萬(wàn)計(jì)的權(quán)值或參數(shù),使其能夠?qū)⑤斎霐?shù)據(jù)示例映射到正確的響應(yīng)。由于目標(biāo)函數(shù)相對(duì)于網(wǎng)絡(luò)權(quán)值最小,訓(xùn)練需要在網(wǎng)絡(luò)中反復(fù)向前和向后傳遞。為了估計(jì)真實(shí)世界的性能,通常需要訓(xùn)練幾個(gè)模型,并根據(jù)訓(xùn)練期間沒(méi)有看到的數(shù)據(jù)驗(yàn)證模型的準(zhǔn)確性。
下一步——推理——使用經(jīng)過(guò)訓(xùn)練的模型根據(jù)新數(shù)據(jù)進(jìn)行預(yù)測(cè)。在此步驟中,在生產(chǎn)環(huán)境(如數(shù)據(jù)中心、汽車或嵌入式平臺(tái))中運(yùn)行的應(yīng)用程序中使用經(jīng)過(guò)最佳訓(xùn)練的模型。對(duì)于一些應(yīng)用,如自動(dòng)駕駛,推理是實(shí)時(shí)進(jìn)行的,因此高吞吐量是至關(guān)重要的。
Figure 3: Deep learning training to eployment workflow with NVIDIA DIGITS and Tensor RT.
要了解更多關(guān)于訓(xùn)練和推理之間的區(qū)別,請(qǐng)參閱Michael Andersch關(guān)于GPUs推理的文章。
目標(biāo)部署環(huán)境引入了訓(xùn)練環(huán)境中通常不存在的各種挑戰(zhàn)。例如,如果目標(biāo)是使用經(jīng)過(guò)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)感知其周圍環(huán)境的嵌入式設(shè)備,則通過(guò)該模型的正向推理將直接影響設(shè)備的總體響應(yīng)時(shí)間和功耗。優(yōu)化的關(guān)鍵指標(biāo)是功率效率:每瓦特的推理性能。
每瓦特性能也是最大化數(shù)據(jù)中心運(yùn)營(yíng)效率的關(guān)鍵指標(biāo)。在這種情況下,需要最小化在地理上和時(shí)間上完全不同的大量請(qǐng)求上使用的延遲和能量,這限制了形成大批量的能力。
NVIDIA TensorRT
Tensor RT是一個(gè)高性能的推理引擎,旨在為常見(jiàn)的深度學(xué)習(xí)應(yīng)用(如圖像分類、分割和目標(biāo)檢測(cè))提供最大的推理吞吐量和效率。Tensor RT優(yōu)化訓(xùn)練的神經(jīng)網(wǎng)絡(luò)以獲得運(yùn)行時(shí)性能,并為web/移動(dòng)、嵌入式和汽車應(yīng)用程序提供GPU加速推理。
Figure 4: The TensorRT workflow, showing the two key functionalities of TensorRT: the TensorRT neural network optimizer (middle) and the TensorRT target runtime (right).
TensorRT的使用分為兩個(gè)階段:構(gòu)建和部署。在構(gòu)建階段,TensorRT對(duì)網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行優(yōu)化,并生成一個(gè)用于計(jì)算深神經(jīng)網(wǎng)絡(luò)前向傳遞的優(yōu)化計(jì)劃。該計(jì)劃是一個(gè)優(yōu)化的目標(biāo)代碼,可以序列化并存儲(chǔ)在內(nèi)存或磁盤上。
部署階段通常采用長(zhǎng)時(shí)間運(yùn)行的服務(wù)或用戶應(yīng)用程序的形式,該服務(wù)或用戶應(yīng)用程序接受成批輸入數(shù)據(jù),通過(guò)對(duì)輸入數(shù)據(jù)執(zhí)行計(jì)劃來(lái)執(zhí)行推理,并返回成批輸出數(shù)據(jù)(分類、對(duì)象檢測(cè)等)。使用TensorRT,不需要在部署硬件上安裝和運(yùn)行深入學(xué)習(xí)框架。關(guān)于推理服務(wù)的批處理和管道的討論是另一篇文章的主題;相反,將重點(diǎn)討論如何使用TensorRT進(jìn)行推理。
TensorRT構(gòu)建階段
Tensor RT運(yùn)行時(shí)需要三個(gè)文件來(lái)部署分類神經(jīng)網(wǎng)絡(luò):
網(wǎng)絡(luò)體系結(jié)構(gòu)文件(deploy.prototxt文件),
訓(xùn)練重量(net.caffemodel網(wǎng)站),和
為每個(gè)輸出類提供名稱的標(biāo)簽文件。
此外,還必須定義批大小和輸出層。代碼清單1演示了如何將Caffe模型轉(zhuǎn)換為TensorRT對(duì)象。構(gòu)建者(第4-7行)負(fù)責(zé)讀取網(wǎng)絡(luò)信息。或者,如果不提供網(wǎng)絡(luò)體系結(jié)構(gòu)文件,則可以使用生成器定義網(wǎng)絡(luò)信息(deploy.prototxt文件)。
Tensor RT支持以下層類型。
· Convolution: 2D
· Activation: ReLU, tanh and sigmoid
· Pooling: max and average
· ElementWise: sum, product or max of two tensors
· LRN: cross-channel only
· Fully-connected: with or without bias
· SoftMax: cross-channel only
· Deconvolution
卷積:二維
激活:ReLU,tanh和sigmoid
池化:最大值和平均值
元素:兩個(gè)張量的和、積或最大值
LRN:僅跨信道
全連接:有無(wú)偏倚
SoftMax: 僅跨通道
反卷積
-
IBuilder* builder = createInferBuilder(gLogger);
-
// parse the caffe model to populate the network, then set the outputs
-
INetworkDefinition* network = builder->createNetwork();
-
CaffeParser parser;
-
auto blob_name_to_tensor = parser.parse(“deploy.prototxt”,
-
trained_file.c_str(),
-
*network,
-
DataType::kFLOAT);
-
// specify which tensors are outputs
-
network->markOutput(*blob_name_to_tensor->find(“prob”));
-
// Build the engine
-
builder->setMaxBatchSize(1);
-
builder->setMaxWorkspaceSize(1 << 30);
-
ICudaEngine* engine = builder->buildCudaEngine(*network);
還可以使用張量RT C++ API來(lái)定義沒(méi)有CAFE解析器的網(wǎng)絡(luò),如清單2所示。可以使用API定義任何受支持的層及其參數(shù)。可以定義在網(wǎng)絡(luò)之間變化的任何參數(shù),包括卷積層權(quán)重維度和輸出,以及池化層的窗口大小和步長(zhǎng)。
ITensor* in = network->addInput(“input”, DataType::kFloat, Dims3{…});
IPoolingLayer* pool = network->addPooling(in, PoolingType::kMAX,…);
在定義或加載網(wǎng)絡(luò)之后,必須如清單1的第13行所示指定輸出張量;在示例中,輸出是“prob”(表示概率)。接下來(lái),定義批大小(第16行),根據(jù)部署場(chǎng)景的不同,批大小可能有所不同。清單1使用的批處理大小為1,但可以選擇更大的批處理大小來(lái)滿足應(yīng)用程序需要和系統(tǒng)配置。下面,TensorRT執(zhí)行層優(yōu)化以減少推理時(shí)間。雖然這對(duì)API用戶是透明的,但是分析網(wǎng)絡(luò)層需要內(nèi)存,因此必須指定最大工作空間大小(第17行)。
最后一步是調(diào)用buildCudaEngine執(zhí)行層優(yōu)化,并根據(jù)提供的輸入和參數(shù)使用優(yōu)化的網(wǎng)絡(luò)構(gòu)建引擎。一旦模型轉(zhuǎn)換為TensorRT對(duì)象,就可以部署,可以在主機(jī)設(shè)備上使用,也可以保存并在其地方使用。
TensorRT對(duì)神經(jīng)網(wǎng)絡(luò)圖進(jìn)行了一些重要的轉(zhuǎn)換和優(yōu)化。首先,消除未使用輸出的層,以避免不必要的計(jì)算。接下來(lái),在可能的情況下,卷積層、偏壓層和ReLU層被融合形成一個(gè)單層。圖6顯示了圖5中原始網(wǎng)絡(luò)上垂直層融合的結(jié)果(融合層在圖6中標(biāo)記為CBR)。層融合提高了在GPU上運(yùn)行張量RT優(yōu)化網(wǎng)絡(luò)的效率。
Figure 5: An example convolutional neural network with multiple
convolutional and activation layers.
另一個(gè)轉(zhuǎn)換是水平層融合或?qū)泳酆?#xff0c;以及聚合層到各自輸出所需的劃分,如圖7所示。水平層融合通過(guò)合并具有相同源張量的層并應(yīng)用具有相似參數(shù)的相同操作來(lái)提高性能,從而產(chǎn)生一個(gè)更大的層以獲得更高的計(jì)算效率。圖7中的示例顯示了圖5中3個(gè)1×1 CBR層的組合,這些層將相同的輸入合并到一個(gè)更大的1×1 CBR層中。請(qǐng)注意,必須分解此層的輸出,以便從原始輸入圖饋入不同的后續(xù)層。
在TensorRT解析器讀取經(jīng)過(guò)訓(xùn)練的網(wǎng)絡(luò)和配置文件之后,TensorRT在構(gòu)建階段對(duì)API用戶透明地執(zhí)行轉(zhuǎn)換,如清單1所示。
TensorRT Deploy Phase
推理生成器(IBuilder)buildCudaEngine方法返回指向新的推理引擎運(yùn)行時(shí)對(duì)象(ICudaEngine)的指針。此運(yùn)行時(shí)對(duì)象已準(zhǔn)備好立即使用;或者,可以將其狀態(tài)序列化并保存到磁盤或?qū)ο蟠鎯?chǔ)以供分發(fā)。序列化的目標(biāo)代碼稱為計(jì)劃。
如前所述,與運(yùn)行時(shí)推斷引擎之間的批處理和流式處理數(shù)據(jù)的整個(gè)范圍超出了本文的范圍。清單3演示了使用推理機(jī)處理一批輸入數(shù)據(jù)以生成結(jié)果所需的步驟。
/ The execution context is responsible for launching the
// compute kernels
IExecutionContext context = engine->createExecutionContext();
// In order to bind the buffers, we need to know the names of the
// input and output tensors.
int inputIndex = engine->getBindingIndex(INPUT_LAYER_NAME),
int outputIndex = engine->getBindingIndex(OUTPUT_LAYER_NAME);
// Allocate GPU memory for Input / Output data
void buffers = malloc(engine->getNbBindings() * sizeof(void*));
cudaMalloc(&buffers[inputIndex], batchSize * size_of_single_input);
cudaMalloc(&buffers[outputIndex], batchSize * size_of_single_output);
// Use CUDA streams to manage the concurrency of copying and executing
cudaStream_t stream;
cudaStreamCreate(&stream);
// Copy Input Data to the GPU
cudaMemcpyAsync(buffers[inputIndex], input,
batchSize * size_of_single_input,
cudaMemcpyHostToDevice, stream);
// Launch an instance of the GIE compute kernelc
ontext.enqueue(batchSize, buffers, stream, nullptr);
// Copy Output Data to the Host
cudaMemcpyAsync(output, buffers[outputIndex],
batchSize * size_of_single_output,
cudaMemcpyDeviceToHost, stream));
// It is possible to have multiple instances of the code above
// in flight on the GPU in different streams.
// The host can then sync on a given stream and use the results
cudaStreamSynchronize(stream);
使用TensorRT最大化性能和效率
TensorRT 1.0現(xiàn)在可以免費(fèi)下載給NVIDIA開發(fā)者程序的成員。
NVIDIA TensorRT使能夠輕松地部署神經(jīng)網(wǎng)絡(luò),以最高的性能和效率為產(chǎn)品添加深度學(xué)習(xí)功能。在構(gòu)建階段,TensorRT識(shí)別優(yōu)化網(wǎng)絡(luò)的機(jī)會(huì),在部署階段,TensorRT以最小化延遲和最大吞吐量的方式運(yùn)行優(yōu)化的網(wǎng)絡(luò)。
如果運(yùn)行的是由數(shù)據(jù)中心服務(wù)器支持的web或移動(dòng)應(yīng)用程序,TensorRT的低開銷意味著可以部署更多樣、更復(fù)雜的模型,為產(chǎn)品添加智能,讓用戶感到高興。如果正在使用深入學(xué)習(xí)來(lái)創(chuàng)建下一代智能設(shè)備,TensorRT將幫助部署具有高性能、高精度和高能效的網(wǎng)絡(luò)。
此外,TensorRT使能夠利用gpu的能力,使用混合精度FP16數(shù)據(jù)執(zhí)行神經(jīng)網(wǎng)絡(luò)推理。在Tesla P100和jetsontx2gpu上使用FP16進(jìn)行神經(jīng)網(wǎng)絡(luò)推理可以減少一半的內(nèi)存使用,并提供更高的性能。
總結(jié)
以上是生活随笔為你收集整理的用NVIDIA-TensorRT构造深度神经网络的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 计算机视觉一些项目实战技术(续)
- 下一篇: 基于TensorRT 3的自动驾驶快速I