TRT8 一个大版本,8.4-、 8.5、 8.6(包含预览功能)却有很多变动,一不注意就发现很混乱,特备注此贴。建议具体case可以参考这个合集,真心安利:https://github.com/NVIDIA/trt-samples-for-hackathon-cn/tree/master/cookbook
版本差异概述
1)当前使用了8.4;
参考:
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/01-SimpleDemo/TensorRT8.0/main-cuda.py
2)8.5版本废弃了binding, 导致开内存代码不同;
参考:
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/01-SimpleDemo/TensorRT8.5/main.py
3)8.6版本以后支持dynamic shape统一个profile 用于不同的context。不再支持Pascal (P40),但完全改变了原来TRT engine必须绑定硬件和版本的要求,
现在可以解耦出来,但是有如下限制:
1、binding 改变
1)8.5前需要使用biding 接口
对应dynamic batch 多个profile 需要计算偏置。偏置或者说index 是针对profile (同一个engine)的不是针对context的。下图是一个engine里有3个profile,模型有4个输入1个输出,那么就有(4+1)*3 =15个binding。
engine.num_bindings 获取binding 总数
engine.binding_is_input 计算出input数量(每个profile里 算一个, engine.binding_is_inpu // nProfile 才是模型的输入个数)
context.set_binding_shape 设置输入输出的维度,如上面表格需要计算出pad和对应输入输出的顺序index
contex.get_binding_shape 获得对应profile 的输出的维度
context.execute_async_v2 执行推理,这里传入的第一个参数为输出输出GPU显存的地址,并且需要填满如上的表格,不用的位置填0。
完整代码:
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/08-Advance/MultiOptimizationProfile/main-BindingAPI.py
logger = trt.Logger(trt.Logger.ERROR)
engine = trt.Runtime(logger).deserialize_cuda_engine(engineString) # engineString 是二进制 open engine文件
nIO = engine.num_bindings
nInput = np.sum([engine.binding_is_input(i) for i in range(engine.num_bindings)])
nOutput = nIO - nInput
nIO, nInput, nOutput = nIO // nProfile, nInput // nProfile, nOutput // nProfile
context = engine.create_execution_context()
context.set_optimization_profile_async(index, stream)
bindingPad = nIO * index_profile # 计算binding 的偏置
context.set_binding_shape(bindingPad + 0, inputShape) # 第一个输入
outputShape = contex.get_binding_shape(bindingPad + nInput + 0) # 第一个输出
bufferList = [int(0) for b in bufferD[:bindingPad]] + \
[int(b) for b in bufferD[bindingPad:(bindingPad + nInput + nOutput)]] + \
[int(0) for b in bufferD[(bindingPad + nInput + nOutput):]]
context.execute_async_v2(bufferList, stream)
2)8.5 之后废弃binding
使用范例如下
engine.num_io_tensors 获取输入输出总个数
engine.get_tensor_name 获得对应的输入输出名字
engine.get_tensor_mode 判断是输入还是输出(trt.TensorIOMode.INPUT 、trt.TensorIOMode.OUTPUT)
context.set_input_shape 直接设置对应的形状,不再需要计算偏置
context.get_tensor_shape 直接获得输入输出(需要先设置输入自动计算)形状
context.set_tensor_address 绑定TRT 输入输出和 开辟的显存
context.execute_async_v3 来执行推理
完整代码:
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/08-Advance/MultiOptimizationProfile/main.py
logger = trt.Logger(trt.Logger.ERROR)
engine = trt.Runtime(logger).deserialize_cuda_engine(engineString) # engineString 是二进制 open engine文件
nIO = engine.num_io_tensors
lTensorName = [engine.get_tensor_name(i) for i in range(nIO)]
nInput = [engine.get_tensor_mode(lTensorName[i]) for i in range(nIO)].count(trt.TensorIOMode.INPUT)
context = engine.create_execution_context()
context.set_optimization_profile_async(index, stream)
context.set_input_shape(lTensorName[0], inputShape)
outputShape = context.get_tensor_shape(lTensorName[1])
context.set_tensor_address(lTensorName[0], int(cudart.cudaMalloc(nbytes)[1]))
context.execute_async_v3(0)
2、dynamic shape 性能
如果跨度较大建议使用多个配置文件,可以明显提升推理性能
参考:
Developer Guide :: NVIDIA Deep Learning TensorRT Documentation
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/09-BestPractice/UsingMultiOptimizationProfile/result-A30.md
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/09-BestPractice/UsingMultiOptimizationProfile/main.py
获得真实推理形状(假设真实为(3,150,150)),要使用
context.get_tensor_shape(0) (返回
(3, 150, 250)),而不是
engine.get_tensor_shape("foo”)
(返回
(3, -1, -1)
) 。
3、engine、 context、stream、profile(动态batch的配置文件)
一个engine 可以拥有多个context,共享一个权重。
可以将不同的context 放到不同的stream 中,实现并行。
一个context可以拥有多个profile(至少一个),但是8.6 0805预览特性前,一个profile 只能绑定一个context(context 和profile 需要错开使用)。
参考:
多流(8.6):
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/08-Advance/MultiStream/main.py
多上下文-动态batch(8.6+):
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/08-Advance/MultiContext/main.py
多上下文-动态batch(8.5-):
https://github.com/NVIDIA/trt-samples-for-hackathon-cn/blob/master/cookbook/08-Advance/MultiContext/main-MultiOptimizationProfile.py