TensorRT 中 converter.build() 有什么用?

What's the use for converter.build() in TensorRT?

official documentation on TensorRT 列出了两种将 TensorFlow SavedModel 转换为 TensorRT SavedModel 的方法:第一种是

from tensorflow.python.compiler.tensorrt import trt_convert as trt
converter = trt.TrtGraphConverterV2(input_saved_model_dir=input_saved_model_dir)
converter.convert()
converter.save(output_saved_model_dir)

第二个是

import tensorflow as tf
from tensorflow.python.compiler.tensorrt import trt_convert as trt

conversion_params = trt.DEFAULT_TRT_CONVERSION_PARAMS
conversion_params = conversion_params._replace(
    max_workspace_size_bytes=(1<<32))
conversion_params = conversion_params._replace(precision_mode="FP16")
conversion_params = conversion_params._replace(
    maximum_cached_engiens=100)

converter = trt.TrtGraphConverterV2(
    input_saved_model_dir=input_saved_model_dir,
    conversion_params=conversion_params)
converter.convert()
def my_input_fn():
  for _ in range(num_runs):
    Inp1 = np.random.normal(size=(8, 16, 16, 3)).astype(np.float32)
    inp2 = np.random.normal(size=(8, 16, 16, 3)).astype(np.float32)
    yield inp1, inp2
converter.build(input_fn=my_input_fn)
converter.save(output_saved_model_dir)

saved_model_loaded = tf.saved_model.load(
    output_saved_model_dir, tags=[tag_constants.SERVING])
graph_func = saved_model_loaded.signatures[
    signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
frozen_func = convert_to_constants.convert_variables_to_constants_v2(
    graph_func)
output = frozen_func(input_data)[0].numpy()

去除所有用于导入、推理等的样板代码,区别似乎在于对 converter.build() 的调用。文档是这样解释这个函数的:

"This method optimizes the converted function (returned by convert()) by building TensorRT engines. This is useful in case the user wants to perform the optimizations before runtime. The optimization is done by running inference on the converted function using the input data received from the argument input_fn. This argument is a generator function that yields input data as a list or tuple. "

在这种情况下,"before runtime" 是什么意思? "optimizations" 是在加载模型时、在第一次推理时执行,还是在使用转换后的模型进行每次推理时执行?这些优化是什么?将模型转换为TensorRT本身不是一种优化吗?

我问是因为如果我调用 converter.build(),在花费大量时间(超过两个小时)到 运行 后,转换似乎以不可预测的方式失败,而没有产生任何合理的输出,所以我想知道不调用它会损失多少,以及是否有更全面的文档介绍如何将 TF2.x SavedModels 与 TensorRT 一起使用。

先谢谢能回答的人!!

根据我的理解(在阅读 TensorFlow's docs 之后),converter.convert() 函数将图形转换为 tf-trt,用 TRTEngineOp 替换它可以替换的任何节点,但它不会创建实际的引擎文件在推理期间使用。

然而,对 converter.build() 的调用会创建引擎文件,但是 对于 input_fn 和 [=28= 提供的输入的输入大小]为构建的平台在运行上。因此,不调用 converter.build() 的原因是您事先不知道输入形状,或者无法在您要 运行 推断的平台上进行构建。

我很难想象为每个正向传递创建新的引擎文件,但肯定是为每个新的输入形状创建新的引擎文件。从示例中不清楚 input_fn 的输入是否用于提供有关输入形状的信息以外的任何其他方式,但如果您 return 输入不同形状,则应为每个输入大小创建一个引擎文件.

例如,提供以下输入函数将为输入大小 (112,112,3) 生成一个引擎,为 (224,224,3) 生成一个引擎:

def input_fn():
  input_sizes = [[112, 112], [224, 224]]
  for size in input_sizes:
    inp1 = np.random.normal(size=(1, *size, 3)).astype(np.float32)
    yield [inp1]

至于你的input_fn,你有两张图像作为网络的输入吗?对我有用的是 returning 列表中的单个图像,如上面的示例(元组由于某种原因不起作用,尽管文档说它应该)。

希望对您有所帮助。