Python api構建tensorrt加速模型的步驟詳解
1.用TensorRT中network模塊定義網絡模型2.調用TensorRT構建器從網絡創建優化的運行時引擎3.采用序列化和反序列化操作以便在運行時快速重建4.將數據喂入engine中進行推理
二、Python api和C++ api在實現網絡加速有什么區別?個人看法1.python比c++更容易讀并且已經有很多包裝很好的科學運算庫(numpy,scikit等),2.c++是接近硬件的語言,運行速度比python快很多很多,因為python是解釋性語言c++是編譯型語言
三、構建TensorRT加速模型 3.1 加載tensorRT1.import tensorrt as trt2.為tensorrt實現日志報錯接口方便報錯,在下面的代碼我們只允許警告和錯誤消息才打印,TensorRT中包含一個簡單的日志記錄器Python綁定。
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
3.2 創建網絡簡單來說就是用tensorrt的語言來構建模型,如果自己構建的話,主要是靈活但是工作量so large,一般還是用tensorrt parser來構建(1)Caffe框架的模型可以直接用tensorrt內部解釋器構建(2)除caffe,TF模型以外其他框架,先轉成ONNX通用格式,再用ONNX parser來解析(3)TF可以直接通過tensorrt內部的UFF包來構建,但是tensorrt uff包中并支持所有算子(4)自己將wts放入自己構建的模型中,工作量so large,但是很靈活。
3.3 ONNX構建engine因為博主用的ONNXparser來構建engine的,下面就介紹以下ONNX構建engine,步驟如下:(1)導入tensorrt
import tensorrt as trt
(2)創建builder,network和相應模型的解釋器,這里是onnxparser
EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)with builder = trt.Builder(TRT_LOGGER) as builder,builder.create_network(EXPLICIT_BATCH) as network, trt.OnnxParser(network, TRT_LOGGER) as parser:with open(model_path, ’rb’) as model:parser.parse(model.read())
這個代碼的主要意思是,構建報錯日志,創建build,network和onnxparser,然后用parser讀取onnx權重文件。
3.3.1 builder介紹
builder功能之一是搜索cuda內核目錄,找到最快的cuda以求獲得最快的實現,因此有必要使用相同的GPU進行構建(相同的操作,算子進行融合,減少IO操作),engine就是在此基礎上運行的,builder還可以控制網絡以什么精度運行(FP32,FP16,INT8),還有兩個特別重要的屬性是最大批處理大小和最大工作空間大小。
builder.max_batch_size = max_batch_sizebuilder.max_workspace_size = 1 << 20
3.3.2序列化模型
序列化和反序列化模型的主要是因為network和定義創建engine很耗時,因此可以通過序列化一次并在推理時反序列化一次來避免每次應用程序重新運行時重新構建引擎。note:序列化引擎不能跨平臺或TensorRT版本移植。引擎是特定于它們所構建的GPU模型(除了平臺和TensorRT版本)代碼如下:
#序列化模型到模型流serialized_engine = engine.serialize()#反序列化模型流去執行推理,反序列化需要創建一個運行時對象with trt.Runtime(TRT_LOGGER) as runtime:engine = runtime.deserialize_cuda_engine(serialized_engine)#也可以將序列化模型writewith open(“sample.engine”, “wb”) as f:f.write(engine.serialize())#然后再讀出來進行反序列化with open(“sample.engine”, “rb”) as f, trt.Runtime(TRT_LOGGER) as runtime:engine = runtime.deserialize_cuda_engine(f.read())
3.3.3執行推理過程
note:下面過程的前提是已經創建好了engine
# 為輸入和輸出分配一些主機和設備緩沖區:#確定尺寸并創建頁面鎖定內存緩沖區h_input = cuda.pagelocked_empty(trt.volume(engine.get_binding_shape(0)),dtype=np.float32)h_output =cuda.pagelocked_empty(trt.volume(engine.get_binding_shape(1)),dtype=np.float32)#為輸入和輸出分配設備內存d_input = cuda.mem_alloc(h_input.nbytes)d_output = cuda.mem_alloc(h_output.nbytes)#創建一個流,在其中復制輸入/輸出并運行推斷stream = cuda.Stream()
# 創建一些空間來存儲中間激活值,因為engine保存了network定義和訓練時的參數,這些都是構建的上下文執行的。with engine.create_execution_context() as context: # 輸入數據傳入GPUcuda.memcpy_htod_async(d_input, h_input, stream) # 執行推理. context.execute_async(bindings=[int(d_input), int(d_output)], stream_handle=stream.handle) # 將推理后的預測結果從GPU上返回. cuda.memcpy_dtoh_async(h_output, d_output, stream) # 同步流 stream.synchronize() # 返回主機輸出 return h_output
note:一個engine可以有多個執行上下文,允許一組權值用于多個重疊推理任務。例如,可以使用一個引擎和一個上下文在并行CUDA流中處理圖像。每個上下文將在與引擎相同的GPU上創建。
到此這篇關于Python api構建tensorrt加速模型的文章就介紹到這了,更多相關Python api tensorrt加速模型內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!
相關文章: