已知:GPU Cluster服务器,非root账户,python3.6+ CUDA9.2+ cuDNN7.6.5
欲:装Tensorflow r2.2(装B)
主要指引:Tensorflow官方的指引:从源代码构建
不得不说pytorch就是好用,只要在conda里面指定py版本cuda版本cudnn版本就能傻瓜式地装好,我爱pytorch,但是人家写的某些源码仍然使用tensorflow写的。所以说还是有必要把tensorflow也安排上。
官方提供的pip包(通过pip install tensorflow
安装)只有CPU版本(tf.test.is_gpu_available() -> False
),而且GPU版本(通过pip install tensorflow-gpu
安装)的官方版一般也只有9.0或者10.0版本的pip包[1]。看了别人有说解决方案可以是直接用别人编译好的.whl包,但是找了一个试了一下好像8太彳亍。还有建议装CUDA其他版本的,我也没去试了。思前想后,最后还是决定根据官方指引,直接从源代码编译。
首先安装bazel。我直接在bazel的Github仓库中下载了bazel-2.2.0-installer-linux-x86_64.sh(可以用wget下载但是没必要,直接先开本地加速下载再用scp更加快嘻嘻)然后直接运行就行,这个没啥好说的,对当前用户安装就行。
然后就是clone tensorflow源码,这个也没啥好说的有手就行,耐心一下就是,毕竟带项目。clone完源码之后记得切分支。我就切了r2.2。
然后就开始踩坑辣。
坑1:./configure提示bazel版本出问题
直接魔改configure.py,把_TF_MAX_BAZEL_VERSION = '2.0.0'
手动改成_TF_MAX_BAZEL_VERSION = '2.2.0'
就行。还有根目录下有个.bazelversion的它原来写的也是2.0.0,这个我们也换成2.2.0。
然后运行./configure,直接抄官方指引的答案就行了。基本上除了CUDA那一栏是y,其他都是n(一路回车)。值得注意的是,貌似它会直接检测到CUDA和cuDNN目录,所以也不用我们手动输入CUDA和cuDNN版本了。然后还有个Cuda compute capability的东西。这个好像它也是直接检测并帮我们填好了默认值,直接回车就完事了。如果不放心的可以去wikipedia搜这个东西,下面画了一个表,罗列了所有显卡对应的数字。
然后开始构建pip软件包。由于我是用的r2.2,所以直接抄它的第一个命令bazel build //tensorflow/tools/pip_package:build_pip_package
。
坑2:执行bazel build开始会下一堆东西,有的时候直接ERROR,报错connect time out
解决方法就是最土味的↑+回车,再次执行一遍命令。下好了的包会缓存
坑3:执行bazel build报错@org_python_license不能load,原因为checksum对不上
我们打开tensorflow目录(tensorflow这个repo下面有个叫tensorflow的目录)下的workspace.bzl文件,搜索这个org_python_license
看一看,在465行发现url的居然是/2.7/xxxxx,出问题。这个库具体是干啥的不是很清楚,但是下的都是些license TXT。为了保险起见,改成3.6,再次执行bazel build,checksum还是对不上,把get XXX wanted YYY的XXX复制到sha256_urls
前面的那串字符串,再次执行bazel build,可以了。下完这些包之后又是漫长的等待,可以先暂时挂挂机。
封好这个pip软件包之后,再抄官方指引的下一条命令
./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
完事之后cd进/tmp/tensorflow_pkg/之后ls一下,发现打好的包,然后pip install
就行
坑4:pip install完之后迫不及待地想玩一下tensorflow结果报错
这个别人也会提到:一定要切换到tensorflow源码以外的目录,不然会报错!
之后就可以tf.test.is_gpu_available()
看到日志里面罗列出所有的显卡信息。
-03-31 15:24:50.608297: I tensorflow/compiler/xla/service/:176] StreamExecutor device (0): Tesla P100-SXM2-16GB, Compute Capability 6.0-03-31 15:24:50.608304: I tensorflow/compiler/xla/service/:176] StreamExecutor device (1): Tesla P100-SXM2-16GB, Compute Capability 6.0-03-31 15:24:50.608309: I tensorflow/compiler/xla/service/:176] StreamExecutor device (2): Tesla P100-SXM2-16GB, Compute Capability 6.0-03-31 15:24:50.608314: I tensorflow/compiler/xla/service/:176] StreamExecutor device (3): Tesla P100-SXM2-16GB, Compute Capability 6.0
并且在最后返回了True。于是我们来跑一个TF程序试一试,看看能不能正常使用GPU资源来计算。
注意一下,在tensorflow 2.x里面如果还想使用tensorflow 1.x的api的话,把import tensorflow as tf
改成import pat.v1 as tf
就行了,耶✌
坑5:session.run时会提到编译用cuDNN和运行的cuDNN版本不匹配的问题
完整报错如下:
E tensorflow/stream_executor/cuda/:343] Loaded runtime CuDNN library: 7.0.5 but source was compiled with: 7.6.5. CuDNN library major and minor version needs to match or have higher minor version in case of CuDNN 7.0 or later version. If using a binary install, upgrade your CuDNN library. If building from sources, make sure the library loaded at runtime is compatible with the version specified during compile configuration.
搜了一下,有人提到是软链接的问题。但是当我检查cuDNN软链接的时候发现并没有其他的cuDNN版本:ls /usr/local/cuda/lib64
发现只有libcudnn.so.7和libcudnn.so.7.6.5。后来发现是环境变量的问题:需要在~/.bashrc中设置
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
然后source ~/.bashrc
一下,再运行就OK辣~
大家笑一笑就好