现在机器学习异常火热,智能大会也在天津进行的如火如荼,英伟达的AI芯大卖股价暴涨,学术界的很多方面也需要结合机器学习来研究一些新内容,有必要搭建一个机器学习框架。Tensorflow是TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,现在(写于2018-5-16)已经推出版本1.8。Tensorflow有仅用CPU的版本,这个安装很简单,可以官方参考文档。为了发挥GPU运算的优势,提高运算速度,这里搭建一个GPU版本的Tensorflow,这个笔记和大家分享,一起学习。

一、软硬件条件

这里选择在Ubuntu 16.04 LTS系统(在Ubuntu下可用cat /etc/issue 查看版本号),根据官网的文档,安装GPU版本的Tensorflow需要满足以下先决条件:

  • CUDA® 工具包 9.0。如需了解详情,请参阅 NVIDIA 文档。请务必按照 NVIDIA 文档中的说明将相关的 CUDA 路径名附加到 LD_LIBRARY_PATH 环境变量中。
    与 CUDA 工具包 9.0 相关联的 NVIDIA 驱动程序。
  • cuDNN v7.0。如需了解详情,请参阅 NVIDIA 文档。请务必按照 NVIDIA 文档中的说明创建 CUDA_HOME 环境变量。
  • CUDA 计算能力为 3.0 或更高的 GPU 卡(用于从源代码构建),以及 CUDA 计算能力为 3.5 或更高的 GPU 卡(用于安装我们的二进制文件)。如需了解支持的 GPU 卡的列表,请参阅 NVIDIA 文档。
  • libcupti-dev 库,这是 NVIDIA CUDA 分析工具接口。此库提供高级分析支持。要安装此库,请针对 CUDA 工具包 8.0 或更高版本发出以下命令:

$ sudo apt-get install cuda-command-line-tools

并将其路径添加到您的 LD_LIBRARY_PATH 环境变量中:

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64

对于 CUDA 工具包 7.5 或更低版本,请发出以下命令:

$ sudo apt-get install libcupti-dev

接下来一一检查这些条件

Ubuntu 16.04 LTS

已经成功安装Ubuntu16.04

发现服务器ping不通外网,在/etc/resolv.conf添加了一行

nameserver 114.114.114.114

但是这样重启后会被重写,改用下边这种方法

sudo vim /etc/resolvconf/resolv.conf.d/base

添加

nameserver 114.114.114.114

本来为了避免安装软件的过程中过慢或者卡死,将系统源替换为国内镜像,可是发现国内的源要不丢包,要不更新慢,最后还是用回了原装,事实证明转装的最好用,不慢还齐全。

NVIDIA® GPU

首先需要保证有NVIDIA® GPU而且支持CUDA。
发现系统中查不到NVIDIA® GPU,使用lspci和lshw找不到NVIDIA的GPU。可能是驱动的原因?首先安装驱动,去英伟达官网下载了最新的驱动NVIDIA-Linux-x86_64-390.48.run

sudo chmod a+x NVIDIA-Linux-x86_64-390.48.run
sudo ./NVIDIA-Linux-x86_64-390.48.run

安装提示:没有找不到cc命令,需要编译环境,安装gcc,make还要安装要安装build-essential,安装了这个包会安装上g++,libc6-dev,linux-libc-dev,libstdc++6-4.1-dev等好多必须的软件和头文件。

sudo apt install gcc
sudo apt install make
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev libgflags-dev libgoogle-glog-dev liblmdb-dev protobuf-compiler
sudo apt-get install build-essential

再次安装驱动,又遇到这样的错误:

ERROR: Unable to load the kernel module 'nvidia.ko'.  This happens most frequently when this kernel module was built against the wrong or improperly configured kernel sources, with a version of gcc that differs from the one used to build the target kernel, or if a driver such as rivafb, nvidiafb, or nouveau is present and prevents the NVIDIA kernel module from obtaining ownership of the NVIDIA graphics device(s), or no NVIDIA GPU installed in this system is supported by this NVIDIA Linux graphics driver release. Please see the log entries 'Kernel module load error' and 'Kernel messages' at the end of the file '/var/log/nvidia-installer.log' for more information.

查看log中显示

Kernel module load error: No such device

可能是驱动版本不对,去另一个相同服务器中查看驱动信息

nvidia-smi
驱动版本信息

驱动不是随便下的[/my fault],显卡版本是NVIDIA Tesla P100,然后下载驱动,下在过程吃到的X,都在这里
下载到nvidia-diag-driver-local-repo-ubuntu1604-390.46_1.0-1_amd64.deb

