TensorRT宏碁自建云(BYOC, BuildYourOwnCloud)上集成
TensorRT宏碁自建云(BYOC, BuildYourOwnCloud)上集成
这个PR增加了对分区、编译和运行TensorRT BYOC目标的支持。
Building
有两个新的cmake标志:
USE_TENSORRT=ON/OFF:启用TENSORRT代码生成-这不需要TENSORRT库 USE_TENSORRT_GRAPH_RUNTIME=ON/OFF/"path/to/TensorRT":
启用TENSORRTruntime-这需要TENSORRT库。从deb包或JetPack在系统范围内安装TensorRT时,可以通过“ON”来检测,但是.tar.gz安装要求提供提取的TensorRT归档文件的路径。
Usage
编译目标应该是“cuda”,以确保将TensorRT函数的输入和输出参数放在GPU上。
# Compilation
from tvm.relay.op.contrib import tensorrt
mod = tensorrt.partition_for_tensorrt(mod, params)
with relay.build_config(opt_level=3):
graph, lib, params = relay.build(mod, target="cuda", params=params)
# Running inference is unchanged
mod = graph_runtime.create(graph, lib, ctx=tvm.gpu(0))
mod.run(...)
High level components
Partitioning
TensorRT的注释规则根据目标的TensorRT版本以及“批处理模式”而变化。这可以用trt_version进行配置,并使用use_implicit_batch分区的partition_for_tensorrt批处理参数。
如果TVM是针对TensorRT库构建的,则链接版本将用于分区。
Codegen
此实现使用codegen的JSONRuntime JSONSerializer基类将中继表达式序列化为json格式。
Runtime
runtime由tensorrt中的runtime模块类处理tensorrt_runtime.cc。在runtime,它首先使用TensorRTBuilder类(tensorrt_builder.cc)用于使用TensorRT API将json图转换为TensorRT INetworkDefinition。它使用tensorrt中的converterconverter classes算子tensorrt_ops.cc。然后,构建TensorRT引擎,此过程可能需要几分钟时间,因为TensorRT将在此时执行优化。引擎被缓存以备进一步的推理调用。
如果guards,runtime可以针对许多TensorRT版本进行编译。它适用于TensorRT 5、6和7。编译后的模型必须为TensorRT版本<=runtime使用的版本进行分区。编译后的模型可能需要更新的TensorRT版本的算子可用。
Problem
TensorRT有一些参数,比如max_workspace_size和use_implicit_batch,希望用户能够在分区_中为partition_for_tensorrt提供这些参数。这些参数需要传递给codegen并存储在序列化图中,直到运行时为止。使用“隐式”批处理也会影响分区规则。使用环境变量将这些从Python传递到C++中的代码生成。想知道有没有更好的方法来做这个?
我在python/tvm/relay/op/contrib/tensorrt.py中实现了一个名为prune_tensorrt_subgraphs()的转换/tensorrt.py. 这是在分区之后运行的,决定是保留子图还是将其返回到典型的TVM编译路径。之所以需要这样做,是因为有些子图可能是无效的——例如当输入具有不同的批处理大小时,或者为了优化目的,如果子图没有乘法累加。在C++中实现了一个通用版本,但使用全局注册表来允许每个代码对象定义自己的is_invalid_subgraph回调。将来,如果找到更好的方法来注册回调,可以切换到泛型版本。
需要在注释时介入目标tensorrt版本。把它放在一个全局变量中。