本文档记录了在远程服务器 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
这里我下载的版本是 Anaconda3-4.3.1-Linux-x86_64.sh
安装命令:
# bash Anaconda3-4.3.1-Linux-x86_64.sh
四、安装 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 安装了即可