sudo dpkg -i nvidia-diag-driver-local-repo-ubuntu1604-390.46_1.0-1_amd64.deb

出错:The public CUDA GPG key does not appear to be installed.

sudo apt-key add /var/nvidia-diag-driver-local-repo-390.46/7fa2af80.pub

更新总线信息update-pciids,仍然找不到英伟达显卡。

小插曲

安装网卡驱动

最后发现显卡插口松动,换了一个插口后,成功查到显卡。
显卡信息

NVIDIA驱动

现在正式开始重新安装显卡驱动,当然上一步编译环境也是需要安装的,这里略去。
去官网下载合适版本的驱动NVIDIA-Linux-x86_64-390.46.run

1.卸载已有的驱动

sudo chmod a+x NVIDIA-Linux-x86_64-390.46.run
sudo apt-get remove --purge nvidia*
或者
sudo ./NVIDIA-Linux-x86_64-390.48.run --uninstall

2.禁用nouveau

sudo vim /etc/modprobe.d/blacklist.conf

添加

blacklist nouveau   
blacklist lbm-nouveau   
options nouveau modeset=0   
alias nouveau off   
alias lbm-nouveau off  

sudo update-initramfs -u
sudo reboot

3.开始安装

如果是使用桌面版的,先关掉桌面

sudo /etc/init.d/lightdm stop

可能有的用的不是lightdm,比如gdm,寻找对应的文件就好。

sudo ./NVIDIA-Linux-x86_64-390.46.run

提示:

The distribution-provided pre-install script failed!  Are you sure you want to continue? 直接继续

nvidia-installer was forced to guess the X library path '/usr/lib' and X module path 直接OK

Install NVIDIA's 32-bit compatibility libraries? YES

Installation of the kernel module for the NVIDIA Accelerated Graphics Driver for Linux-x86_64 (version 390.46) is now complete. OK

安装完成,重启

使用nvidia-smi 验证是否安装成功
nvidia-smi

CUDA工具包9.0

官网 下载CUDA的安装包
以.run文件为例

首先还是删除之前的安装文件

sudo dpkg -l|grep -i cuda
sudo dpkg --purge 对应文件名

安装CUDA

CUDA(Compute Unified Device Architecture)是一个并行计算框架,它使GPU可以解决复杂计算问题。详见CUDA百度词条

依次安装,CUDA和两个不定

sudo ./cuda_9.0.176_384.81_linux.run
sudo ./cuda_9.0.176.1_linux.run
sudo ./cuda_9.0.176.2_linux.run

Default Install Location of CUDA Toolkit

Windows platform:

%ProgramFiles%\NVIDIA GPU Computing Toolkit\CUDA\v#.#

Linux platform:

/usr/local/cuda-#.#

Mac platform:

/Developer/NVIDIA/CUDA-#.#

安装过程:

鉴于已经安装过显卡驱动,就不再安装了。

Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 384.81?
(y)es/(n)o/(q)uit: n

Install the CUDA 9.0 Toolkit?
(y)es/(n)o/(q)uit: y

Enter Toolkit Location
 [ default is /usr/local/cuda-9.0 ]:

创建符号链接,方便操作

Do you want to install a symbolic link at /usr/local/cuda?
(y)es/(n)o/(q)uit: y

Install the CUDA 9.0 Samples?
(y)es/(n)o/(q)uit: y

Enter CUDA Samples Location
 [ default is /home/tank ]: /home/tank/soft/cuda/samples

安装成功

安装完成切记要配置环境变量

cuda环境变量

在/etc/environment 添加CUDA的bin目录和LD_LIBRARY_PATH,并目录还要写在PATH中

LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64
CUDA_INSTALL=/usr/local/cuda-9.0/bin
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:CUDA_INSTALL"

在 ~/.bashrc中添加一行

source /etc/environment

cuDNN v7.0

cuDNN(CUDA Deep Neural Network),在CUDA基础上对神经网络操作进行了优化。

根据 官方文档
安装步骤

下载网址,需要注册NVIDIA开发者账号,下载如下三个文件
下载列表

sudo dpkg -i libcudnn7_7.0.5.15-1+cuda9.0_amd64.deb
sudo dpkg -i libcudnn7-dev_7.0.5.15-1+cuda9.0_amd64.deb
sudo dpkg -i libcudnn7-doc_7.0.5.15-1+cuda9.0_amd64.deb

