本章說明 Python API 的基本用法,假設您從 ONNX 模型開始。onnx_resnet50.py示例更詳細地說明了這個用例。
Python API 可以通過tensorrt模塊訪問:
import tensorrt as trt
4.1. The Build Phase
要創建構建器,您需要首先創建一個記錄器。 Python 綁定包括一個簡單的記錄器實現,它將高于特定嚴重性的所有消息記錄到stdout
。
logger = trt.Logger(trt.Logger.WARNING)
或者,可以通過從ILogger
類派生來定義您自己的記錄器實現:
class MyLogger(trt.ILogger): def __init__(self): trt.ILogger.__init__(self) def log(self, severity, msg): pass # Your custom logging implementation here logger = MyLogger()
然后,您可以創建一個構建器:
builder = trt.Builder(logger)
4.1.1. Creating a Network Definition in Python
創建構建器后,優化模型的第一步是創建網絡定義:
network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))
為了使用 ONNX 解析器導入模型,需要EXPLICIT_BATCH
標志。有關詳細信息,請參閱顯式與隱式批處理部分。
4.1.2. Importing a Model using the ONNX Parser
現在,需要從 ONNX 表示中填充網絡定義。您可以創建一個 ONNX 解析器來填充網絡,如下所示:
parser = trt.OnnxParser(network, logger)
然后,讀取模型文件并處理任何錯誤:
success = parser.parse_from_file(model_path) for idx in range(parser.num_errors): print(parser.get_error(idx)) if not success: pass # Error handling code here
4.1.3. Building an Engine
下一步是創建一個構建配置,指定 TensorRT 應該如何優化模型:
config = builder.create_builder_config()
這個接口有很多屬性,你可以設置這些屬性來控制 TensorRT 如何優化網絡。一個重要的屬性是最大工作空間大小。層實現通常需要一個臨時工作空間,并且此參數限制了網絡中任何層可以使用的最大大小。如果提供的工作空間不足,TensorRT 可能無法找到層的實現:
config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 20) # 1 MiB
指定配置后,可以使用以下命令構建和序列化引擎:
serialized_engine = builder.build_serialized_network(network, config)
將引擎保存到文件以供將來使用可能很有用。你可以這樣做:
with open(“sample.engine”, “wb”) as f: f.write(serialized_engine)
4.2. Deserializing a Plan
要執行推理,您首先需要使用Runtime接口反序列化引擎。與構建器一樣,運行時需要記錄器的實例。
runtime = trt.Runtime(logger)
然后,您可以從內存緩沖區反序列化引擎:
engine = runtime.deserialize_cuda_engine(serialized_engine)
如果您需要首先從文件加載引擎,請運行:
with open(“sample.engine”, “rb”) as f: serialized_engine = f.read()
4.3. Performing Inference
引擎擁有優化的模型,但要執行推理需要額外的中間激活狀態。這是通過IExecutionContext
接口完成的:
context = engine.create_execution_context()
一個引擎可以有多個執行上下文,允許一組權重用于多個重疊的推理任務。 (當前的一個例外是使用動態形狀時,每個優化配置文件只能有一個執行上下文。)
要執行推理,您必須為輸入和輸出傳遞 TensorRT 緩沖區,TensorRT 要求您在 GPU 指針列表中指定。您可以使用為輸入和輸出張量提供的名稱查詢引擎,以在數組中找到正確的位置:
input_idx = engine[input_name] output_idx = engine[output_name]
使用這些索引,為每個輸入和輸出設置 GPU 緩沖區。多個 Python 包允許您在 GPU 上分配內存,包括但不限于 PyTorch、Polygraphy CUDA 包裝器和 PyCUDA。
然后,創建一個 GPU 指針列表。例如,對于 PyTorch CUDA 張量,您可以使用data_ptr()
方法訪問 GPU 指針;對于 PolygraphyDeviceArray
,使用ptr
屬性:
buffers = [None] * 2 # Assuming 1 input and 1 output buffers[input_idx] = input_ptr buffers[output_idx] = output_ptr
填充輸入緩沖區后,您可以調用 TensorRT 的execute_async
方法以使用 CUDA 流異步啟動推理。
首先,創建 CUDA 流。如果您已經有 CUDA 流,則可以使用指向現有流的指針。例如,對于 PyTorch CUDA 流,即torch.cuda.Stream()
,您可以使用cuda_stream
屬性訪問指針;對于 Polygraphy CUDA 流,使用ptr
屬性。 接下來,開始推理:
context.execute_async_v2(buffers, stream_ptr)
通常在內核之前和之后將異步memcpy()
排入隊列以從 GPU 中移動數據(如果數據尚不存在)。
要確定內核(可能還有memcpy() )何時完成,請使用標準 CUDA 同步機制,例如事件或等待流。例如,對于 Polygraphy,使用:
stream.synchronize()
如果您更喜歡同步推理,請使用execute_v2
方法而不是execute_async_v2
。
關于作者
Ken He 是 NVIDIA 企業級開發者社區經理 & 高級講師,擁有多年的 GPU 和人工智能開發經驗。自 2017 年加入 NVIDIA 開發者社區以來,完成過上百場培訓,幫助上萬個開發者了解人工智能和 GPU 編程開發。在計算機視覺,高性能計算領域完成過多個獨立項目。并且,在機器人和無人機領域,有過豐富的研發經驗。對于圖像識別,目標的檢測與跟蹤完成過多種解決方案。曾經參與 GPU 版氣象模式GRAPES,是其主要研發者。
審核編輯:郭婷
-
gpu
+關注
關注
28文章
4909瀏覽量
130631 -
python
+關注
關注
56文章
4823瀏覽量
86143 -
CUDA
+關注
關注
0文章
122瀏覽量
14054
發布評論請先 登錄
DLP6500能否用Python編程進行開發,是否有API接口?
有關Python的解析
python代碼示例之基于Python的日歷api調用代碼實例

API-Shop-OCR-營業執照識別API接口Python調用示例代碼說明

評論