本文档记录了在远程服务器 Tesla K80 Redhat 系统上安装 GPU 版 tensorflow 的过程

一、安装 CUDA

1. 准备工作:

Step 1 保证你的 GPU 支持 CUDA

# lspci | grep -i nvidia
86:00.0 3D controller: NVIDIA Corporation GK210GL [Tesla K80] (rev a1)
86:00.0 3D controller: NVIDIA Corporation GK210GL [Tesla K80] (rev a1)

Step 2 保证你的 Linux 支持 CUDA

# uname -m && cat /etc/*release
x86_64
LSB_VERSION=...
Red Hat Enterprise Linux Server release 6.7 (Santiago)
Red Hat Enterprise Linux Server release 6.7 (Santiago)

Step 3 保证你的系统安装了正确的 gcc 版本

# gcc -version
gcc (GCC) 4.4.7 20120312 (Red Hat 4.4.7-16)
...

此外,g++ 也是需要的,我准备了和 gcc 版本相同的 libstdc++-4.4.7-16.el6.x86_64.rpm 和 gcc-c++-4.4.7-16.el6.x86_64.rpm:

# rpm ivh libstdc++-4.4.7-16.el6.x86_64.rpm
# rpm ivh gcc-c++-4.4.7-16.el6.x86_64.rpm

当然如果你的机器可以直连外网,也可以通过 yum 自动下载安装。

Step 4 保证你的系统有正确的 Kernal Headers 和开发包

查看你的内核版本:

# uname -r
2.6.32-573.el6.x86_64

根据你的内核版本安装 Kernal Headers 和相应的开发包:

# sudo yum install kernel-devel-$(uname -r) kernel-headers-$(uname -r)

你可能会遇到以下问题:

This system is not registered to red hat subscription management. You can use subscription-manager

这是由于你的 Redhat 没有注册,具体注册流程参考这篇文章;或者是由于服务器网络受限无法连接到 yum 源,你可以通过下载相应内核的 Kernal-headers 和 Kernal-devel 的 rpm 来进行本地安装,可以选择到 rpmfind 或者 pbone 自行下载。

比如对于我的内核版本,可以搜索:

  • kernel-headers-2.6.32-573.el6.x86_64.rpm
  • kernel-devel-2.6.32-573.el6.x86_64.rpm

安装:

rpm -ivh kernel-headers-2.6.32-573.el6.x86_64.rpm
rpm -ivh kernel-devel-2.6.32-573.el6.x86_64.rpm

Step6 下载 NVIDIA CUDA Toolkit

根据自己的系统下载对应的安装文件,这里建议选择 runfile(local),之前在 Ubuntu 上被 .deb 坑惨了所以这里不敢用 .rpm 了…

注意!

下载完一定要做校验!

下载完一定要做校验!

下载完一定要做校验!

由于文件比较大,而且最早的时候 NVIDIA CUDA 的源很不稳定,下载速度比较慢(后来改善了许多),但一定要保证自己下的文件是没问题的,不然以后安装的时候错都不知道错哪了。

# md5sum cuda_8.0.61_375.26_linux.run
33e1bd980e91af4e55f3ef835c103f9b cuda_8.0.61_375.26_linux.run

Step7 保证你的系统没有安装 CUDA

安装之前,把之前安装过的和 CUDA 有关的文件删干净(如果你安装过的话)。

由于服务器之前是干净的,这里说一下原来在 Ubuntu 下卸载 CUDA 相关文件的方法:

# .run
$ sudo /usr/local/cuda-8.0/bin/uninstall_cuda_8.0.pl
$ sudo /usr/bin/nvidia-uninstall
# .deb
$ sudo apt-get remove --purge nvidia-*
$ sudo apt-get remove --purge cuda*

2. 安装 CUDA:

Step1 禁用 Nouveau

检测你的系统中 Nouveau 是否被禁用

# lsmod | grep nouveau
nouveau                 1340573     0
ttm                       89408     1 nouveau
drm_kms_helper            88766     1 nouveau
...
...

如果此命令有任何输出,说明你的 Nouveau 并没有被禁用,通过以下方式禁用:

# cd /etc/modprobe.d/
# vi blacklist-nouveau.conf

在 blacklist-nouveau.conf 中输入

blacklist nouveau
options nouveau modeset=0

重新生成内核的 initramfs:

# sudo dracut --force

重启后查看 Nouveau 是否被成功禁用

# lsmod | grep nouveau

此时没有任何输出

Step2 开始安装!

# sudo sh cuda_8.0.61_375.26_linux.run

这里我没有装 OpenGL,因为当初在 Ubuntu 下安装的时候听说是大坑,我也踩了,所以这里就不再装了。