验证是否安装成功

verifying

运行一个示例程序

cp -r /usr/src/cudnn_samples_v7/ ~/soft/cudnn/cudnn_samples_v7
cd ~/soft/cudnn/mnistCUDNN/
make clean && make
./mnistCUDNN

报错:

 error while loading shared libraries: libcudart.so.9.0: cannot open shared object file: No such file or directory

解决方法:

在 /etc/ld.so.conf.d/加入文件 cuda.conf, 内容如下
/usr/local/cuda-6.5/lib64  

试用以下命令使之生效。

sudo ldconfig

再次运行 ./mnistCUDNN ,出现Test passed!,测试通过。
官网提供的说明说要按照NVIDIA文档配置CUDA_HOME,但是文档里没有写,在网上查到配置方法

CUDA_HOME=/usr/local/cuda

或者

CUDA_HOME=/usr/local/cuda-9.0

这是因为在安装过程中选择了创建符号链接可以用cuda代指cuda-9.0文件

并在PATH中添加

$CUDA_HOME/bin

所以修改环境变量如下

LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64
CUDA_HOME=/usr/local/cuda-9.0
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$CUDA_HOME/bin"

libcupti-dev 库

这是 NVIDIA CUDA 分析工具接口
官网提供了以下命令,但是提示找不到包

sudo apt-get install cuda-command-line-tools

但这个命令会报找不到package的错。
网上大部分解决方案是使用以下命令

sudo apt-get install cuda-command-line-tools-9-0

但是我使用Ubuntu-16.04,这个方法并不能解决问题,仍然报找不到包的错误。
解决方法如下,但是似乎CUPTI已经和CUDA一起安装了,没有必要在安装了。以下经供参考,个人觉得官方文档没有及时更新,这个版本已经没有必要单独安装cupti,可以查看到ls /usr/local/cuda/extras/CUPTI/lib64/ 里边是有文件的,以下的命令似乎直接重装了一遍CUDA。

curl -O http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-9-0_9.0.176-1_amd64.deb
如果报错,安装所有依赖包
sudo dpkg -i ./cuda-9-0_9.0.176-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda-9-0

将/usr/local/cuda/extras/CUPTI/lib64/ 添加到LD_LIBRARY_PATH,现在我们的环境变量如下:

LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:/usr/local/cuda/extras/CUPTI/lib64
CUDA_HOME=/usr/local/cuda-9.0
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$CUDA_HOME/bin"

SUMMARY

至此,安装Tensorflow的准备工作完成,总结一下:
先后安装

环境变量中需要添加

LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:/usr/local/cuda/extras/CUPTI/lib64  
CUDA_HOME=/usr/local/cuda-9.0

并将$CUDA_HOME/bin 添加到PATH

二、安装Tensorflow

官网提供了三种方式安装
  • Virtualenv
  • “原生”pip
  • Docker
  • Anaconda
  • 从源代码安装

我选择使用Anaconda安装

安装Anaconda

Anaconda官网下载3.6安装包

Conda是一个开源的包、环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换。Anaconda包括Conda、Python等180多个科学包及其依赖项。

安装Anaconda

sudo chmod a+x Anaconda3-5.1.0-Linux-x86_64.sh
sudo ./Anaconda3-5.1.0-Linux-x86_64.sh

创建过程会提示安装目录、是否将变更环境变量的命令写在~/.bashrc、是否安装VSCode

我选择配置环境变量,安装完之后运行一下以下命令。

source ~/.bashrc

创建tensorflow的conda环境

conda create -n tensorflow pip python=3.6 #注意版本

运行出错,提示CondaHTTPError: HTTP 000 CONNECTION FAILED for url
解决:添加国内源

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes

没有解决,原来是机房没流量了/
再运行conda create -n tensorflow pip python=3.6,运行成功。

激活Conda环境

source activate tensorflow

安装tensorflow

官网找到对应版本链接,我选择用python3.6版本的tensorflow1.6的支持GPU的版本

(tensorflow) tank@gpu2:~/soft/tensorflow$ pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-1.6.0-cp36-cp36m-linux_x86_64.whl

验证安装

激活容器

source activate tensorflow

进入python shell

python

输入示例程序

import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))

得到结果

tensorflow验证结果


更新

安装cuda 11.0+cuddnn8 后测试编译报错找不到FreeImage.h,安装一下就可以解决。

sudo apt-get install libfreeimage3 libfreeimage-dev$$