带有 TensorRT 的 C++ Tensorflow API

Posted

技术标签:

【中文标题】带有 TensorRT 的 C++ Tensorflow API【英文标题】:C++ Tensorflow API with TensorRT 【发布时间】:2018-05-02 01:14:05 【问题描述】:

我的目标是在 C++ 应用程序中运行 tensorrt 优化的 tensorflow 图。我正在使用 tensorflow 1.8 和 tensorrt 4。使用 python api,我能够优化图形并看到很好的性能提升。

尝试在 c++ 中运行图表失败并出现以下错误:

Not found: Op type not registered 'TRTEngineOp' in binary running on e15ff5301262. Make sure the Op and Kernel are registered in the binary running in this process.

其他非张量图也可以。我对 python api 有类似的错误,但通过导入 tensorflow.contrib.tensorrt 解决了它。从错误中我相当确定内核和操作没有注册,但我不知道如何在构建 tensorflow 后在应用程序中这样做。附带说明一下,我不能使用 bazel,但需要使用 cmake。到目前为止,我链接到 libtensorflow_cc.solibtensorflow_framework.so

有人可以帮我吗?谢谢!

更新: 使用c或者c++ api加载_trt_engine_op.so在加载的时候不会报错,但是运行失败了

Invalid argument: No OpKernel was registered to support Op 'TRTEngineOp' with these attrs.  Registered devices: [CPU,GPU], Registered kernels:
  <no registered kernels>

     [[Node: my_trt_op3 = TRTEngineOp[InT=[DT_FLOAT, DT_FLOAT], OutT=[DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT], input_nodes=["tower_0/down_0/conv_0/Conv2D-0-TransposeNHWCToNCHW-LayoutOptimizer", "tower_0/down_0/conv_skip/Conv2D-0-TransposeNHWCToNCHW-LayoutOptimizer"], output_nodes=["tower_0/down_0/conv_skip/Relu", "tower_0/down_1/conv_skip/Relu", "tower_0/down_2/conv_skip/Relu", "tower_0/down_3/conv_skip/Relu"], serialized_engine="\220I\000...00\000\000"](tower_0/down_0/conv_0/Conv2D-0-TransposeNHWCToNCHW-LayoutOptimizer, tower_0/down_0/conv_skip/Conv2D-0-TransposeNHWCToNCHW-LayoutOptimizer)]]

【问题讨论】:

从 TensorFlow 1.7 和 TensorRT 3.04 开始,使用 C API 中的 TF_LoadLibrary 加载 _trt_engine_op.so 为我完成了注册操作的工作。目前似乎不适用于 1.8,所以我没有将其发布为答案。但也许这些信息会有用。 我将 "//tensorflow/contrib/tensorrt:trt_engine_op_kernel" 添加到 libtensorflow.so 的 bazel 构建依赖项中,现在它可以工作了。我仍在与“TensorRT 引擎需要一致的批量大小”(适用于 python)作斗争,但禁用 trt_shfn.cc 中的致命警告允许它运行。 【参考方案1】:

解决Tensorflow 1.8上出现“未找到:操作类型未注册'TRTEngineOp'”错误问题的另一种方法:

1) 在文件tensorflow/contrib/tensorrt/BUILD 中,添加具有以下内容的新部分:

cc_library(
name = "trt_engine_op_kernel_cc",
srcs = [
    "kernels/trt_calib_op.cc",
    "kernels/trt_engine_op.cc",
    "ops/trt_calib_op.cc",
    "ops/trt_engine_op.cc",
    "shape_fn/trt_shfn.cc",
],
hdrs = [
    "kernels/trt_calib_op.h",
    "kernels/trt_engine_op.h",
    "shape_fn/trt_shfn.h",
],
copts = tf_copts(),
visibility = ["//visibility:public"],
deps = [
    ":trt_logging",
    ":trt_plugins",
    ":trt_resources",
    "//tensorflow/core:gpu_headers_lib",
    "//tensorflow/core:lib_proto_parsing",
    "//tensorflow/core:stream_executor_headers_lib",
] + if_tensorrt([
    "@local_config_tensorrt//:nv_infer",
]) + tf_custom_op_library_additional_deps(),
alwayslink = 1,  # buildozer: disable=alwayslink-with-hdrs
)

2) 将//tensorflow/contrib/tensorrt:trt_engine_op_kernel_cc作为依赖添加到您要构建的相应BAZEL项目中

PS:无需使用 TF_LoadLibrary 加载库_trt_engine_op.so

【讨论】:

为了清楚起见:文件 trt_calib_op.cc 包含宏 REGISTER_OP ("TRTEngineOp"),它注册了所需的操作 TRTEngineOp。问题是trt_engine_op_kernel 不包含此文件。【参考方案2】:

这是我对这个问题(Tensorflow 1.8.0、TensorRT 3.0.4)的发现(以及某种解决方案):

我想将 tensorrt 支持包含到一个库中,该库从给定的 *.pb 文件加载图表。

仅将//tensorflow/contrib/tensorrt:trt_engine_op_kernel 添加到我的 Bazel BUILD 文件对我来说没有任何作用。我仍然收到一条消息,指出未注册的 Ops:

