Torch-TensorRT是一个允许用户在PyTorch环境中自动将PyTorch和TorchScript模块编译为TensorRT的软件包
项目描述
torch_tensorrt
PyTorch JIT 的即时编译 (AOT)
Torch-TensorRT 是一个针对 PyTorch/TorchScript 的编译器,通过 NVIDIA 的 TensorRT 深度学习优化器和运行时,针对 NVIDIA GPU。与 PyTorch 的即时 (JIT) 编译器不同,Torch-TensorRT 是一个即时编译 (AOT) 编译器,这意味着在您部署 TorchScript 代码之前,您需要通过一个显式的编译步骤将标准的 TorchScript 程序转换为针对 TensorRT 引擎的模块。Torch-TensorRT 作为 PyTorch 扩展运行,并编译无缝集成到 JIT 运行时的模块。使用优化后的图编译后,与运行 TorchScript 模块的感觉应该没有区别。您还可以在编译时访问 TensorRT 的配置套件,因此您可以指定模块的操作精度(FP32/FP16/INT8)和其他设置。
示例用法
import torch_tensorrt
...
trt_ts_module = torch_tensorrt.compile(torch_script_module,
inputs = [example_tensor, # Provide example tensor for input shape or...
torch_tensorrt.Input( # Specify input object with shape and dtype
min_shape=[1, 3, 224, 224],
opt_shape=[1, 3, 512, 512],
max_shape=[1, 3, 1024, 1024],
# For static size shape=[1, 3, 224, 224]
dtype=torch.half) # Datatype of input tensor. Allowed options torch.(float|half|int8|int32|bool)
],
enabled_precisions = {torch.half}, # Run with FP16)
result = trt_ts_module(input_data) # run inference
torch.jit.save(trt_ts_module, "trt_torchscript_module.ts") # save the TRT embedded Torchscript
安装
ABI / 平台 | 安装命令 |
---|---|
预 CXX11 ABI (Linux x86_64) | python3 setup.py install |
CXX ABI (Linux x86_64) | python3 setup.py install --use-cxx11-abi |
预 CXX11 ABI (Jetson 平台 aarch64) | python3 setup.py install --jetpack-version 4.6 |
CXX11 ABI (Jetson 平台 aarch64) | python3 setup.py install --jetpack-version 4.6 --use-cxx11-abi |
对于 Linux x86_64 平台,Pytorch 库默认使用预 CXX11 ABI。因此,请使用 python3 setup.py install
。
在 Jetson 平台上,NVIDIA 提供 预构建的 Pytorch 轮文件。这些轮文件使用 CXX11 ABI 构建。因此,在 Jetson 平台上,请使用 python3 setup.py install --jetpack-version 4.6 --use-cxx11-abi
内部结构
当提供已追踪的模块给 Torch-TensorRT 时,编译器将内部表示转换为类似这样的形式
graph(%input.2 : Tensor):
%2 : Float(84, 10) = prim::Constant[value=<Tensor>]()
%3 : Float(120, 84) = prim::Constant[value=<Tensor>]()
%4 : Float(576, 120) = prim::Constant[value=<Tensor>]()
%5 : int = prim::Constant[value=-1]() # x.py:25:0
%6 : int[] = prim::Constant[value=annotate(List[int], [])]()
%7 : int[] = prim::Constant[value=[2, 2]]()
%8 : int[] = prim::Constant[value=[0, 0]]()
%9 : int[] = prim::Constant[value=[1, 1]]()
%10 : bool = prim::Constant[value=1]() # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0
%11 : int = prim::Constant[value=1]() # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
%12 : bool = prim::Constant[value=0]() # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
%self.classifer.fc3.bias : Float(10) = prim::Constant[value= 0.0464 0.0383 0.0678 0.0932 0.1045 -0.0805 -0.0435 -0.0818 0.0208 -0.0358 [ CUDAFloatType{10} ]]()
%self.classifer.fc2.bias : Float(84) = prim::Constant[value=<Tensor>]()
%self.classifer.fc1.bias : Float(120) = prim::Constant[value=<Tensor>]()
%self.feat.conv2.weight : Float(16, 6, 3, 3) = prim::Constant[value=<Tensor>]()
%self.feat.conv2.bias : Float(16) = prim::Constant[value=<Tensor>]()
%self.feat.conv1.weight : Float(6, 1, 3, 3) = prim::Constant[value=<Tensor>]()
%self.feat.conv1.bias : Float(6) = prim::Constant[value= 0.0530 -0.1691 0.2802 0.1502 0.1056 -0.1549 [ CUDAFloatType{6} ]]()
%input0.4 : Tensor = aten::_convolution(%input.2, %self.feat.conv1.weight, %self.feat.conv1.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0
%input0.5 : Tensor = aten::relu(%input0.4) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
%input1.2 : Tensor = aten::max_pool2d(%input0.5, %7, %6, %8, %9, %12) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
%input0.6 : Tensor = aten::_convolution(%input1.2, %self.feat.conv2.weight, %self.feat.conv2.bias, %9, %8, %9, %12, %8, %11, %12, %12, %10) # ~/.local/lib/python3.6/site-packages/torch/nn/modules/conv.py:346:0
%input2.1 : Tensor = aten::relu(%input0.6) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
%x.1 : Tensor = aten::max_pool2d(%input2.1, %7, %6, %8, %9, %12) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:539:0
%input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0
%27 : Tensor = aten::matmul(%input.1, %4)
%28 : Tensor = trt::const(%self.classifer.fc1.bias)
%29 : Tensor = aten::add_(%28, %27, %11)
%input0.2 : Tensor = aten::relu(%29) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
%31 : Tensor = aten::matmul(%input0.2, %3)
%32 : Tensor = trt::const(%self.classifer.fc2.bias)
%33 : Tensor = aten::add_(%32, %31, %11)
%input1.1 : Tensor = aten::relu(%33) # ~/.local/lib/python3.6/site-packages/torch/nn/functional.py:1063:0
%35 : Tensor = aten::matmul(%input1.1, %2)
%36 : Tensor = trt::const(%self.classifer.fc3.bias)
%37 : Tensor = aten::add_(%36, %35, %11)
return (%37)
(CompileGraph)
图已经从类似您的 PyTorch 模块是模块集合的集合,每个模块管理自己的参数,转换为具有参数内联到图中并且所有操作展开的单个图。Torch-TensorRT 还执行了一系列优化和映射,以便将图更容易地转换为 TensorRT。从这里,编译器可以通过跟踪图中的数据流来组装 TensorRT 引擎。
当图构建阶段完成后,Torch-TensorRT 生成一个序列化的 TensorRT 引擎。从这里,根据 API,此引擎返回给用户或移动到图构建阶段。在这里,Torch-TensorRT 创建一个 JIT 模块来执行 TensorRT 引擎,该引擎将由 Torch-TensorRT 运行时实例化和管理。
这是编译完成后返回的图
graph(%self.1 : __torch__.___torch_mangle_10.LeNet_trt,
%2 : Tensor):
%1 : int = prim::Constant[value=94106001690080]()
%3 : Tensor = trt::execute_engine(%1, %2)
return (%3)
(AddEngineToGraph)
您可以看到执行引擎的调用,基于一个常量,即引擎的 ID,告诉 JIT 如何找到引擎以及将被输入到 TensorRT 的输入张量。引擎表示与运行正常 PyTorch 模块所执行的精确相同的计算,但优化以在您的 GPU 上运行。
Torch-TensorRT 通过生成与图中看到的指令相对应的层或子图来从 TorchScript 转换。转换器是用于将特定操作映射到 TensorRT 中的层或子图的代码的小模块。并非所有操作都受支持,但如果您需要实现一个,您可以在 C++ 中实现。
注册自定义转换器
通过模块化转换器将操作映射到TensorRT,这是一种函数,它从一个JIT图中的节点生成在TensorRT中的等效层或子图。Torch-TensorRT附带了一个存储在注册表中的转换器库,这将根据正在解析的节点执行。例如,一个aten::relu(%input0.4)
指令将触发relu转换器在其上运行,产生TensorRT图中的一个激活层。但由于这个库不是详尽的,您可能需要编写自己的转换器以使Torch-TensorRT支持您的模块。
Torch-TensorRT发行版附带内部核心API头文件。因此,您可以访问转换器注册表并为所需的操作添加转换器。
例如,如果我们尝试编译一个不支持flatten操作(aten::flatten
)的Torch-TensorRT构建的图,您可能会看到以下错误
terminate called after throwing an instance of 'torch_tensorrt::Error'
what(): [enforce fail at core/conversion/conversion.cpp:109] Expected converter to be true but got false
Unable to convert node: %input.1 : Tensor = aten::flatten(%x.1, %11, %5) # x.py:25:0 (conversion.AddLayer)
Schema: aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)
Converter for aten::flatten requested, but no such converter was found.
If you need a converter for this operator, you can try implementing one yourself
or request a converter: https://www.github.com/NVIDIA/Torch-TensorRT/issues
我们可以在我们的应用程序中为这个操作注册一个转换器。所有构建转换器所需工具都可以通过包含Torch-TensorRT/core/conversion/converters/converters.h
来导入。我们首先创建一个实例self-registering的class torch_tensorrt::core::conversion::converters::RegisterNodeConversionPatterns()
,它将在全局转换器注册表中注册转换器,将函数模式如aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)
与一个lambda函数关联,该函数将接受转换状态、要转换的节点/操作以及节点的所有输入,并作为副作用在TensorRT网络中产生一个新层。参数作为按模式列表中列出的顺序的TensorRT ITensors和Torch IValues的可检查联合体向量传递。
以下是一个aten::flatten
转换器的实现,我们可以在我们的应用程序中使用。在转换器实现中,您可以完全访问Torch和TensorRT库。因此,例如,我们可以通过在PyTorch中运行操作而不是像我们在以下flatten转换器中那样自己实现完整计算来快速获取输出大小。
#include "torch/script.h"
#include "torch_tensorrt/torch_tensorrt.h"
#include "torch_tensorrt/core/conversion/converters/converters.h"
static auto flatten_converter = torch_tensorrt::core::conversion::converters::RegisterNodeConversionPatterns()
.pattern({
"aten::flatten.using_ints(Tensor self, int start_dim=0, int end_dim=-1) -> (Tensor)",
[](torch_tensorrt::core::conversion::ConversionCtx* ctx,
const torch::jit::Node* n,
torch_tensorrt::core::conversion::converters::args& args) -> bool {
auto in = args[0].ITensor();
auto start_dim = args[1].unwrapToInt();
auto end_dim = args[2].unwrapToInt();
auto in_shape = torch_tensorrt::core::util::toVec(in->getDimensions());
auto out_shape = torch::flatten(torch::rand(in_shape), start_dim, end_dim).sizes();
auto shuffle = ctx->net->addShuffle(*in);
shuffle->setReshapeDimensions(torch_tensorrt::core::util::toDims(out_shape));
shuffle->setName(torch_tensorrt::core::util::node_info(n).c_str());
auto out_tensor = ctx->AssociateValueAndTensor(n->outputs()[0], shuffle->getOutput(0));
return true;
}
});
要在Python中使用此转换器,建议使用PyTorch的C++ / CUDA扩展模板来将您的转换器库包装到一个.so
文件中,然后您可以使用Python应用程序中的ctypes.CDLL()
加载它。
有关编写转换器的所有详细信息的更多信息,请参阅贡献者文档(编写转换器)。如果您发现自己有一个大型转换器实现库,请考虑将其上游化,PR是受欢迎的,并且让社区受益将是非常好的。
项目详情
torch_tensorrt-2.4.0-cp311-cp311-win_amd64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9f24401f8c3021c3e44008fd3c2442494a3527671ffb8d1ab19d5059bf41f8c9 |
|
MD5 | eef6b213f8f1baa533d2d31af0c3ca2f |
|
BLAKE2b-256 | 99920b20a30e8ac95932e011b24048a92a7b7e7e583b3e63b34c5248a156674b |
torch_tensorrt-2.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_34_x86_64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 76c807ed23038c6776b50d43344354820db7345adb0da2899671f972e87bc453 |
|
MD5 | 514d97197abdead741fb44ac938df013 |
|
BLAKE2b-256 | 8eb55d6b92738ea3a1fda80495338e3840680541eae9007c1dfa8319f9c16d06 |
torch_tensorrt-2.4.0-cp310-cp310-win_amd64.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 31dc1988d32d2c9b0a38f24a2bd1166e164d6fa6cfc1f48375af5b63a5c5c832 |
|
MD5 | 96dedeca1120b1f9b6db5605e6809b6f |
|
BLAKE2b-256 | 13559d7db64a40221c8925864d5ddeccacfd7147cc9bfa1347478077436bd39e |
哈希值 用于 torch_tensorrt-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_34_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 97595fb8c51a642a53b390e718de9b02da033fc6415a71129ae759faa6dec4d8 |
|
MD5 | 6ffe5dbbbe1ee7e0e1b018c09cad6d11 |
|
BLAKE2b-256 | 9088e938b5dbc502293e1903f9c51e594d928b5a21d5ce11e2d6b5ac039ebe7e |
哈希值 用于 torch_tensorrt-2.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_34_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 54e998355395a72c5aacc93062e77d46875d5648a9ff6e66b5113b895fffef90 |
|
MD5 | e59dfc38594935c2685dc36b65239c44 |
|
BLAKE2b-256 | 342f7e90d5e7b16fc9182cfaa01df7ffb0b2030586319f862c37ce10afec4a3b |
哈希值 用于 torch_tensorrt-2.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_34_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | c758b51be167c4ec471e651631ee35c757b06aa0fffec47b36d7b5c349c2ba99 |
|
MD5 | 5d77ee766124efb1c41e56a0a5b22303 |
|
BLAKE2b-256 | 5a9008fa5993992f6681f2d86bc14faaf28b754660f002fed074f0e00c7a84ee |