我刚刚设法使用glibc 2.12在CentOS 6.5上安装tensorflow 0.12rc0,没有root权限。只需通过pip安装tensorflow二进制文件就会给我一个错误,也与GLIBC版本有关。
基本上,你有4个选项来处理这个问题(每个都有一些优点和缺点):
选项1 - 全局升级您的系统GLIBC。
这可能是最佳选择,如果您的系统支持此功能,您拥有root权限,并且您确信此升级不会因某些奇怪的原因而破坏任何内容。最终,这可以升级整个Linux发行版。这是流行发行版上默认GLIBC版本的简短列表。
选项2 - 将第二个GLIBC添加到您的系统
编译或下载二进制文件。最简单明了的选择。特别是如果你只需要运行一些简单的脚本。
它可能具有相同的系统上的glibc的多个版本,但应该有一个非常小心做到这一点。
如果您的所有更改仅限于虚拟环境,则不会销毁您的系统。
之前安装/编译的许多程序可能依赖于旧的GLIBC,只会在您的新环境(例如您的python IDE)中崩溃。包括最基本的bash命令,如“lc”,“cd”等。
其他副作用,如重大内存泄漏也是可能的。
因此,将新的GLIBC添加到您的正常环境中是一个非常糟糕的主意,例如通过.bashrc。
另一方面,如果您需要在新的虚拟环境中使用某种特定工具,则可以重新编译它,链接新的GLIBC。所以,它可以在你的新环境中正常工作。
但是,就个人而言,我很快就放弃了在新环境中重新编译所需的一切(没有root和包管理器)。
GLIBC开发人员正式提供了一种稍微不同的方法,用于测试新的GLIBC构建。
选项3 - 补丁张量流
这可能适用于TF 0.6.0,但是当每个新的tensorflow版本发布时,您可能必须从头开始。例如,这是0.9.0的修复程序。
选项4 - 从源编译张量流
如果您从源代码重新编译它并链接到现有的GLIBC,则不再需要更新的GLIBC。不知何故,这个选项在这里没有提到任何答案。Imho,这是“ 一般 ”和“专门针对张量流” 的最佳选择。
这适用于r0.11并且可能会工作多年,但理论上,它可能会在一些较新的tensorflow版本中出现问题,如果他们决定实际使用一些新的GLIBC功能,而不是在旧版本中。
说实话,从源代码构建张量流并不简单,特别是在过时的系统上。
“过时系统构建张量流”的快速摘要:
虽然官方指南提供了“ 从源代码安装 ”部分,但是在过时的系统上构建它需要做很少的技巧。在这里,我假设您没有root权限(如果您这样做 - 您可能能够使用包管理器安装相同的预先请求,而不是从源代码手动构建它们)。
我找到了两个记录完备的成功案例:#1,#2和官方github上的一些有用的帖子(主要是关于二进制内部链接的一组库):#1,#2,#3,#4。我必须结合技巧,在那里描述成功编译TF在我的情况下。
首先,检查一下gcc --version,并验证它是否支持c ++ 11。我的是4.4.7,所以它不起作用。我已经下载了 gcc-4.9.4源代码,并对其进行了编译。这一步非常简单,但编译本身可能需要几个小时。至于在巴泽尔的问题的解决方法,我用gcc编译硬编码路径来as,ld和nm。但是,您可以尝试另一种解决方法:(1,2)。
#!/bin/sh
unset LIBRARY_PATH CPATH C_INCLUDE_PATH
unset PKG_CONFIG_PATH CPLUS_INCLUDE_PATH INCLUDE LD_LIBRARY_PATH
cd gcc-4.9.4
./contrib/download_prerequisites
mkdir objdir
cd objdir
# I've added --disable-multilib to fix the following error:
# /usr/bin/ld: crt1.o: No such file: No such file or directory
# collect2: ld returned 1 exit status
# configure: error: I suspect your system does not have 32-bit
# developement libraries (libc and headers). If you have them,
# rerun configure with --enable-multilib. If you do not have them,
# and want to build a 64-bit-only compiler, rerun configure
# with --disable-multilib.
../configure --prefix=$HOME/opt/gcc-4.9.4 \
--disable-multilib \
--disable-nls \
--enable-languages=c,c++ \
--with-ld=/usr/bin/ld \
--with-nm=/usr/bin/nm \
--with-as=/usr/bin/as
make
make install
检查你的java --version。Bazel需要JDK 8,必要时安装它。(他们仍然为bazel-0.4.1 提供了一些jdk7相关的下载,但看起来他们认为它被弃用了)
我创建了一个单独的use_gcc_4.9.4.sh文件,包含必要的环境变量。source ./use_gcc_4.9.4.sh当我需要这么新的编译器时,我会使用它。
#!/bin/sh
this=$HOME/opt/gcc-4.9.4
export PATH=$this/bin:$PATH
export CPATH=$this/include:$CPATH
export LIBRARY_PATH=$this/lib:$LIBRARY_PATH
export LIBRARY_PATH=$this/lib64:$LIBRARY_PATH
export LD_LIBRARY_PATH=$this/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$this/lib64:$LD_LIBRARY_PATH
当前的bazel二进制文件(0.4.1)需要GLIBC 2.14,因此我们必须从源代码编译bazel(使用我们的新gcc)。工作正常,除非您只允许在目标计算机上运行非常有限数量的线程。(这篇文章描述了一些额外的解决方法,但在我的情况下,它们不是必需的,可能是由于最近的bazel代码更新。)
获取tensorflow源代码git clone https://github.com/tensorflow/tensorflow,并安装所需的先决条件(CUDA,cuDNN,python等)。见官方指南。
如果你不使用默认的系统GCC(例如,如果你有编译新的gcc,像上面所讨论的),添加下面的链接器标志来tensorflow/third_party/gpus/crosstool/CROSSTOOL.tpl,第59行:
linker_flag: "-L/home/username/localinst/opt/gcc-4.9.4/lib64"
linker_flag: "-Wl,-rpath,/home/username/localinst/opt/gcc-4.9.4/lib64"
如果没有这一步,你可能会遇到这样的错误消息这样:
# ERROR: /home/username/localdistr/src/tensorflow/tensorflow/tensorflow/core/debug/BUILD:33:1: null failed: protoc failed: error executing command bazel-out/host/bin/external/protobuf/protoc '--cpp_out=bazel-out/local_linux-py3-opt/genfiles/' '--plugin=protoc-gen-grpc=bazel-out/host/bin/external/grpc/grpc_cpp_plugin' ... (remaining 8 argument(s) skipped): com.google.devtools.build.lib.shell.BadExitStatusException: Process exited with status 1.
# bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by bazel-out/host/bin/external/protobuf/protoc)
# bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by bazel-out/host/bin/external/protobuf/protoc)
# bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by bazel-out/host/bin/external/protobuf/protoc)
最后,为了避免GLIBC依赖,我们必须通过添加-lrt链接器标志(也许 -lm也是如此)静态链接一些库。我找到了多个帖子,建议以不同的方式添加:
通过bazel命令行(可能听起来很合理,但对于我当前的tensorflow版本不合适,不知何故),
通过“bazel-tensorflow / external / protobuf / BUILD”(不确定它是否正常工作,但这看起来不方便 - 这个文件只在构建尝试期间创建)
通过“third_party / gpus / crosstool / CROSSTOOL.tpl”(我们刚刚在上一步中编辑的文件,就在我们已添加的行的下方)。
linker_flag: "-lrt"
linker_flag: "-lm"
通过“tensorflow / tensorflow.bzl”(对我有用,但不太方便,因为你必须再编辑一个文件。我不确定它是否与前一点100%相当)
没有-lrt我再次遇到GLIBC版本特定的错误,试图import tensorflow:
# ImportError: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/username/anaconda3/envs/myenvname/lib/python3.5/site-packages/tensorflow/python/_pywrap_tensorflow.so)
没有-lm你可能遇到这个(对我来说,事实证明没有必要)。
运行构建过程。
source ./use_gcc_4.9.4.sh
./configure
bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
pip install --upgrade /tmp/tensorflow_pkg/tensorflow-0.12.0rc0-cp35-cp35m-linux_x86_64.whl
尝试运行以下简单的python脚本来测试最基本的东西是否正常运行:
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a + b))