trt_model.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import pycuda.autoinit
  2. import pycuda.driver as cuda
  3. import tensorrt as trt
  4. import numpy as np
  5. EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
  6. TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
  7. def GiB(val):
  8. return val * 1 << 30
  9. def ONNX_to_TRT(onnx_model_path=None,trt_engine_path=None,fp16_mode=False):
  10. """
  11. 仅适用TensorRT V8版本
  12. 生成cudaEngine,并保存引擎文件(仅支持固定输入尺度)
  13. fp16_mode: True则fp16预测
  14. onnx_model_path: 将加载的onnx权重路径
  15. trt_engine_path: trt引擎文件保存路径
  16. """
  17. builder = trt.Builder(TRT_LOGGER)
  18. network = builder.create_network(EXPLICIT_BATCH)
  19. parser = trt.OnnxParser(network, TRT_LOGGER)
  20. config = builder.create_builder_config()
  21. config.max_workspace_size=GiB(1)
  22. if fp16_mode:
  23. config.set_flag(trt.BuilderFlag.FP16)
  24. with open(onnx_model_path, 'rb') as model:
  25. assert parser.parse(model.read())
  26. serialized_engine=builder.build_serialized_network(network, config)
  27. with open(trt_engine_path, 'wb') as f:
  28. f.write(serialized_engine) # 序列化
  29. print('TensorRT file in ' + trt_engine_path)
  30. print('============ONNX->TensorRT SUCCESS============')
  31. class TrtModel():
  32. '''
  33. TensorRT infer
  34. '''
  35. def __init__(self,trt_path):
  36. self.ctx=cuda.Device(0).make_context()
  37. stream = cuda.Stream()
  38. TRT_LOGGER = trt.Logger(trt.Logger.INFO)
  39. runtime = trt.Runtime(TRT_LOGGER)
  40. # Deserialize the engine from file
  41. with open(trt_path, "rb") as f:
  42. engine = runtime.deserialize_cuda_engine(f.read())
  43. context = engine.create_execution_context()
  44. host_inputs = []
  45. cuda_inputs = []
  46. host_outputs = []
  47. cuda_outputs = []
  48. bindings = []
  49. for binding in engine:
  50. print('bingding:', binding, engine.get_binding_shape(binding))
  51. size = trt.volume(engine.get_binding_shape(binding)) * engine.max_batch_size
  52. dtype = trt.nptype(engine.get_binding_dtype(binding))
  53. # Allocate host and device buffers
  54. host_mem = cuda.pagelocked_empty(size, dtype)
  55. cuda_mem = cuda.mem_alloc(host_mem.nbytes)
  56. # Append the device buffer to device bindings.
  57. bindings.append(int(cuda_mem))
  58. # Append to the appropriate list.
  59. if engine.binding_is_input(binding):
  60. self.input_w = engine.get_binding_shape(binding)[-1]
  61. self.input_h = engine.get_binding_shape(binding)[-2]
  62. host_inputs.append(host_mem)
  63. cuda_inputs.append(cuda_mem)
  64. else:
  65. host_outputs.append(host_mem)
  66. cuda_outputs.append(cuda_mem)
  67. # Store
  68. self.stream = stream
  69. self.context = context
  70. self.engine = engine
  71. self.host_inputs = host_inputs
  72. self.cuda_inputs = cuda_inputs
  73. self.host_outputs = host_outputs
  74. self.cuda_outputs = cuda_outputs
  75. self.bindings = bindings
  76. self.batch_size = engine.max_batch_size
  77. def __call__(self,img_np_nchw):
  78. '''
  79. TensorRT推理
  80. :param img_np_nchw: 输入图像
  81. '''
  82. self.ctx.push()
  83. # Restore
  84. stream = self.stream
  85. context = self.context
  86. engine = self.engine
  87. host_inputs = self.host_inputs
  88. cuda_inputs = self.cuda_inputs
  89. host_outputs = self.host_outputs
  90. cuda_outputs = self.cuda_outputs
  91. bindings = self.bindings
  92. np.copyto(host_inputs[0], img_np_nchw.ravel())
  93. cuda.memcpy_htod_async(cuda_inputs[0], host_inputs[0], stream)
  94. context.execute_async(batch_size=self.batch_size, bindings=bindings, stream_handle=stream.handle)
  95. cuda.memcpy_dtoh_async(host_outputs[0], cuda_outputs[0], stream)
  96. stream.synchronize()
  97. self.ctx.pop()
  98. return host_outputs[0]
  99. def destroy(self):
  100. # Remove any context from the top of the context stack, deactivating it.
  101. self.ctx.pop()