/ DeepLearning

深度学习环境简易折腾指南

最近在自己的电脑以及一台Dell PowerEdge T630服务器上分别折腾了一下深度学习环境,主要是GPU加速的TensorFlow。以下是过程以及需要注意的事项:

在Windows上配置TensorFlow

本机的配置为Windows 10 1803版本,显卡为NVIDIA GeForce GT850M,比较弱_(:з」∠),不过折腾方法大同小异。由于是NVIDIA的显卡,可以支持CUDA加速TensorFlow运算,于是打算装TensorFlow-GPU版本。如果不是使用NVIDIA显卡的话,直接安装CPU版本的就好啦。本文中使用的驱动版本为397.64,CUDA版本为9.0,TensorFlow版本为1.8,Python3环境使用Anaconda3,cuDNN版本为7.0。

Step 1:安装显卡驱动

这一步就不赘述了,Windows下安装显卡驱动的方式十分简单粗暴,只要去NVIDIA官网驱动下载下载对应系统版本以及显卡版本的驱动程序安装即可。这里有个坑,Windows Server版本不支持GeForce系列、Titan系列显卡的驱动,因此如果是服务器的话,还是选择装Ubuntu吧,毕竟Tesla系列显卡性价比要低很多。

Step 2:安装VS2017

由于在安装CUDA的时候,CUDA安装程序需要对一些核心库进行编译,依赖Visual Studio的C++编译器,于是安装Visual Studio 2017 Community版本,之后选择C++编译器进行安装。
Visual Studio Installer
C----

Step 3:安装CUDA 9.0

因为TensorFlow官方目前最高1.8版本只支持到CUDA 9.0,如果想要使用最新CUDA的话要自己魔改……于是去官网下载CUDA和CUDNN,记得在Legacy Release里找到所需版本,然后下载对应操作系统的离线安装包(exe[local])。否则大天朝的网络会教你做人。
CUDA_Download
这里我遇到一个巨坑……无论如何都无法安装CUDA。显示如下:
CZA-Y-32-_M3T-XGQCTBWMV

最后在一个小小的贴吧发现了一个解决办法:安装过程中选择自定义,并且不勾选Visual Studio Integration,成功安装CUDA9.0。测试如下,能看到版本号则说明正常:
nvcc
CUDA的坑真是巨大无比TAT

Step 4:安装cuDNN 7.0

官网链接
这里注意选择合适的cuDNN版本,TensorFlow支持CUDA 9.0以及cuDNN 7.0。官方文档写得很详细,直接阅读官方文档请点击传送门。如果懒得看官方文档的话,请看官进行如下步骤:

  • 解压cuDNN压缩包;
  • 解压路径\cuda\bin\cudnn64_7.dll复制到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\bin
  • 解压路径\cuda\include\cudnn.h复制到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\include
  • 解压路径\cuda\lib\x64\cudnn.lib复制到C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64

大功告成~

Step 5:安装TensorFlow-GPU

如果以上步骤都能成功完成的话……那么终于来到了最后一步,安装TensorFlow-GPU。到这一步就非常简单了。

  • 如果使用anaconda的话,最好先建立一个独立的环境:
    conda create -n tf pip python=3.6
  • 然后运行:
    pip install tensorflow-gpu
  • 如果只装CPU版的话,则使用:
    pip install tensorflow

然后就等啊等,等啊等~就好了!

在Ubuntu上配置TensorFlow

在服务器上配置TensorFlow可是费尽了心机,非常痛苦
最初服务器装了Windows Server 2012 R2的操作系统,驱动、CUDA安装win8.1的标准装起来,一大堆问题,后去咨询了NVIDIA客服,答曰服务器不支持NVIDIA 1080 Ti来跑深度学习(就是为了卖Tesla系列来赚钱)。于是一怒之下换了Ubuntu 16.04 LTS Desktop(这里说一下,截至2018.5.28日,Ubuntu 18.04 LTS在安装显卡驱动、CUDA等程序的时候有问题,包括但不仅限于gcc版本过高需降级至5.0等问题)。折腾过程以及安装遇到的坑都会慢慢说来:

对系统进行更新

装完Ubuntu 16.04后,首先需要对系统程序进行升级,国内用户可选使用清华的Ubuntu源。然后进行如下操作:

sudo apt upgrade
sudo apt update

然后就可以折腾基于Ubuntu的深度学习环境了。

安装NVIDIA驱动

Ubuntu配置深度学习环境的巨坑基本上都在这里了,列举一下我遇到的坑:

  • 安装驱动后循环登录(桌面环境);
  • 安装驱动后无法正常显示;
  • 输入密码错误的话会导致NVIDIA驱动被移除(CUDA不会被移除);

基本流畅如下:

安装环境必须的依赖包

输入如下命令对依赖包进行更新或安装:

sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler

sudo apt-get install --no-install-recommends libboost-all-dev

sudo apt-get install libopenblas-dev liblapack-dev libatlas-base-dev

sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev

sudo apt-get install git cmake build-essential

一般来说,若无明显报错则为安装成功。

下载驱动

NVIDIA官网驱动下载页面选择下载相应显卡、系统版本的驱动程序。
NVIDIA_DRIVER_DOWNLOAD

重启进入BIOS关闭Secure Boot

这一步我跳过了,因为PowerEdge T630未使用UEFI进行系统引导,于是并不存在Secure Boot。

禁用nouveau驱动

nouveau为Ubuntu系统集成的开源显卡驱动程序,我们需要将它禁用掉,否则可能会与NVIDIA驱动有冲突。
/etc/modprobe.d/使用sudo权限创建一个blacklist-nouveau.conf文件并写入如下内容:

