这些天很忙有些时间没上来写东西了,怕时间久了忘记遇到过的各种错误及解决办法的细节,今天周末来补上前面没做完的功课。
前面说过,需安装什么版本的CUDA和cuDNN取决于你安装的Tensorflow GPU版本对应支持到了哪个版本的CUDA,Tensorflow1.8仍只支持到了CUDA9.0,所以你盲目下载最新的CUDA9.2安装的话,后面你安装gpu版Tensorflow后,运行Tensoflow时就会报Import Error: Could not find 'cudart64_90.dll'之类的错误。
在Windows10下面,确定了CUDA版本下载后就可以安装了,在Linux下就没这么简单了,你不注意你的Linux环境,安装时就会让你面对一个又一个的错误,会让你喝几壶茶后都还是不能解决问题。
使用runfile安装时在完成多个步骤确认和设置后后面的过程实际上是把源码解压出来安装头文件并编译源码生成多个ko文件的过程,这期间需要使用到你Linux的gcc编译环境,如果你的Linux版本比较高,使用的gcc版本也就比较高,CUDA就可能不支持!比如我开始是使用的Fedora28,里面的gcc是8.1版本的,而CUDA9.0在安装过程中编译ko文件时需要使用不大于gcc 6的版本,于是报错:
error -- unsupported GNU version! gcc versions later than 6 are not supported!
这是/usr/local/cuda/include/crt/host_config.h里这段代码报的错:
#if defined(__GNUC__)
#if __GNUC__ > 6
#error -- unsupported GNU version! gcc versions later than 6 are not supported!
#endif /* __GNUC__ > 6 */
这里即使你把这个6改成8,后面编译时仍旧会报其他错误,因为gcc高版本和低版本之间往往有比较大的改动,头文件里的一些结构变量定义都发生了变化,十分头疼。我试过使用CentOS-SCLo-scl.repo安装devtoolset 6(里面有gcc6全套环境),但是安装是提示需要把Fedoda28的一些核心包要删除或者回退,那样岂不是引起大乱,只好作罢,然后又从GNU网站上下载gcc6.4.1源码包,费尽千辛万苦解决各种编译错误后,强制把/usr下的gcc及其lib,lib64库改链接指向使用gcc6.4,结果系统崩溃了,使用网上推荐的update alternatives install办法安装gcc6,然后改bin文件和库的链接指向gcc6,结果仍然编译报很多错,看来本机Linux默认安装的gcc版本如果和需要安装的低版本gcc相差大时(很多头文件里定义变了),这么做不容易解决问题。所以,根据CUDA下载页面的提示安装对应版本的Linux会省去了这些因为gcc版本不对出现的编译错误的麻烦。
比如,我想在Fedora环境下安装CUDA,查看下载页面会发现对于CUDA9.1和9.2,支持的最高版本是Fedora27,而CUDA9.0则只支持到了Fedora25:
Fedora25安装时的默认gcc版本就是6.2或6.4,Fedora27的默认gcc版本是gcc7,而Fedora28的默认gcc版本是8.1,为了节省时间省去因为编译器不对产生的各种莫名错误,所以我重装了本子,改安装了Fedora25。
各种Linux支持CUDA9.0的最高版本如下(你想在上面安装CUDA9.0的Linux版本不得超过下面列出的这些版本):
Distribution | Kernel | GCC | GLIBC | ICC | PGI | XLC | CLANG |
---|---|---|---|---|---|---|---|
x86_64 | |||||||
RHEL 7.x | 3.10 | 4.8.5 | 2.17 | 17.0 | 17.1 | NO | 3.9 |
RHEL 6.x | 2.6.32 | 4.4.7 | 2.12 | ||||
CentOS 7.x | 3.10 | 4.8.5 | 2.17 | ||||
CentOS 6.x | 2.6.32 | 4.4.7 | 2.12 | ||||
Fedora 25 | 4.8.8 | 6.2.1 | 2.24-3 | ||||
OpenSUSE Leap 42.2 | 4.4.27 | 4.8 | 2.22 | ||||
SLES 12 SP2 | 4.4.21 | 4.8.5 | 2.22 | ||||
Ubuntu 17.04 | 4.9.0 | 6.3.0 | 2.24-3 | ||||
Ubuntu 16.04 | 4.4 | 5.3.1 | 2.23 | ||||
POWER8(*) | |||||||
RHEL 7.x | 3.10 | 4.8.5 | 2.17 | NO | 17.1 | 13.1.5 | NO |
Ubuntu 16.04 | 4.4 | 5.3.1 | 2.23 | NO | 17.1 | 13.1.5 | NO |
(*) Only the Tesla P100 GPU is supported for CUDA 9.0 on POWER8.
解决了编译环境,下面一个重要事情就是要把安装Linux时默认给GPU安装的nouveau driver给disabled掉(因为CUDA安装程序安装的invida driver跟nouveau不能共存,nouveau driver不disable掉的话,给INVIDA GPU 安装的invida driver加载不了),在/usr/lib/modprobe.d/和/etc/modprobe.d/下各创建一个文件blacklist-nouveau.conf,内容如下:
blacklist nouveau
options nouveau modeset=0
然后备份kernel initramfs文件(我的Fedora25的initramfs是4.8.6-300版,对于Ubuntu 16.04,则是initrd.img-4.15.0-43-generic):
mv initramfs-4.8.6-300.fc25.x86_64.img initramfs-4.8.6-300.fc25.x86_64.img.bak
然后执行下面这个命令重新生成一个包含了上面的disable nouveau变化的initramfs:
sudo dracut --force
对于Ubuntu 16.04 ,则是执行sudo update-initramfs -u生成新的initramfs文件。
注意,更新initramfs文件一定要在重启之前,否则重启后仍使用没变化的initramfs文件的话nouveau禁用不了。
然后sudo reboot,重启机器后使用了新的initamfs,把nouveau禁用了。
这个其实也可以在执行CUDA安装时由CUDA安装程序完成,安装程序在前面的设置提示步骤会提示你是否要disable掉nouveau driver,输入y并回车后,安装程序会自动在/usr/lib/modprobe.d/和/etc/modprobe.d/下各创建一个文件nvidia-installer-disable-nouveau.conf,内容跟上面两行一样,然后提示你重启机器。
重启动后再执行CUDA安装程序进入安装提示步骤,提示步骤中有一步会提示你是否需要安装OpenGL libraries,这里得敲黑板划重点了!如果你的机器只有一张GPU卡并且是INVIDA的,那么可以选择安装(输入y回车),如果你的机器有两张GPU卡,平时是使用的非INVIDA的GPU卡显示,那么千万别选择安装,否则会安装完CUDA重启机器后会发现登录界面变灰了并报错Oh no! something has gone wrong:
我开始没注意到这点,选择了安装OpenGL库,结果就出现这个问题,按照网上说的一般没用,网上一般人都只讲到了怎么回退回去使用Nouveau驱动解决这个问题,但我们需要使用Invida驱动不能回退回去使用Nouveau,反复安装Linux和CUDA折腾了好几次都是出这个错误,弄到深夜不知道哪里出错引起的,后面凌晨一点回头仔细阅读CUDA Installation Guide for Linux,发现了这段很重要的话,原因就在这里,开始没注意到它,哎:
If installing the driver, the installer will also ask if the openGL libraries should be installed. If the GPU used for display is not an NVIDIA GPU, the NVIDIA openGL libraries should not be installed. Otherwise, the openGL libraries used by the graphics driver of the non-NVIDIA GPU will be overwritten and the GUI will not work. If performing a silent installation, the --no-opengl-libs option should be used to prevent the openGL libraries from being installed.
现在很多笔记本都有两块GPU卡,一块是Intel 集成显卡,一块是INVIDA独立显卡,比如我的本子就是Intel HD630 + NVIDIA GeForce 940MX,平时使用的是Intel HD显卡显示,我这种情况就不能选择安装OpenGL库,否则就把Intel HD的OpenGL库被覆盖弄坏了,重启开机后图形界面显示自然就出错了(Linux也给不出稍具体一点的提示,这点真是不友好!),开始没注意Guide里这个提示细节,瞎吃了苦头算是记忆深刻。不知道哪里去找Intel HD的驱动安装程序来修复它,所以干脆重装了Fedora25,然后在安装CUDA时没选择安装OpenGL库,后面果然没这问题了。 (早已不使用Fedora,工作需要改用Ubuntu了,Ubuntu上可以安装 intel-graphics-update-tool或者xserver-xorg-video-intel、libva-intel-vaapi-driver vainfo来恢复Intel HD驱动)
注意避开或解决了上面的问题,安装CUDA和CUDNN很简单,CUDA9.0 linux版有1个主安装文件cuda_9.0.176_384.81_linux.run和3个patch安装文件:cuda_9.0.176.1_linux.run、cuda_9.0.176.2_linux.run、cuda_9.0.176.3_linux.run,依次安装完毕即可(安装过程中会确认License Agreement和安装目标路径设置需要确认或输入),cuDNN只需要把下载的压缩文件的后缀改名为.tgz,即cudnn-9.0-linux-x64-v7.1.tgz,解压后把里面的头文件和库文件拷贝到CUDA安装的路径/usr/local/cuda/(实际是指向/usr/local/cuda-9.0的链接,安装时选择创建的)下的include和lib64目录下即可,然后在.bashrc或.bash_profile里把/usr/local/cuda/bin加入PATH环境变量,把/usr/local/cuda/lib64加入LD_LIBRARY_PATH环境变量即可,还可以增加export CUDA_HOME=/usr/local/cuda供需要的程序使用。
https://docs.nvidia.com/cuda/archive/9.0/cuda-installation-guide-linux/ 是CUDA安装的指南文档,里面列举了环境准备和各种安装方式怎么安装,没时间懒得看的话,注意我上面说的三个问题就行了。
补充一个最近发现的新问题:
安装一台台式机安装的Ubuntu 16.04 LTS,在上面安装CUDA9.0后发现图形界面进不去。
在Ubuntu 16.04上安装CUDA9.0的步骤是:
先做以下修改:
sudo vi /etc/default/grub
把 GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"中的值改为 "text",然后把GRUB_TERMINAL=console前的注释符号去掉,并执行 sudo systemctl set-default multi-user.target (该回图形界面时使用sudo systemctl set-default graphical.target),然后重启机器进入图形界面,然后安装cuda_9.0.176_384.81_linux.run和4个patch安装文件:
cuda_9.0.176.1_linux.run、cuda_9.0.176.2_linux.run、cuda_9.0.176.3_linux.run、cuda_9.0.176.4_linux.run
在安装完CUDA9.0后把/etc/default/grub和default.target链接改回原样,重启机器后结果发现图形界面进不去,输入登录口令后立即又退回登录界面,我意识到这是显卡驱动有问题了,可能是因为安装cuda_9.0.176_384.81_linux.run时选择安装了显卡驱动,而驱动程序比较老(384.81),这台台式机使用的NVIDIA GTX 1070显卡,于是我到NVIDIA网站https://www.nvidia.com/Download/index.aspx?lang=en-in上下载了个最新版的linux驱动(在下载页面的下拉选项里依次选择:Gefore/Geforce 10 Series/Geforce GTX 1070/Linux 64-bit) NVIDIA-Linux-x86_64-410.78.run,然后把Ubuntu设置成使用文本界面然后重启,再用U盘mount到/media后运行sudo ./NVIDIA-Linux-x86_64-410.78.run, 安装完毕后把Ubuntu改回使用图形界面再重启机器,就可以正常登录进去了。
关于怎么下载对应版本的CUDA和CUDNN,参见我以前写的 我的AI之路(5)--如何选择和正确安装跟Tensorflow版本对应的CUDA和cuDNN版本
我的AI之路(1)--前言
我的AI之路(2)--安装Fedora 28
我的AI之路(3)--安装Anaconda3 和Caffe
我的AI之路(4)--在Anaconda3 下安装Tensorflow 1.8
我的AI之路(5)--如何选择和正确安装跟Tensorflow版本对应的CUDA和cuDNN版本
我的AI之路(6)--在Anaconda3 下安装PyTorch
我的AI之路(7)--安装OpenCV3_Python 3.4.1 + Contrib以及PyCharm
我的AI之路(8)--体验用OpenCV 3的ANN进行手写数字识别及解决遇到的问题
我的AI之路(9)--使用scikit-learn
我的AI之路(10)--如何在Linux下安装CUDA和CUDNN
我的AI之路(11)--如何解决在Linux下编译OpenCV3时出现的多个错误
我的AI之路(12)--如何配置Caffe使用GPU计算并解决编译中出现的若干错误
我的AI之路(13)--解决编译gcc/g++源码过程中出现的错误
我的AI之路(14)--Caffe example:使用MNIST数据集训练和测试LeNet-5模型
我的AI之路(15)--Linux下编译OpenCV3的最新版OpenCV3.4.1及错误解决
我的AI之路(16)--云服务器上安装和调试基于Tensorflow 1.10.1的训练环境
我的AI之路(17)--Tensorflow和Caffe的API及Guide
我的AI之路(18)--Tensorflow的模型安装之object_detection
我的AI之路(19)--如何在Windows下安装pycocotools PythonAPI
我的AI之路(20)--用Tensorflow object_detection跑raccoon数据集
我的AI之路(21)--用Tensorflow object_detection跑PASCAL VOC 2012数据集
我的AI之路(22)--使用Object_Detection_Tensorflow_API
我的AI之路(23)--在Windows下编译Bazel和使用Bazel编译tensorflow