TensorRT深度學習推理架構介紹__深度學習

來源:互聯網
上載者:User

一.  產生背景

       深度學習的發展帶動了一批深度學習架構,caffe、tensorflow、pytorch等,對於計算量龐大的CNN,效率一直是大家所關注的,接觸過深度網路壓縮的同學應該知道網路壓縮最關鍵的兩個思路,剪枝和量化。

       TensorRT就是量化,將FP32位權值資料最佳化為 FP16 或者 INT8,而推理精度不發生明顯的降低。

       關於TensorRT首先要清楚以下幾點:

1. TensorRT是NVIDIA開發的深度學習推理工具,只支援推理,不支援訓練;

   目前TensorRT3已經支援Caffe、Caffe2、TensorFlow、MxNet、Pytorch等主流深度學習庫;

2. TensorRT底層針對NVIDIA顯卡做了多方面的最佳化,不僅僅是量化,可以和 CUDA CODEC SDK 結合使用,

    也就是另一個開發包DeepStream;

3. TensorRT獨立於深度學習架構,通過解析架構檔案來實現,不需要額外安裝DL庫;

    參考示意圖:


二. 使用TensorRT

       上面是TensorRT的介紹,也可以參考官方文檔,更權威一些:https://developer.nvidia.com/tensorrt

       下面以Caffe為例介紹TensorRT的使用:

1. caffeToGIEModel - 將 caffe model 轉換到 TensorRT 格式

    + void caffeToGIEModel( const std::string& deployFile,    // name for caffe prototxt
const std::string& modelFile,    // name for model 
const std::vector<std::string>& outputs,   // network outputs
unsigned int maxBatchSize,   // batch size - NB must be at least as large as the batch we want to run with)
IHostMemory *&gieModelStream)           // output buffer for the GIE model
  {

// 1.建立builderIBuilder* builder = createInferBuilder(gLogger);// 2.解析caffe模型,儲存到 NetworkINetworkDefinition* network = builder->createNetwork();ICaffeParser* parser = createCaffeParser();const IBlobNameToTensor* blobNameToTensor = parser->parse(locateFile(deployFile,                 directories).c_str(), locateFile(modelFile, directories).c_str(),*network, DataType::kFLOAT);// 3.指定輸出Tensorfor (auto& s : outputs)    network->markOutput(*blobNameToTensor->find(s.c_str()));// 4.構建enginebuilder->setMaxBatchSize(maxBatchSize);builder->setMaxWorkspaceSize(1 << 20);ICudaEngine* engine = builder->buildCudaEngine(*network);assert(engine);// 5.銷毀parsernetwork->destroy();parser->destroy();// 6.將engine序列化到GIE,退出gieModelStream = engine->serialize();engine->destroy();builder->destroy();
  }

2. 執行過程 main

// 1.從caffe模型建立GIE模型,序列化到流IHostMemory *gieModelStream{nullptr};caffeToGIEModel("mnist.prototxt", "mnist.caffemodel", std::vector < std::string > { OUTPUT_BLOB_NAME }, 1, gieModelStream);// x.資料擷取(略)// x.解析mean檔案(略)// 2.還原序列化,得到Runtime engine IRuntime* runtime = createInferRuntime(gLogger);ICudaEngine* engine = runtime->deserializeCudaEngine(gieModelStream->data(), gieModelStream->size(), nullptr);if (gieModelStream) gieModelStream->destroy();// 3.建立上下文IExecutionContext *context = engine->createExecutionContext();// 4.運行inferencefloat prob[OUTPUT_SIZE];doInference(*context, data, prob, 1);// 5.銷毀enginecontext->destroy();engine->destroy();runtime->destroy();
3. 推理過程 doInference
void doInference(IExecutionContext& context, float* input, float* output, int batchSize)
{
const ICudaEngine& engine = context.getEngine();// 傳遞給引擎的輸入輸出buffer指標- 需要精確的 IEngine::getNbBindings(),這裡1個輸入+1個輸出assert(engine.getNbBindings() == 2);void* buffers[2];// 1.為了綁定buffer,需要知道輸入和輸出tensor的namesint inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME), outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME);// 2.建立 GPU buffer 和 streamCHECK(cudaMalloc(&buffers[inputIndex], batchSize * INPUT_H * INPUT_W * sizeof(float)));CHECK(cudaMalloc(&buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float)));cudaStream_t stream;CHECK(cudaStreamCreate(&stream));// 3.通過DMA 輸入到 GPU,  非同步之行batch,並通過DMA回傳CHECK(cudaMemcpyAsync(buffers[inputIndex], input, batchSize * INPUT_H * INPUT_W * sizeof(float), cudaMemcpyHostToDevice, stream));context.enqueue(batchSize, buffers, stream, nullptr);CHECK(cudaMemcpyAsync(output, buffers[outputIndex], batchSize * OUTPUT_SIZE*sizeof(float), cudaMemcpyDeviceToHost, stream));cudaStreamSynchronize(stream);// 4.釋放 stream 和 buffercudaStreamDestroy(stream);CHECK(cudaFree(buffers[inputIndex]));CHECK(cudaFree(buffers[outputIndex]));

三. 模型轉化

       TensorRT3.0 雖然號稱支援 Caffe、caffe2、TensorFlow、Pytorch等網路模型,實際上例子只提供了Caffe和TensorFlow的直接支援。

       對於caffe的支援比較簡單,可以直接通過載入deploy file和caffemodel來做,而對於tensorflow則是通過轉換為uff格式來載入,可以參考範例程式。

        網路模型轉換及部署可以分為三個步驟:

1)訓練模型並儲存為.pb檔案;

2)將.pb檔案轉成.uff格式;

3)利用TensorRT載入並運行模型;

        對於caffe2,暫時沒找到比較好的轉換工具,有經驗的朋友可以探討。

四. 關於統一模型的討論
       在當下深度學習架構肆虐的情況下,tensorflow、pytorch、caffe、caffe2、mxnet、CNTK等等,都有自己的使用者群,不同架構之間的格式為交流及資料共用帶來了巨大的弊端,各種轉碼,另攻城獅不勝其煩,有競爭必然有結盟,大一統是必然結果。

       比如我們來看從 caffe -> caffe2模型格式轉換過程

       可以採用caffe2提供的轉換指令碼 caffe_translator.py

       python -m caffe2.python.caffe_translator deploy.prototxt pretrained.caffemodel

       不同架構之間通過指令碼進行格式轉換。 NNVM & ONNX

       NNVM來自於陳天奇團隊,對其比較直觀的描述,我們可以參考:

       TVM和之前發布的模組化深度學習系統NNVM一起,“組成深度學習到各種硬體的完整最佳化工具鏈”。

       與LLVM一致,可以理解為將不同語言(DL架構)進行編譯、最佳化、連結的 編譯器。其目的在於將多個DL架構的使用者進行整合,與TF進行PK(TF底層也有同樣的功能模組)。

       或者說,基於NNVM,你可以實現一套自己的深度學習架構(利用tinyflow),代碼只需要2000行,可以實現到各種硬體的快速編譯部署,聽著就很Tool。

       ONNX是Facebook、微軟聯合推出的一個開放標準,旨在不同架構之間完成互操作;

       聽起來像NNVM如此宏大,將來是一個什麼樣的關係,還有待於進一步跟進。

       就目前來看,ONNX首先著力於結果模型的轉化,也就是推理部分。

       (關於標準和入口向來是兵家必爭,目前階段不需要盲目投入過多精力,靜等某方勝出方為上冊,形勢很快明朗)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.