blacklist nouveau
options nouveau modeset=0

接着运行如下命令行来对配置进行更新:
sudo update-initramfs -u
重启系统,键入lsmod | grep nouveau,若无输出,则说明nouveau已经被禁用

安装GPU驱动

网上有教程推荐添加ppa源,然后使用apt对NVIDIA驱动进行管理,这里我不推荐这么做,一方面可能会无法正确安装最新版本的驱动,另一方面有一些安装参数无法添加,会涉及到我提到的第一坑——循环登录。
于是还是安安心心下载好驱动程序,通过sudo chmod 777 NVIDIA-Linux-x86_64-390.59.run(请自行修改所下载文件的文件名)赋予权限。
然后退出登录,使用快捷键Ctrl+Alt+F1进入文本模式,登录;使用命令sudo service lightdm stop来关闭X-windows服务。
接着使用如下命令安装(请自行修改所下载文件的文件名):
sudo ./NVIDIA-Linux-x86_64-390.59.run --no-opengl-files
--no-opengl-files参数的意义是不安装OpenGL来代替原有的X11环境,在PowerEdge T630上不添加该命令会导致循环登录,重复出现密码框而无法进入系统
在安装过程中会有一些警告,大部分都可以直接accept,但是如果使用NVIDIA-Setting来替换Xorg的配置文件的话,会导致桌面分辨率显示出错。因为本机使用板载显卡来进行图像输出,而四张高性能的NVIDIA 1080Ti用来做计算加速,因此也无需使用NVIDIA显卡进行图像输出,于是选择不替换Xorg配置文件。

顺利的话,在一系列的进度条之后你应该能看到Successful的字样,表示安装成功,此时输入命令sudo service lightdm start来重新启动桌面环境,按Ctrl+Alt+F7从文本模式进入图形界面。
重启电脑,进入系统,输入nvidia-smi命令,顺利的话,你应该看到如下图示,表示驱动成功安装:
nvidia-smi

安装CUDA与cuDNN

下载CUDA

CUDA官网下载所需版本CUDA,最好选择runfile(local)文件进行下载,如图:
CUDA_DOWNLOAD-1

安装CUDA

通过如下命令给予CUDA的runfile文件权限并执行安装(请自行修改所下载文件的文件名):

sudo chmod 777 cuda_9.2.88_396.26_linux.run
sudo ./cuda_9.2.88_396.26_linux.run

在这里需要注意,由于我们已经安装了NVIDIA驱动程序,因此CUDA安装程序在询问是否安装驱动程序时,要选择N来拒绝!

设置环境变量

对你正在使用的shell的环境变量进行配置,如果你使用默认的bash的话,请编辑sudo vim ~/.bashrc,我使用的是zsh,因此要编辑sudo vim ~/.zshrc,在文件最后添加如下代码:

export PATH=/usr/local/cuda-9.0/bin:$PATH  
export LD_LIBRARY_PATH=/usr/local/cuda9.0/lib64:$LD_LIBRARY_PATH
export CUDA_HOME=/usr/local/cuda

保存退出,重启terminal使配置文件生效。

这时可通过nvcc -V来检查CUDA是否配置正确,如果显示NVCC相应版本则说明正确安装CUDA。

安装cuDNN

cuDNN官网找到对应CUDN版本以及TensorFlow所需版本的cuDNN进行下载(这里需要注册一个账号才能继续下载)。然后使用如下命令将cuDNN解压并复制到对应目录并赋予对应权限即可:

tar -xzvf cudnn-9.0-linux-x64-v7.tgz

sudo cp cuda/include/cudnn.h /usr/local/cuda/include
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*

至此NVIDIA驱动、CUDA、cuDNN就全部安装完成啦!

通过Anaconda安装TensorFlow-GPU

这一步同Windows中的类似,按照Anaconda官网的文档进行安装、创建虚拟环境、使用pip进行安装tensorflow-gpu版本即可。

TensorFlow-GPU测试

在这里贴一个TensorFlow-GPU版本的测试代码。若一切均成功的话,在输出的过程log中会有相应显卡的信息,并且正确计算出结果。代码如下:

import tensorflow as tf
import datetime
#running
# Creates a graph.(cpu version)
print('cpu version')
starttime1 = datetime.datetime.now()
with tf.device('/gpu:0'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0,1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[6, 9], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0,1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[9, 6], name='b')
  c = tf.matmul(a, b)
  c = tf.matmul(c,a)
  c = tf.matmul(c,b)
# Creates a session with log_device_placement set to True.
sess1 = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
for i in range(59999):
    sess1.run(c)
print(sess1.run(c))
sess1.close()
endtime1 = datetime.datetime.now()
time1 = (endtime1 - starttime1).microseconds
#print('time1:',time1)
#############################################
print('gpuversion')
# Creates a graph.(gpu version)
starttime2 = datetime.datetime.now()
#running
with tf.device('/gpu:0'):
  a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0,1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[6, 9], name='a')
  b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0,1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[9, 6], name='b')
  c = tf.matmul(a, b)
  c = tf.matmul(c,a)
  c = tf.matmul(c,b)
# Creates a session with log_device_placement set to True.
sess2 = tf.Session(config=tf.ConfigProto(log_device_placement=True))
# Runs the op.
for i in range(59999):
    sess2.run(c)
print(sess2.run(c))
sess2.close()
endtime2 = datetime.datetime.now()
time2 = (endtime2 - starttime2).microseconds
print('time1:',time1)
print('time2:',time2)

测试结果如图:
gpu_info
gpu_test_result

说明一切都正常!

完结撒花✿✿ヽ(°▽°)ノ✿

深度学习环境简易折腾指南
Share this

Subscribe to Zed's Blog