2018-05-21 12:22:07.286665: E tensorflow/core/framework/op_kernel.cc:1242] OpKernel ('op: "TRTCalibOp" device_type: "GPU"') for unknown op: TRTCalibOp
2018-05-21 12:22:07.286856: E tensorflow/core/framework/op_kernel.cc:1242] OpKernel ('op: "TRTEngineOp" device_type: "GPU"') for unknown op: TRTEngineOp
2018-05-21 12:22:07.296024: E tensorflow/examples/tf_inference_lib/cTfInference.cpp:56] Not found: Op type not registered 'TRTEngineOp' in binary running on ***. 
Make sure the Op and Kernel are registered in the binary running in this process.

解决方案是,我必须使用 C_API 在我的 C++ 代码中加载 Ops 库 (tf_custom_op_library):

#include "tensorflow/c/c_api.h"
...
TF_Status status = TF_NewStatus();
TF_LoadLibrary("_trt_engine_op.so", status);

共享对象_trt_engine_op.so是为bazel目标//tensorflow/contrib/tensorrt:python/ops/_trt_engine_op.so创建的:

bazel build --config=opt --config=cuda --config=monolithic \
     //tensorflow/contrib/tensorrt:python/ops/_trt_engine_op.so

现在我只需要确保 _trt_engine_op.so 在需要时可用,例如LD_LIBRARY_PATH.

如果有人有想法,如何以更优雅的方式做到这一点(为什么我们有 2 个必须构建的人工制品?我们不能只有一个吗?),我很高兴每一个建议。

tldr

    //tensorflow/contrib/tensorrt:trt_engine_op_kernel添加为您要构建的相应BAZEL项目的依赖项

    使用 C-API 在您的代码中加载 ops-library _trt_engine_op.so

【讨论】:

【参考方案3】:

对于 Tensorflow r1.8,下面显示在两个 BUILD 文件中的添加和使用单体选项构建 libtensorflow_cc.so 对我有用。

diff --git a/tensorflow/BUILD b/tensorflow/BUILD
index cfafffd..fb8eb31 100644
--- a/tensorflow/BUILD
+++ b/tensorflow/BUILD
@@ -525,6 +525,8 @@ tf_cc_shared_object(
         "//tensorflow/cc:scope",
         "//tensorflow/cc/profiler",
         "//tensorflow/core:tensorflow",
+        "//tensorflow/contrib/tensorrt:trt_conversion",
+        "//tensorflow/contrib/tensorrt:trt_engine_op_kernel",
     ],
 )

diff --git a/tensorflow/contrib/tensorrt/BUILD b/tensorflow/contrib/tensorrt/BUILD
index fd3582e..a6566b9 100644
--- a/tensorflow/contrib/tensorrt/BUILD
+++ b/tensorflow/contrib/tensorrt/BUILD
@@ -76,6 +76,8 @@ cc_library(
     srcs = [
         "kernels/trt_calib_op.cc",
         "kernels/trt_engine_op.cc",
+        "ops/trt_calib_op.cc",
+        "ops/trt_engine_op.cc",
     ],
     hdrs = [
         "kernels/trt_calib_op.h",
@@ -86,6 +88,7 @@ cc_library(
     deps = [
         ":trt_logging",
         ":trt_resources",
+        ":trt_shape_function",
         "//tensorflow/core:gpu_headers_lib",
         "//tensorflow/core:lib_proto_parsing",
         "//tensorflow/core:stream_executor_headers_lib",

【讨论】:

【参考方案4】:

正如您所提到的,当您将 //tensorflow/contrib/tensorrt:trt_engine_op_kernel 添加到依赖项列表时,它应该可以工作。目前 Tensorflow-TensorRT 集成仍在进行中,可能仅适用于 python API;对于 C++,您需要从 tensorflow/contrib/tensorrt/convert/convert_graph.h 调用 ConvertGraphDefToTensorRT() 进行转换。

如果您有任何问题,请告诉我。

【讨论】:

我正在使用另一个使用预编译 libtensorflow_cc.so 的存储库中的 C++ API 加载具有 TensorRT 优化的 protobufs。我尝试使用 TF_LoadLibrary C API 加载 _trt_engine_op.so,这消除了 TRTEngineOp 不可用的投诉,但内核未注册。在外部项目中注册内核还需要做什么?【参考方案5】:

解决方案:添加导入

从 tensorflow.python.compiler.tensorrt 导入 trt_convert as trt

链接讨论:https://github.com/tensorflow/tensorflow/issues/26525

【讨论】:

【参考方案6】:

这是我的解决方案,tensorflow 是 1.14。 在您的 BUILD 文件中,exp,tensorflow/examples/your_workspace/BUILD:

tf_cc_binary:

scrs= [...,"//tensorflow/compiler/tf2tensorrt:ops/trt_engine_op.cc"]
deps=[...,"//tensorflow/compiler/tf2tensorrt:trt_op_kernels"]

【讨论】:

感谢您的贡献@user12359839!如果您正在构建//tensorflow/tools/lib_package:libtensorflow,请问这将如何转换为tensorflow/tools/lib_package/BUILD 对不起,我不知道。

以上是关于带有 TensorRT 的 C++ Tensorflow API的主要内容,如果未能解决你的问题,请参考以下文章

带有 CTC 层的 TensorRT

pytorch C++部署模型 ONNX tensorRT

TensorRT C++网络模型接口推理

TensorRT 系列 C++ API 构建编译网络

C++ (tensorRT中学习)

TensorRT模型部署实战,英伟达平台,C++ 和python对比(包含源码)