Relay TensorRT 集成
介绍
NVIDIA TensorRT 是一个用于优化深度学习推理的库。这种集成尽可能多地将算子从 Relay 迁移到 TensorRT,无需对 schedule 调优,即可提升 NVIDIA GPU 的性能。
本教程演示如何安装 TensorRT 以及如何构建 TVM,来启用 TensorRT BYOC 和 runtime。此外,还给出了示例代码,演示了如何用 TensorRT 编译和运行 ResNet-18 模型,以及如何配置编译和 runtime 设置。最后,还记录了支持的算子,以及如何扩展集成来支持其他算子。
安装 TensorRT
若要下载 TensorRT,需要创建一个 NVIDIA 开发者帐户,可参考 NVIDIA 的文档来了解更多信息:https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html。若有 Jetson 设备(如 TX1、TX2、Xavier 或 Nano),则 TensorRT 可能已由 JetPack SDK 安装到设备了 。
安装 TensorRT 的两种方法:
- 通过 deb 或 rpm 包系统安装。
- 通过 tar 文件安装。
用 tar 文件的安装方法,必须将解压后的 tar 路径传到 USE_TENSORRT_RUNTIME=/path/to/TensorRT 中;用系统安装的方法,USE_TENSORRT_RUNTIME=ON 会自动定位安装路径。
使用 TensorRT 支持构建 TVM
TVM 的 TensorRT 集成有两个单独的构建标志,这些标志启用了交叉编译:USE_TENSORRT_CODEGEN=ON —— 在支持 TensorRT 的主机上构建模块; USE_TENSORRT_RUNTIME=ON —— 使得边界设备上的 TVM runtime 能够执行 TensorRT 模块。若要编译并执行具有相同 TVM 构建的模型,则应启用这两者。
- USE_TENSORRT_CODEGEN=ON/OFF - 使得无需任何 TensorRT 库即可编译 TensorRT 模块。
- USE_TENSORRT_RUNTIME=ON/OFF/path-to-TensorRT - 启用 TensorRT runtime 模块,它用已安装的 TensorRT 库来构建 TVM。
config.cmake 文件中的设置示例:
set(USE_TENSORRT_CODEGEN ON)
set(USE_TENSORRT_RUNTIME /home/ubuntu/TensorRT-7.0.0.11)
使用 TensorRT 构建和部署 ResNet-18
从 MXNet ResNet-18 模型中创建 Relay 计算图:
import tvm
from tvm import relay
import mxnet
from mxnet.gluon.model_zoo.vision import get_model
dtype = "float32"
input_shape = (1, 3, 224, 224)
block = get_model('resnet18_v1', pretrained=True)
mod, params = relay.frontend.from_mxnet(block, shape={'data': input_shape}, dtype=dtype)
为 TensorRT 计算图进行注释和分区,TensorRT 集成的所有操作都被标记并迁移到 TensorRT,其余的操作将通过常规的 TVM CUDA 编译和代码生成。
from tvm.relay.op.contrib.tensorrt import partition_for_tensorrt
mod, config = partition_for_tensorrt(mod, params)
用 partition_for_tensorrt 返回的新模块和配置来构建 Relay 计算图。target 必须始终是 CUDA target。partition_for_tensorrt
会自动填充配置中所需的值,因此无需修改它——只需将其传给 PassContext,就可在编译时被读取到。
target = "cuda"
with tvm.transform.PassContext(opt_level=3, config={'relay.ext.tensorrt.options': config}):
lib = relay.build(mod, target=target, params=params)
导出模块:
lib.export_library('compiled.so')
在目标机器上加载模块并运行推理,这个过程必须确保启用 USE_TENSORRT_RUNTIME
。第一次运行时因为要构建 TensorRT 引擎,所以需要较长时间。
dev = tvm.cuda(0)
loaded_lib = tvm.runtime.load_module('compiled.so')
gen_module = tvm.contrib.graph_executor.GraphModule(loaded_lib['default'](dev))
input_data = np.random.uniform(0, 1, input_shape).astype(dtype)
gen_module.run(data=input_data)