安装完后 reboot 一下进入下一步

3. 检测 CUDA 是否成功安装

在安装结束后发现输入以下命令是没有结果的:

# ls /dev/nvi*

于是检查 CUDA 的配置,进行了以下操作:

  • 配置 lib 和 PATH:
echo -e "/usr/local/cuda/lib64\n/usr/local/cuda/lib" > /etc/ld.so.conf.d/cuda.conf
echo "export PATH=/usr/local/cuda/bin:$PATH" > /etc/profile.d/cuda.sh
/sbin/ldconfig
  • 创建了 /etc/init.d/nvidia 文件,该文件内容用于在启动时初始化 NVIDIA 驱动及 CUDA 环境:
#!/bin/bash
#
# Startup/shutdown script for nVidia CUDA
#
# chkconfig: 345 80 20
# description: Startup/shutdown script for nVidia CUDA

# Source function library.
. /etc/init.d/functions

DRIVER=nvidia
RETVAL=0

# Create /dev nodes for nvidia devices
function createnodes() {
   # Count the number of NVIDIA controllers found.
   N3D=`/sbin/lspci | grep -i NVIDIA | grep "3D controller" | wc -l`
   NVGA=`/sbin/lspci | grep -i NVIDIA | grep "VGA compatible controller" | wc -l`

   N=`expr $N3D + $NVGA - 1`
   for i in `seq 0 $N`; do
       mknod -m 666 /dev/nvidia$i c 195 $i
       RETVAL=$?
       [ "$RETVAL" = 0 ] || exit $RETVAL
   done

   mknod -m 666 /dev/nvidiactl c 195 255
   RETVAL=$?
   [ "$RETVAL" = 0 ] || exit $RETVAL
}

# Remove /dev nodes for nvidia devices
function removenodes() {
   rm -f /dev/nvidia*
}

# Start daemon
function start() {
   echo -n $"Loading $DRIVER kernel module: "
   modprobe $DRIVER && success || failure
   RETVAL=$?
   echo
   [ "$RETVAL" = 0 ] || exit $RETVAL

   echo -n $"Initializing CUDA /dev entries: "
   createnodes && success || failure
   RETVAL=$?
   echo
   [ "$RETVAL" = 0 ] || exit $RETVAL
}

# Stop daemon
function stop() {
   echo -n $"Unloading $DRIVER kernel module: "
   rmmod -f $DRIVER && success || failure
   RETVAL=$?
   echo
   [ "$RETVAL" = 0 ] || exit $RETVAL

   echo -n $"Removing CUDA /dev entries: "
   removenodes && success || failure
   RETVAL=$?
   echo
   [ "$RETVAL" = 0 ] || exit $RETVAL
}

# See how we were called
case "$1" in
   start)
       start
      ;;
   stop)
       stop
      ;;
   restart)
       stop
       start
      ;;
   *)
       echo $"Usage: $0 {start|stop|restart}"
       RETVAL=1
esac
exit $RETVAL

启用该文件:

# cp nvidia /etc/init.d/nvidia -f
# chmod a+x /etc/init.d/nvidia
# chkconfig nvidia on
# reboot

此时再次尝试以下命令:
查看已经创建的 NVIDIA 设备

# ls /dev/nvi*
nvidia0     nvidia1     nvidiactl
# nvidia-smi -L
GPU 0: Tesla K80 (UUID: GPU-XXX...XXX)
GPU 1: Tesla K80 (UUID: GPU-XXX...XXX)

检查所支持的 NVIDIA 显卡:

# lspci -d "10de:*" -v
86:00.0 3D controller: NVIDIA Corporation GK210GL [Tesla K80] (rev a1)
         ...
         ...
         ...
86:00.0 3D controller: NVIDIA Corporation GK210GL [Tesla K80] (rev a1)
         ...
         ...
         ...

4. 编译并运行 CUDA Examples

# cd NVIDIA_Examples_DIRECTORY/
# make

make 的时间会比较长,而且会出一大波 warning,不过不用担心。

编译结束后,运行 deviceQuery 启用该文件:

# cd bin/x86_64/linux/release/
# ./deviceQuery

如果没有出现报错,恭喜,你已经成功安装了 CUDA。

5. 将 CUDA 的相关环境变量添加到 ~/.bashrc 中

# vim ~/.bashrc

输入以下内容:

# CUDA Toolkit
export CUDA_HOME=/usr/local/cuda-7.5
export LD_LIBRARY_PATH=\${CUDA_HOME}/lib64:$LD_LIBRARY_PATH
export PATH=\${CUDA_HOME}/bin:${PATH}

保存并使其生效:

# source ~/.bashrc

二、安装 cuDNN

1. 下载 cuDNN

