TensorRT學習

tensorrt加速推理整到一半還沒整明白。由於另外一個項目緊急,寫了個簡單的進展彙報給同事,由同事接着作下去。等之後有空了徹底弄明白tensorrt,再回來修改這篇文章。html

TensorRT當前進展python

(本文前4節爲已作工做總結,可直接跳過,看「5 當前進展」,並開展下一步工做!)c++

1  TensorRT的基本功能git

TensorRT是NVIDIA開發的一個能夠在NVIDIA旗下的GPU上進行高性能推理的C++庫,是一個高性能推理優化引擎。github

其核心庫是使用c++去加速NVIDIA生產的GPU,具備python API。它能夠加速的框架模型有:tensorflow、Caffe、Pytorch、MXNet等。網絡

它能夠吸取在這些流行框架上受過訓練的神經網絡,優化神經網絡計算,生成一個輕量級的運行時引擎,而後它將在這些GPU平臺上最大限度地提升吞吐量、延遲和性能框架

1.1  工做原理async

主要的優化模型工做集中在:ide

1)分析圖結構中沒有用到的輸出layer,對網絡層進行合併。函數

2)融合卷積操做、bias和ReLU操做。

3)把有類似參數的操做和有相同輸入源的tensor聚合。

4)經過直接將layer的輸出對應到最終的destination,這樣融合了級聯層。

1.2 官方指導

https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/

2  須要的庫

2.1  tensorflow、tensorrt

已安裝

2.2  pycuda

已安裝

2.3  uff、graphsurgeon

已安裝

準備工做

3.1  pb文件

       以keras訓練出的yolov3_tiny.h5爲例,在Nano中/Documents/1tensorrt_pb_uff文件夾下,運行first_step_freeze_model.py進行轉換:

python3 first_step_freeze_model.py --model=「yolov3_tiny.h5」 —output=「yolov3_tiny.pb」

       (這個好像只能對yolo_tiny轉.pb文件,yolo不行)

3.2  pb文件轉uff文件

       使用自帶的convert_to_uff工具轉uff文件:

python3 /usr/lib/python3.6/dist-packages/uff/bin/convert_to_uff.py --input-file yolov3_tiny.pb

4  tensorrt基本流程

4.1  導入模型

4.1.1創造builder和network。

IBuilder* builder=createInferBuilder(gLogger);

nvinfer1::INetworkDefinition* network=builder->createNetwork();

4.1.2創造parse

使用parse導入模型填充網絡。

parser->parse(args);

4.1.3導入caffe和tensorflow、ONNX模型,能夠參考官網的指導。

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

4.1.4創造engine

有了網絡結構後能夠創造engine了。builder有兩個重要的屬性,分別是batchsize和worksize。

2 使用builder object創建引擎。

一、builder->setMaxBatchSize(maxBatchSize);

二、builder->setMaxWorkspaceSize(1 << 20);

三、ICudaEngine* engine = builder->buildCudaEngine(*network);

釋放空間:

engine->destroy();

network->destroy();

builder->destroy();

4.3序列化模型

序列化和反序列化是能夠自由選擇的,使用序列化模型的主要緣由是使用讀取模型定義網絡再創造engine是很耗時的操做,序列化後能夠避免每次 都須要從新創建engine。

當engine創建了以後,能夠將其序列化保存下來爲之後使用。

注意:序列化的模型在不一樣的模型和tensorRT的版本之間是不可以相互使用的。

序列化:

IHostMemory *serializedModel=engine->serialize();

serializedModel->destroy();

反序列化:

IRuntime* runtime = createInferRuntime(glogger);

ICudaEngine* engine = runtime->deserializeCudaEngin(modelData,modelSize, nullptr)

4.3進行預測

一、IExecutionContext *context = engine->createExecutionContext();

二、int inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME);

int outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME);

三、void* buffers[2];

buffers[inputIndex] = inputbuffer;

buffers[outputIndex] = outputBuffer;

四、context.enqueue(batchSize, buffers, stream, nullptr);

當前進展

5.1  tensorRT_mnist_example-master代碼分析

       代碼github地址爲:https://github.com/junyu0704/tensorRT_mnist_example。運行前須要編譯(此步已完成,不須要再作)。

       如下爲代碼簡介。

5.1.1  mnist.py

       訓練mnist,權重文件保存爲mnist.pb。

5.1.2  mnist_pred.py

       對mnist.py中訓練出的mnist.pb,進行tensorrt優化推理,而後再進行預測。

5.2  mnist_pred.py代碼分析

       優化推理主要有三步:第一步,find_data查找數據,事實上就是一個參數解析函數;第二步,build_engine建立引擎;第三步,inference推理。

5.2.1  find_data查找數據

事實上就是一個參數解析函數,定義parser解析器。

5.2.2  build_engine建立引擎

建立推理引擎,對網絡進行推理解析

with trt.Builder(TRT_LOGGER) as builder, builder.create_network() as network, trt.UffParser() as parser:

5.2.3  inference推理

       推理共5行代碼。

# 將數據移動到GPU

[cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs]

# 執行inference.

context.execute_async(batch_size=batch_size,bindings=bindings, stream_handle=stream.handle)

# 將結果從 GPU寫回到host端

[cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs]

# 同步stream

stream.synchronize()

# 返回host端的輸出結果

return [out.host for out in outputs]

相關文章
相關標籤/搜索