在Ubuntu 12.04中导入Python 2.7中的Tensorflow时出错.'找不到GLIBC_2.17'

Tan*_*vir 43 python ubuntu glibc tensorflow

我已成功安装了Tensorflow绑定和python.但是当我尝试导入Tensorflow时,我得到了以下错误.

ImportError: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so)
Run Code Online (Sandbox Code Playgroud)

我试图将GLIBC_2.15更新为2.17,但没有运气.

Igo*_*gor 20

我刚刚设法使用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并且可能会工作多年,但理论上,如果他们决定实际使用一些新的GLIBC功能,它可能会在一些较新的tensorflow版本中中断,而在旧版本中不存在.
  • 说实话,从源代码构建张量流并不简单,尤其是在过时的系统上.

"过时系统构建张量流"的快速摘要:

虽然官方指南提供了" 从源代码安装 "部分,但在过时的系统上构建它需要做很少的技巧.在这里,我假设您没有root权限(如果您这样做 - 您可能能够使用包管理器安装相同的预先请求,而不是从源代码手动构建它们).

我找到了两个记录完备的成功案例:#1,#2和官方github上的一些有用的帖子(主要是关于二进制内部链接的一组库):#1,#2,#3,#4.我必须结合技巧,在那里描述成功编译TF在我的情况下.

  1. 首先,检查一下gcc --version,并验证它是否支持c ++ 11.我的是4.4.7,所以它不起作用.我已经下载了 gcc-4.9.4源代码,并对其进行了编译.这一步非常简单,但编译本身可能需要几个小时.至于在巴泽尔的问题的解决方法,我用gcc编译硬编码路径as,ldnm.但是,您可以尝试另一种解决方法:(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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 检查你的java --version.Bazel需要JDK 8,必要时安装它.(他们仍然为bazel-0.4.1 提供了一些jdk7相关的下载,但看起来他们认为它被弃用了)

  3. 我创建了一个单独的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
    
    Run Code Online (Sandbox Code Playgroud)
  4. 当前的bazel二进制文件(0.4.1)需要GLIBC 2.14,因此我们必须从源代码编译bazel(使用我们的新gcc).工作正常,除非您只允许在目标计算机上运行非常有限数量的线程.(这篇文章描述了一些额外的解决方法,但在我的情况下,它们不是必需的,可能是由于最近的bazel代码更新.)

  5. 获取tensorflow源代码git clone https://github.com/tensorflow/tensorflow,并安装所需的先决条件(CUDA,cuDNN,python等).见官方指南.

  6. 如果你不使用默认的系统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"
    
    Run Code Online (Sandbox Code Playgroud)

    如果没有这一步,你可能会遇到这样的错误消息这样:

    # 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)
    
    Run Code Online (Sandbox Code Playgroud)
  7. 最后,为了避免GLIBC依赖,我们必须通过添加-lrt链接器标志(也许 -lm也是如此)静态链接一些库.我找到了多个帖子,建议以不同的方式添加:

    没有-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)
    
    Run Code Online (Sandbox Code Playgroud)

    没有-lm你可能遇到这个(对我来说,事实证明没有必要).

  8. 运行构建过程.

    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
Run Code Online (Sandbox Code Playgroud)
  1. 尝试运行以下简单的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))
    
    Run Code Online (Sandbox Code Playgroud)


Thé*_*o T 17

我试过BR_User解决方案但仍然有一个烦人的事情:

ImportError: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found
Run Code Online (Sandbox Code Playgroud)

我在CentOS 6.7上,它也缺少更新的c ++标准库,所以为了构建BR_User解决方案,我提取了正确的libstdc ++包,但是我发现不需要虚拟环境.

假设您已经安装了tensorflow,它给出:

mkdir ~/my_libc_env
cd ~/my_libc_env
wget http://launchpadlibrarian.net/137699828/libc6_2.17-0ubuntu5_amd64.deb
wget http://launchpadlibrarian.net/137699829/libc6-dev_2.17-0ubuntu5_amd64.deb
wget ftp.riken.jp/Linux/scientific/7.0/x86_64/os/Packages/libstdc++-4.8.2-16.el7.x86_64.rpm
ar p libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
ar p libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
rpm2cpio libstdc++-4.8.2-7mgc30.x86_64.rpm| cpio -idmv
Run Code Online (Sandbox Code Playgroud)

然后运行python:

LD_LIBRARY_PATH="$HOME/my_libc_env/lib/x86_64-linux-gnu/:$HOME/my_libc_env/usr/lib64/" $HOME/my_libc_env/lib/x86_64-linux-gnu/ld-2.17.so `which python`
Run Code Online (Sandbox Code Playgroud)

