Monolithic build of libtensorflow_cc.so produces libtensorflow_framework.so, failing to run application

dojqjjoe  于 6个月前  发布在  其他
关注(0)|答案(8)|浏览(164)

#### 问题类型

构建/安装

#### 你是否在TF nightly版本中复现了这个bug?

否

#### 来源

源代码

#### Tensorflow版本

tf 2.10

#### 自定义代码

无

#### OS平台和发行版

Linux Ubuntu 20.04

#### 移动设备

* 无响应*

#### Python版本

3.8.10

#### Bazel版本

5.3.1

#### GCC/编译器版本

9.4.0

#### CUDA/cuDNN版本

11.2.152

#### GPU型号和内存

NVIDIA RTX 3090 TI (24GB)

#### 当前行为?

我正在尝试从源代码构建TensorFlow C++库 `libtensorflow_cc.so` 的单块版本,适用于TensorFlow版本2.10+。
我正在Docker容器中构建官方的 `devel-gpu` 镜像,该镜像为 [defined in devel-gpu.Dockerfile](https://github.com/tensorflow/tensorflow/blob/v2.10.0/tensorflow/tools/dockerfiles/dockerfiles/devel-gpu.Dockerfile) 。
对于构建,我调用以下命令。构建输出作为此问题中的日志附加。请注意,我还不得不引入这个补丁才能使构建正常工作。

bazel build --jobs ${JOBS} --config=cuda --config=opt --config=monolithic --verbose_failures tensorflow:libtensorflow_cc.so tensorflow:install_headers


库成功构建,但我注意到 `libtensorflow_cc.so` 似乎现在链接到 `libtensorflow_framework.so` ,而在这个过程中也构建了它。这在v2.9.2及更早版本中并不存在。实际上,我认为 `--config=monolithic` 应该只导致 `libtensorflow_cc.so` ,但看起来 `libtensorflow_framework.so` 是依赖项,因为 [843c02f](https://github.com/tensorflow/tensorflow/commit/843c02fe06983ac0f4382a93fff9ffd07eb93d27) ?目前我没有找到 `--config=monolithic` 如何发挥作用的地方。
我现在的主要问题是无法成功编译和运行测试C++程序。以前这可以:

g++ -I /usr/local/include/tensorflow
hello_tensorflow.cpp
-ltensorflow_cc -lprotobuf
-o hello_tensorflow


使用v2.10.0+时,它给我以下错误。

/usr/bin/ld: /tmp/ccVj5SwH.o: undefined reference to symbol '_ZN10tensorflow6TensorC1ENS_8DataTypeERKNS_11TensorShapeE'
/usr/bin/ld: /usr/local/lib//libtensorflow_framework.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status


现在,如果我将 `libtensorflow_framework.so` 添加到要链接的库列表中,编译就可以工作。

g++ -I /usr/local/include/tensorflow
hello_tensorflow.cpp
-ltensorflow_cc -ltensorflow_framework -lprotobuf
-o hello_tensorflow


然而,这次我得到了以下运行时错误:

[libprotobuf ERROR external/com_google_protobuf/src/google/protobuf/descriptor_database.cc:118] File already exists in database: google/protobuf/any.proto
[libprotobuf FATAL external/com_google_protobuf/src/google/protobuf/descriptor.cc:1379] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
terminate called after throwing an instance of 'google::protobuf::FatalException'
what(): CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
Aborted (core dumped)


#### 独立代码以重现问题

首先使用 [devel-gpu.Dockerfile](https://github.com/tensorflow/tensorflow/blob/v2.10.0/tensorflow/tools/dockerfiles/dockerfiles/devel-gpu.Dockerfile) 构建官方的GPU开发镜像。

docker build -t tensorflow/tensorflow:2.10.0-devel-gpu -f devel-gpu.Dockerfile .


然后尝试使用以下Dockerfile构建 `libtensorflow_cc.so` 。

ARG TF_VERSION=2.10.0
FROM tensorflow/tensorflow:${TF_VERSION}-devel-gpu AS build

ARG TF_VERSION
ARG JOBS="auto"

clone TensorFlow

RUN git clone --branch v${TF_VERSION} --depth=1 https://github.com/tensorflow/tensorflow.git /tensorflow
WORKDIR /tensorflow

fix build issue in v2.10.0

https://github.com/tensorflow/tensorflow/issues/57826

RUN if [ "${TF_VERSION}" = "2.10.0" ] || [ "${TF_VERSION}" = "2.10.1" ]; then
git fetch --depth=1 origin b1bd1d6beeac169ce669f81dcbf3c48899ca1ed0 &&
git checkout FETCH_HEAD -- tensorflow/BUILD;
fi

configure compilation

ENV PYTHON_BIN_PATH=/usr/bin/python3
ENV PYTHON_LIB_PATH=/usr/lib/python3/dist-packages
ENV TF_NEED_ROCM=0
ENV TF_CUDA_COMPUTE_CAPABILITIES=5.3,6.0,6.1,7.0,7.2,7.5,8.0,8.6
ENV TF_CUDA_CLANG=0
ENV GCC_HOST_COMPILER_PATH=/usr/bin/gcc
ENV CC_OPT_FLAGS="-march=native -Wno-sign-compare"
ENV TF_SET_ANDROID_WORKSPACE=0
RUN ./configure

build C++ library

RUN bazel build --jobs ${JOBS} --config=cuda --config=opt --config=monolithic --verbose_failures tensorflow:libtensorflow_cc.so tensorflow:install_headers

docker build -t tensorflow/tensorflow:2.10.0-libtensorflow-cc .


注意 `libtensorflow_cc.so` 和 `libtensorflow_framework.so` 都被构建了。
将构建好的库和头文件安装到系统上,例如在构建的镜像的Docker容器中。尝试构建并运行以下示例应用程序。

#include
#include

#include <tensorflow/cc/client/client_session.h>
#include <tensorflow/cc/ops/standard_ops.h>
#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/core/public/version.h>

using namespace std;

int main(int argc, char **argv) {

// create new session
auto scope = tensorflow::Scope::NewRootScope();
tensorflow::ClientSession session(scope);

// define graph of operations
auto A = tensorflow::ops::Const(scope, {{1, 2}, {3, 4}});
auto x = tensorflow::ops::Const(scope, {{1}, {2}});
auto b = tensorflow::ops::MatMul(scope, A, x);

// run graph and fetch outputs of A, x, and b
vectortensorflow::Tensor outputs;
session.Run({A, x, b}, &outputs);

// print results
cout << "Hello from TensorFlow C++ " << TF_VERSION_STRING << "!" << endl << endl;
cout << "A = " << endl << outputs[0].tensor<int, 2>() << endl << endl;
cout << "x = " << endl << outputs[1].tensor<int, 2>() << endl << endl;
cout << "A * x = " << endl << outputs[2].tensor<int, 2>() << endl;

return 0;
}

g++ -I /usr/local/include/tensorflow
hello_tensorflow.cpp
-ltensorflow_cc -ltensorflow_framework -lprotobuf
-o hello_tensorflow


#### 相关日志输出

[libprotobuf ERROR external/com_google_protobuf/src/google/protobuf/descriptor_database.cc:118] File already exists in database: google/protobuf/any.proto
[libprotobuf FATAL external/com_google_protobuf/src/google/protobuf/descriptor.cc:1379] CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
terminate called after throwing an instance of 'google::protobuf::FatalException'
what(): CHECK failed: GeneratedDatabase()->Add(encoded_file_descriptor, size):
Aborted (core dumped)

eqqqjvef

eqqqjvef1#

我在构建libtensorflow_cc.so并在另一个项目中使用它时取得了一些成功,而没有使用--config=monolithic配置。不确定这是否有帮助,但我认为错误信息似乎是由于libtensorflow_framework和libtensorflow_cc以某种方式初始化protobuf。

我还可以确认,自2.9.0版本以来,单体构建似乎出现了一些回归。我可以使用--config=monolithic成功运行所有v2.9.0的Python测试,但在较新的TensorFlow版本下,它们会失败。

xlpyo6sf

xlpyo6sf2#

我确认了这个问题。使用相同的辅助脚本 Package Bazel调用(带有--config=monolithic)为2.9.3和2.10.1生成不同的libtensorflow_cc.so文件:前者实际上是单体的,后者依赖于libtensorflow_framework.so。

在使用--config=monolithic时,我也遇到了与OP相同的错误。

如果需要,我可以提供更多关于我的设置的详细信息。

bvuwiixz

bvuwiixz3#

我在不使用--config=monolithic配置的情况下成功构建了libtensorflow_cc.so,并将其用于另一个项目。不确定这是否有帮助,但我认为错误信息似乎是由于libtensorflow_framework和libtensorflow_cc以某种方式初始化protobuf。

我还可以确认自2.9.0版本以来,单体构建似乎出现了一些回归。我可以使用--config=monolithic成功运行所有v2.9.0的Python测试,但在更新的TensorFlow版本下它们会失败。

感谢,我确认在不使用config=monolithic的情况下构建时,我可以成功链接并运行我的应用程序代码。

5uzkadbs

5uzkadbs4#

@lreiher 请问这个问题是否已经解决?
谢谢!

yzuktlbb

yzuktlbb5#

我可以确认,在没有config=monolithic的情况下,我能够成功地链接和运行我的应用程序代码。然而,描述的问题仍然存在,并且我认为它的行为并不符合预期。

tktrz96b

tktrz96b6#

感谢您的更新!
@SuryanarayanaY 请问您能看一下这个问题吗?
谢谢!

tnkciper

tnkciper7#

@sachinprasadhs ,请问您能调查一下这个问题吗?谢谢!

e5njpo68

e5njpo688#

当我在Arch Linux官方仓库中使用tensorflow包时,遇到了相同的protobuf错误信息。请注意,Arch Linux的tensorflow包并不是用--config=monolithic构建的。由于这个问题已经打开了一年多,自那时以来可能发生了很多变化,也许monolithic选项不是问题的原因?

当我在Arch Linux中运行telegram-desktop时,如果使用了一个与tensorflow链接的自定义ffmpeg构建(通过在构建时使用ffmpeg选项--enable-libtensorflow),我就可以重现这个问题。telegram-desktop应用程序链接到ffmpeg和protobuf,而自定义ffmpeg将链接到tensorflow。请注意,telegram-desktop并没有链接到tensorflow库。

当使用与tensorflow链接的自定义ffmpeg构建(即链接到tensorflow)运行telegram-desktop时,protobuf错误会在telegram启动时显示,并导致崩溃。而当使用Arch Linux仓库中的ffmpeg包(即未链接到tensorflow)运行telegram-desktop时,一切正常。

相关问题