该操作需要注册 nvidia 用户,但过程很简单,审批也很快的~

这里我下载的是 cudnn-8.0-linux-x64-v5.1.tar

2. 解压 cuDNN 并 复制到 CUDA 对应文件中

Step 1. 解压 cudnn

# tar -zxvf cudnn-8.0-linux-x64-v5.1.tar

Step 2. 复制相关文件到 CUDA 中

# cp cudnn.h CUDA_DIR/include
# cp libcudnn* CUDA_DIR/lib64

Step 3. 对 cuDNN library 创建软连接

# ln -s libcudnn.so.5 libcudnn.so.5.1.10
# ln -s libcudnn.so libcudnn.so.5

三、安装 Anaconda

下载 Anaconda

这里我下载的版本是 Anaconda3-4.3.1-Linux-x86_64.sh

安装命令:

# bash Anaconda3-4.3.1-Linux-x86_64.sh

四、安装 Tensorflow

下载 Tensorflow

这里我下载的版本是 tensorflow_gpu-1.0.1-cp36-cp36m-linux_x86_64.whl

1. 安装 protobuf(无法访问外网时需要手动操作)

安装 tensorflow 时需要 protobuf,对于 tensorflow_gpu-1.0.1,protobuf 的版本要 >= 3.1.0,我从这里 下了 protobuf-3.1.0-py2.py3-none-any.whl。

# pip install protobuf-3.1.0-py2.py3-none-any.whl

2. 安装 tensorflow

# pip install tensorflow_gpu-1.0.1-cp36-cp36m-linux_x86_64.whl

一般情况下会正常安装完毕,但在使用的时候会出现如下错误:

# python
>>> import tensorflow as tf
Trackback (most rencent call last):
...
...
...
ImportError: /lib64/libc.so.6: version 'GLIBC_2.16' not found (required by /root/anaconda3/lib/python3.6/site-packages/tensorflow/python/_pyware_tensorflow.so)

这是由于你的 glibc 版本太低,需要安装更高版本的.根据系统从这里下载了 glibc-2.16.0.tar.gz

有人说安装的时候尽量不要覆盖原来的 glibc, 于是我一开始安装到了 /opt/glibc-2.16 目录下,但是各种 BUG… 于是就一口气干脆直接更新好了

# tar zxvf glibc-2.16.0.tar.gz
# cd glibc-2.16.0/
# mkdir build
# cd build
# ../configure --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
# make
# make install

在 make install 的时候可能发生错误,如果出现 error,可进行如下操作:

查看 /lib64/libc.so.6 的链接:

# ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 19 Mar 30 00:16 /lib64/libc.so.6 -> /lib64/libc-2.12.so

说明此时还链接在 2.12 上

在 build 目录下 make 之后会发现有 libc.so.6 文件

# ll libc.so.6
lrwxrwxrwx 1 root root 7 Sep 23 07:41 libc.so.6 -> libc.so
# strings libc.so | grep GLIBC  
GLIBC_2.2.5  
GLIBC_2.2.6  
GLIBC_2.3  
GLIBC_2.3.2  
GLIBC_2.3.3  
GLIBC_2.3.4  
GLIBC_2.4  
GLIBC_2.5  
GLIBC_2.6  
GLIBC_2.7  
GLIBC_2.8  
GLIBC_2.9  
GLIBC_2.10  
GLIBC_2.11  
GLIBC_2.12  
GLIBC_2.13  
GLIBC_2.14  
GLIBC_2.15  
GLIBC_2.16  
GLIBC_PRIVATE

这表示当前 libc 已经成功安装到了 2.16,可以将该文件复制到 /lib64 下,并:

# cp /path/to/glibc-2.16/build/libc.so /lib64/libc-2.16.so  
# rm -f /lib64/libc.so.6
# LD_PRELOAD=/lib64/libc-2.16.so ln -s /lib64/libc-2.16.so lib64/libc.so.6

如果执行第三条命令时出现

error while loading shared libraries: __vdso_time: invalid mode for dlopen(): Invalid argument

不要慌张,根据之前版本的 libc 可以恢复,我的是 2.12 版,执行以下命令可以恢复:

# LD_PRELOAD=/lib64/libc-2.12.so ln -s /lib64/libc-2.12.so lib64/libc.so.6

安装完之后发现

# python
>>> import tensorflow as tf
Trackback (most rencent call last):
...
...
...
ImportError: /lib64/libc.so.6: version 'GLIBC_2.17' not found (required by /root/anaconda3/lib/python3.6/site-packages/tensorflow/python/_pyware_tensorflow.so)

哥,你不能一次把话说完?按照上面的步骤把 GLIBC_2.17 安装了即可