如果它不起作用,我有另一个解决方案,但你不会喜欢它.

  • 运行`import tensorflow`后面临以下错误:加载共享库时出错:__ docso_time:dlopen()的无效模式:无效的参数`[问题#2105](https://github.com/tensorflow/tensorflow/issues/2105) (5认同)
  • 以下(2017年3月)失败:wget ftp://rpmfind.net/linux/sourceforge/m/ma/magicspecs/apt/3.0/x86_64/RPMS.lib/libstdc++-4.8.2-7mgc30.x86_64.rpm你可以尝试:wget ftp://195.220.108.108/linux/mageia/distrib/4/x86_64/media/core/updates/libstdc++6-4.8.2-3.2.mga4.x86_64.rpm和rpm2cpio libstdc ++ 6-4.8.2-3.2.mga4.x86_64.rpm | cpio -idmv为了将来的参考(如果它将再次中断),可以在以下网址找到此备用链接:https://www.rpmfind.net/linux/rpm2html/search.php?query = libstdc%2B%2B.so.6 (GLIBCXX_3.4.16)(64位) (4认同)

小智 16

我有同样的问题,所以谷歌搜索我做了这些步骤:

$ sudo pip install --upgrade virtualenv
$ virtualenv --system-site-packages ~/tensorflow
$ cd ~/tensorflow
$ source bin/activate
$ pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.5.0-cp27-none-linux_x86_64.whl
$ cd /tmp
$ wget http://launchpadlibrarian.net/137699828/libc6_2.17-0ubuntu5_amd64.deb
$ wget http://launchpadlibrarian.net/137699829/libc6-dev_2.17-0ubuntu5_amd64.deb
$ mkdir libc6_2.17
$ cd libc6_2.17
$ ar p ../libc6_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
$ ar p ../libc6-dev_2.17-0ubuntu5_amd64.deb data.tar.gz | tar zx
$ cd -
$ LD_LIBRARY_PATH=/tmp/libc6_2.17/lib/x86_64-linux-gnu/ /tmp/libc6_2.17/lib/x86_64-linux-gnu/ld-2.17.so bin/python local/lib/python2.7/site-packages/tensorflow/models/image/mnist/convolutional.py
Run Code Online (Sandbox Code Playgroud)

并退出:

$ deactivate 
Run Code Online (Sandbox Code Playgroud)

这对我行得通.

  • 几乎做到了!现在它说:ImportError:/usr/lib/x86_64-linux-gnu/libstdc++.so.6:找不到版本`GLIBCXX_3.4.19'(/home/yasen/tensorflow/local/lib/python2.7/site要求-packages/tensorflow /蟒/ _pywrap_tensorflow.so) (5认同)
  • 但是路径分配仍然抱怨:bin/python:加载共享库时出错:libpython2.7.so.1.0:无法打开共享对象文件:没有这样的文件或目录 (4认同)
  • @loretoparisi,这个解决方案可能适用于运行简单的脚本(将新的GLIBC添加到LD_LIBRARY_PATH并立即启动特定的python脚本).执行此操作后,控制台会话将[破解](https://github.com/tensorflow/tensorflow/issues/110#issuecomment-220009120) - 之后将其删除.**重要的是永远不要将这些库永久地添加到LD_LIBRARY_PATH**(以及任何"特殊文件夹" - 只需将它们保存在`/ tmp`中,如此处所示),您的系统就可以了. (2认同)
  • 完成后,它说ImportError:/usr/lib64/libstdc++.so.6:找不到版本`GLIBCXX_3.4.14' (2认同)

Thé*_*o T 10

好的,这是我在之前的回答中提到的另一个解决方案,它更棘手,但应该始终适用于GLIBC> = 2.12和GLIBCXX> = 3.4.13的系统.在我的情况下它是在CentOS 6.7,但它也适用于Ubuntu 12.04.

我们需要一个支持c ++ 11的gcc版本,无论是在另一台机器上还是在一个独立的安装上; 但暂时不是.

我们要做的就是编辑_pywrap_tensorflow.so二进制文件以"弱化"其libc和libstdc ++依赖项,以便ld接受链接我们将要创建的存根.然后我们将为缺少的符号创建那些存根,最后我们将在运行python时预先加载所有这些.

首先,我要感谢詹姆斯的精彩文章(http://www.lightofdawn.org/wiki/wiki.cgi/NewAppsOnOldGlibc)以及宝贵的建议,如果没有他,我就无法做到.

所以让我们从弱化依赖关系开始,它只是替换_pywrap_tensorflow.so中的正确字节.请注意,此步骤仅适用于当前版本的tensorflow(0.6.0).所以,如果它没有完成已经创建和激活你的virtualenv如果你有一个(如果你不是admin virtualenv是一个解决方案,另一个是添加--user标志到pip命令),并安装tensorflow 0.6.0(替换cpu由gpu在url如果你想要gpu版本):

pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
Run Code Online (Sandbox Code Playgroud)

让我们削弱所有烦人的依赖关系,这里是tensorflow的cpu版本的命令:

TENSORFLOW_DIR=`python -c "import imp; print(imp.find_module('tensorflow')[1])"`
for addr in 0xC6A93C 0xC6A99C 0xC6A9EC 0xC6AA0C 0xC6AA1C 0xC6AA3C; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so bs=1 seek=$((addr)) ; done
Run Code Online (Sandbox Code Playgroud)

这里是一个gpu(只运行正确的一个或你将破坏二进制):

TENSORFLOW_DIR=`python -c "import imp; print(imp.find_module('tensorflow')[1])"`
for addr in 0xDC5EA4 0xDC5F04 0xDC5F54 0xDC5F74 0xDC5F84 0xDC5FA4; do printf '\x02' | dd conv=notrunc of=${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so bs=1 seek=$((addr)) ; done
Run Code Online (Sandbox Code Playgroud)

您可以查看:

readelf -V ${TENSORFLOW_DIR}/python/_pywrap_tensorflow.so
Run Code Online (Sandbox Code Playgroud)

如果你想了解这里发生了什么,请看一下这篇文章.

现在我们要为缺少的libc符号创建存根:

mkdir ~/my_stubs
cd ~/my_stubs
MYSTUBS=~/my_stubs
printf "#include <time.h>\n#include <string.h>\nvoid* memcpy(void *dest, const void *src, size_t n) {\nreturn memmove(dest, src, n);\n}\nint clock_gettime(clockid_t clk_id, struct timespec *tp) {\nreturn clock_gettime(clk_id, tp);\n}" > mylibc.c
gcc -s -shared -o mylibc.so -fPIC -fno-builtin mylibc.c
Run Code Online (Sandbox Code Playgroud)

需要在具有缺少依赖项的计算机上执行该步骤(或者具有类似版本的标准库的计算机(例如,在集群中)).

现在我们可能会更换机器,因为我们需要一个支持c ++ 11的gcc,而且它可能不在缺少所有依赖项的机器上(或者你可以使用最近的gcc的独立安装).在下面我假设我们仍然在,~/my_stubs并且不知何故你在机器上分享你的家,否则你只需要复制我们将在完成后生成的.so文件.

因此,我们可以为libstdc ++做一个存根,对于剩下的那些存根,我们将从gcc源代码编译它们(克隆存储库可能需要一些时间):

printf "#include <functional>\nvoid std::__throw_bad_function_call(void) {\nexit(1);\n}" > bad_function.cc
gcc -std=c++11 -s -shared -o bad_function.so -fPIC -fno-builtin bad_function.cc
git clone https://github.com/gcc-mirror/gcc.git
cd gcc
mkdir my_include
mkdir my_include/ext
cp libstdc++-v3/include/ext/aligned_buffer.h my_include/ext
gcc -I$PWD/my_include -std=c++11 -fpermissive -s -shared -o $MYSTUBS/hashtable.so -fPIC -fno-builtin libstdc++-v3/src/c++11/hashtable_c++0x.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/chrono.so -fPIC -fno-builtin libstdc++-v3/src/c++11/chrono.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/random.so -fPIC -fno-builtin libstdc++-v3/src/c++11/random.cc
gcc -std=c++11 -fpermissive -s -shared -o $MYSTUBS/hash_bytes.so -fPIC -fno-builtin ./libstdc++-v3/libsupc++/hash_bytes.cc
Run Code Online (Sandbox Code Playgroud)

就是这样!您现在可以通过预加载所有共享库(以及本地libstdc ++)来运行tensorflow python脚本:

LIBSTDCPP=`ldconfig -p | grep libstdc++.so.6 | grep 64 | cut -d' ' -f4` #For 64bit machines
LD_PRELOAD="$MYSTUBS/mylibc.so:$MYSTUBS/random.so:$MYSTUBS/hash_bytes.so:$MYSTUBS/chrono.so:$MYSTUBS/hashtable.so:$MYSTUBS/bad_function.so:$LIBSTDCPP" python ${TENSORFLOW_DIR}/models/image/mnist/convolutional.py
Run Code Online (Sandbox Code Playgroud)

:)