原创文章,版权所有。转载请注明出处!
此篇文章为长期更新文章,最新更新日期为2018年11月25日,更新记录请参阅文档末尾。
由于编译过程耗时很长,下一步将研究编译过程自动化,以期提升工作效率。
目前已制作好适用于 Ubuntu 的 Docker 镜像,可以直接下载使用。
vistart/ubuntu: Dockerfiles | Docker Hub
vistart/cuda: Dockerfiles | Docker Hub
vistart/build_tensorflow: Dockerfiles | Docker Hub
并已放出根据上述镜像构建的 TensorFlow Python 代码包:
TensorFlow 2.0.0 | TensorFlow 1.15.0
以及安装有上述代码包的镜像:
vistart/ml: Dockerfiles | Docker Hub
2019年11月19日
因为官方提供的 TensorFlow 不支持 AVX2/FMA 指令,故我们需要自己编译。如果既不需要 AVX2 指令,也不需要显卡支持,则并无自行编译的必要。
目前暂无法在 Ubuntu 18.04 下编译支持 GPU 的版本,因为 NVIDIA 官方并未提供对应操作系统的驱动和工具包。如果你不需要 GPU 支持,则此文章列出的方法可以直接用在 Ubuntu 18.04 中;若需要使用驱动和工具包,也可以使用 NVIDIA 提供的 Docker 镜像。
此篇文档是官方文档的补充。
编译环境(Environment)
- Python 2.7、Python 3.5(Ubuntu 16.04)、Python 3.6(Ubuntu 18.04,Ubuntu 16.04 下由 Anaconda3 提供)或 Python 3.7(Ubuntu 16.04/18.04 下由 Anaconda3 提供)(相关书籍)和 numpy(相关书籍)、mock、protobuf、absl-py
- bazel(需要 jdk 1.8)
- git (检出源代码)
- cuda 9.0 或 9.2、cuDNN 7.1、NCCL 2.2、TensorRT 4.0(仅限需要 GPU 支持)(截至2018年6月21日)
准备工作(Preparation)
- 安装 Python 2.7 和 Python 3.5 、 Python 3.6 或 Python 3.7,安装完成后再安装 numpy、mock、protobuf、absl-py ,安装这些模块的同时也会一并安装所有依赖模块;如果使用 Python 2.7,则还要安装 enum34 模块;如果是在 Anaconda3 下创建的环境,也可以使用 pip 来安装依赖包。
- 注意:从 Python 3.7 开始,async 和 await 正式作为保留关键字,而 Cython 0.27.1 及以前版本中存在 await,这会导致 TensorFlow 编译失败。如果要编译适用于 Python 3.7 的 TensorFlow,请参阅tensorflow 1.9 默认使用的是 Cython 0.27.1-dev,该版本的 ExprNodes.py 文件的第 2875 行将 await 作为 WithExitCallNode 类的成员,这明显违反了 Python 3.7 的语法规则。
- 安装 bazel;
- 安装 Git;
- 编译 tensorflow 1.12 需要安装 libc-ares-dev
如果要编译支持 GPU 的 TensorFlow ,则还需要修改 workspace.bzl 文件:
如果要编译支持 GPU 的 TensorFlow ,则还需要修改 workspace.bzl 文件:
(如果下载速度慢或不想注册,可以到天翼云盘下载)
- 安装 cuda 9.0 或 9.2;(含更新)
- 安装 cuDNN 7.1;
- cuDNN v5, v6 和 v7 可以共存,因此安装新版本不需要卸载旧版本。
- 下载 cuDNN 7.1
下载安装包可能需要先用 NVIDIA 账户登录并做调查。使用 NVIDIA 账户登录并做完调查后,再访问该链接即可跳转到下载页面。 - 下载前需要同意软件许可协议,同意后,下载以下三个文件:
cuDNN v7.1.4 Runtime Library for Ubuntu16.04 (Deb)
cuDNN v7.1.4 Developer Library for Ubuntu16.04 (Deb)
cuDNN v7.1.4 Code Samples and User Guide for Ubuntu16.04 (Deb) - 如果不想做调查,或官网下载不成功,可以到天翼云盘下载。
- 按照安装指导中的说明安装。
- 安装完成后验证安装。
- 安装 NCCL 2.2(可选)
- 下载 NCCL 2.2
下载安装包可能需要先用 NVIDIA 账户登录并做调查。使用 NVIDIA 账户登录并做完调查后,再访问该链接即可跳转到下载页面。 - 下载前需要同意软件许可协议,同意后,可以选择适当版本:
- 如果需要编译,则应当选 NCCL 2.2.13 O/S agnostic and CUDA 9.2
- 如果只需要使用启用 NCCL 2.x 的 TensorFlow ,则选择 NCCL 2.2.13 for Ubuntu 16.04 and CUDA 9.2
- 如果不想做调查,或者官网下载不成功,可以到天翼云盘下载。
- 下载后,按照安装说明安装即可。
- 注意:NCCL 1.x 和 NCCL 2.x 互不兼容,要使用哪个版本需要视具体代码而定。
- 下载 NCCL 2.2
- 安装 TensorRT 4.0(可选)
TensorRT 4.0 还未发布正式版。待正式版发布后将重新编译。目前最新版本是 TensorRT 4.0 RC- 下载 TensorRT 4.0
下载安装包可能需要先用 NVIDIA 账户登录并做调查。使用 NVIDIA 账户登录并做完调查后,再访问该链接即可跳转到下载页面。 - 下载前需要同意软件许可协议,同意后,下载以下文件:
TensorRT 4.0.1.6 for Ubuntu 1604 and CUDA 9.2 DEB local repo packages - 按照安装指导中 4.1 节的说明安装。
如果要编译适用于 Python 3.7 的 TensorFlow,则还需要:
克隆源代码(Cloning from Origin)
将目录切换到放置源代码的目录,并运行以下命令:
git clone --recurse-submodules https://github.com/tensorflow/tensorflow
该命令会克隆 TensorFlow 和所有子模块。
克隆完毕后切换到 tensorflow 文件夹,然后切换到 r1.9 分支:
cd tensorflow git checkout r1.9
切换完成后就可以开始配置编译参数了。
配置(Configuration)
编译前需要配置编译环境。
在 tensorflow 文件夹下运行:
./configure
如果遇到诸如“创建文件夹不成功:权限不足”等提示,则可以把相关文件夹变为当前用户所有,也可以使用超级用户权限。
运行后,按照提示,依次配置如下(以 Python 2.7 为例):
- Please specify the location of python. [Default is /usr/bin/python]:
- python 的具体位置可以使用 which python 命令查看;
- 如果是在 Ubuntu 中直接安装 Python 2.x,则就是默认目录,可以直接回车;
- 如果是在 Ubuntu 中直接安装 Python 3.x,则目录是 /usr/bin/python3;
- 如果是通过 Anaconda 安装 Python,则应当在 Anaconda 环境中使用 which python 命令查看 python 具体位置。
- Please input the desired Python library path to use. Default is [/usr/local/lib/python2.7/dist-packages]
- 如果是在 Ubuntu 中直接安装 Python 2.x 或 Python 3.x,则就是默认目录,可以直接回车;其中 Python 3.x 的路径名是具体安装的 Python 版本名;
- 如果是通过 Anaconda 安装 Python,则应当指定该环境对应的库目录,不能是公共目录。
- Do you wish to build TensorFlow with jemalloc as malloc support? [Y/n]:
- Do you wish to build TensorFlow with Google Cloud Platform support? [Y/n]:
- Do you wish to build TensorFlow with Hadoop File System support? [Y/n]:
- Do you wish to build TensorFlow with Amazon S3 File System support? [Y/n]:
- Do you wish to build TensorFlow with Apache Kafka Platform support? [Y/n]:
- Do you wish to build TensorFlow with XLA JIT support? [y/N]:
- Do you wish to build TensorFlow with GDR support? [y/N]:
- Do you wish to build TensorFlow with VERBS support? [y/N]:
- Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]:
- 以上九个参数全部按照默认值。
- Do you wish to build TensorFlow with CUDA support? [y/N]: y
- 如果要编译支持显卡的 TensorFlow ,则此步骤输入 y,否则输入 n。若输入 n,则跳过第 13 ~ 22 步。
- 注意:在此之前必须先安装好 cuda。
- Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 9.0]:
- 如果安装的是 cuda 9.0,则可以按照默认值;如果安装的是 cuda 9.2,则输入“9.2”并回车。
- Please specify the location where CUDA 9.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
- 如果当前操作系统只安装了一个 cuda,且没有修改过安装目录,则可以按照默认值;否则,需要指定具体位置。
- 如果当前操作系统安装了多个 cuda,则可以到 /usr/local 目录下确认具体要使用哪一个。
- Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7.0]: 7.1
- 如果安装的是 cuDNN 7.0,则可以按照默认值;如果安装的是 cuDNN 7.1,则输入“7.1”并回车。
- 如果选择使用 cuda,则此步骤不能跳过。
- Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
- 如果当前操作系统只安装了一个 cuda,且没有修改过安装目录,并且安装 cuDNN 时也未修改目录,则可以按照默认值;否则,需要指定具体位置。
- 如果选择使用 cuda,则此步骤不能跳过。
- 若指定目录未找到 cuDNN 库,则会跳回第 15 步重新选择版本。
- Do you wish to build TensorFlow with TensorRT support? [y/N]:y
- 此步骤询问是否使用 TensorRT。如果需要使用,则输入“y”,否则输入“n”。
- 推荐使用 TensorRT,如果不需要加速推理,可以不使用。
- Please specify the location where TensorRT is installed. [Default is /usr/lib/x86_64-linux-gnu]:
- 如果按照安装指导中 4.1 节的说明安装 TensorRT,则可以按照默认值;否则需要指定具体位置。
- Please specify the NCCL version you want to use. [Leave empty to default to NCCL 1.3]:
- 如果没有单独安装 NCCL,则可以按照默认值;若选择默认值,则跳过第 20 步。
- 如果单独安装 NCCL,则需要指定版本,如“2.2”。
- 注意:NCCL 1.x 和 NCCL 2.x 互不兼容,要使用哪个版本需要视具体代码而定。
- Please specify the location where NCCL 2 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
- 如果要选择使用 NCCL 2.x,则需要指定 NCCL 库的位置。
- 请按照下载页面的提示选择 NCCL 2.2.13 O/S agnostic and CUDA 9.2 ,并按照此说明安装,安装后的目录是 /usr/local/nccl_2.2.13-1+cuda9.2_x86_64,然后再将此目录作为 NCCL 2 库的指定位置,不能使用 Debian 安装包。
- 编译成功、安装代码包并运行具体代码时,如果提示“libnccl.so.2 未找到”,则应当返回下载页面并选择 NCCL 2.2.13 for Ubuntu 16.04 and CUDA 9.2,然后按照此说明安装。
- Please specify a list of comma-separated Cuda compute capabilities you want to build with. You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus. Please note that each additional compute capability significantly increases your build time and binary size. [Default is: 6.1,6.1]
- 请根据此页面调整自己的计算能力值。这里就按照默认值。
- 如果需要提高或降低计算能力值,请依次输入每个设备的值,并以逗号隔开。
- Do you want to use clang as CUDA compiler? [y/N]:
- Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:
- Do you wish to build TensorFlow with MPI support? [y/N]:
- Please specify optimization flags to use during compilation when bazel option “–config=opt” is specified [Default is -march=native]:
- Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]:
- 以上五个参数全部按照默认值。
编译(Building)
bazel build -c opt --copt=-msse3 --copt=-msse4.1 --copt=-msse4.2 --copt=-mavx --copt=-mavx2 --copt=-mfma --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=0" //tensorflow/tools/pip_package:build_pip_package
编译过程大约耗时接近一个小时。
参数解释:(输入命令 bazel help build 后获得)
- –compilation_mode 或 -c
编译模式,我们这里选用 opt (优化)。 - –copt=…
该选项给指定 gcc 编译器传递参数。
我们需要启用英特尔处理器的 SSE/AVX/FMA 等指令集。 - –cxxopt=…
该选项给指定 gcc 编译 c++ 文件时传递的参数。
-D_GLIBCXX_USE_CXX11_ABI=0 表示使用老版本 ABI。有关双 ABI 的介绍可以查阅官方文档。
当 TensorFlow 和第三方模块在编译时使用的 CPU、操作系统、编译器不同时,有可能导致无法加载。具体提示可能是某个符号未定义(Undefined Symbol: …)。
如果你能保证所有用到的第三方模块也是使用 GCC 5.1 或更高版本编译,且没有指定此参数,则在编译时可以不加此参数。此参数在 TensorFlow 官方文档中也有说明。
注意:numpy 1.3.x 不支持老版本 ABI,请使用 1.4.x 版本。 - //tensorflow/tools/pip_package:build_pip_package
编译后生成代码包脚本的位置和名称。
由于编译过程会耗费大约 6 GB 左右的空间作为缓存,如果默认缓存位置 “~/.cache”所在硬盘空间不够,可以指定新的缓存位置。
如果新的缓存位置在本地磁盘,可以附加–disk_cache 选项;如果新的缓存位置在远程,可以附加–remote_http_cache 选项。不过实际过程没这么简单,详细用法请参阅官方文档。
生成 pip 包(Generating PIP package)
bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/tensorflow-packages
第一个参数是代码包存放的位置。
注意:bazel-bin文件夹仅仅是软链接,其具体位置在当前用户的缓存文件夹中。因此在编译完成后和生成代码包前,不能删除缓存,否则编译结果就消失了。
安装编译好的 TensorFlow(Install Built TensorFlow)
若在 Python 2.7 下编译,则运行:
sudo -H pip install ~/tensorflow-packages/tensorflow-1.9.0-cp27-cp27mu-linux_x86_64.whl
若在 Python 3.5 下编译,则运行:
sudo -H pip3 install ~/tensorflow-packages/tensorflow-1.9.0-cp35-cp35m-linux_x86_64.whl
注意:若在 Anaconda3 创建的环境下,则直接使用 pip 命令即可,无须超级用户权限。
验证安装(Verifying Installation)
以 Python 2.7 为例,使用 TensorFlow 的验证代码:
import tensorflow as tf hello = tf.constant('Hello, TensorFlow!') sess = tf.Session() print(sess.run(hello))
推荐在 Python 命令行下执行。
执行第一句后,如果 TensorFlow 安装正确,则不会有任何提示。执行第二句后亦如此。
执行第三句后,如果当前 CPU 支持 AVX2 指令,且 TensorFlow 也成功启用 AVX2 指令,则不会提示未启用 AVX2。同时,执行此句后还会出现有关显卡的信息。
执行第四句后输出“Hello, TensorFlow!”。
解决问题(Troubleshooting)
1. 如果在“验证安装”环节执行第一句后出现以下错误:
h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`. from ._conv import register_converters as _register_converters
则问题出在 h5py 2.7.x 版与 numpy 1.4.x 不兼容。h5py 2.8 已改正此问题。你可以选择将 numpy 降级到 1.3.x,但我不推荐这么做。推荐的做法是自行编译 h5py 并安装。方法如下:
选定一个目录存放 h5py,然后克隆仓库:
git clone https://github.com/h5py/h5py
克隆结束后切换到 2.8.0 标签:
cd h5py git checkout 2.8.0
切换后开始安装:(安装前请先卸载旧版)
pip install -v .
此命令可能需要超级用户权限。如果是 Python3,则使用 pip3。
2. 如果在执行 import tensorflow as tf 后提示:
RuntimeError: module compiled against API version 0xc but this version of numpy is 0xb
请使用 numpy 1.4.x 版本即可。
3.如果在编译结束后和执行 import tensorflow as tf 后提示:
/usr/local/lib/python2.7/dist-packages/scipy/sparse/lil.py:19: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from . import _csparsetools
/usr/local/lib/python2.7/dist-packages/scipy/sparse/csgraph/__init__.py:165: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._shortest_path import shortest_path, floyd_warshall, dijkstra,\
/usr/local/lib/python2.7/dist-packages/scipy/sparse/csgraph/_validation.py:5: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._tools import csgraph_to_dense, csgraph_from_dense,\
/usr/local/lib/python2.7/dist-packages/scipy/sparse/csgraph/__init__.py:167: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._traversal import breadth_first_order, depth_first_order, \
/usr/local/lib/python2.7/dist-packages/scipy/sparse/csgraph/__init__.py:169: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._min_spanning_tree import minimum_spanning_tree
/usr/local/lib/python2.7/dist-packages/scipy/sparse/csgraph/__init__.py:170: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._reordering import reverse_cuthill_mckee, maximum_bipartite_matching, \
/usr/local/lib/python2.7/dist-packages/scipy/linalg/basic.py:17: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._solve_toeplitz import levinson
/usr/local/lib/python2.7/dist-packages/scipy/linalg/__init__.py:207: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._decomp_update import *
/usr/local/lib/python2.7/dist-packages/scipy/special/__init__.py:640: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._ufuncs import *
/usr/local/lib/python2.7/dist-packages/scipy/special/_ellip_harm.py:7: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from ._ellip_harm_2 import _ellipsoid, _ellipsoid_norm
/usr/local/lib/python2.7/dist-packages/scipy/interpolate/_bsplines.py:10: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from . import _bspl
/usr/local/lib/python2.7/dist-packages/scipy/spatial/__init__.py:95: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from .ckdtree import *
/usr/local/lib/python2.7/dist-packages/scipy/spatial/__init__.py:96: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from .qhull import *
/usr/local/lib/python2.7/dist-packages/scipy/spatial/_spherical_voronoi.py:18: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from . import _voronoi
/usr/local/lib/python2.7/dist-packages/scipy/spatial/distance.py:122: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from . import _hausdorff
/usr/local/lib/python2.7/dist-packages/scipy/ndimage/measurements.py:36: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
from . import _ni_label
此原因出在,numpy 1.15 开始,对 dtype 的尺寸做了更改。如果要保持兼容性,请使用 numpy 1.14.5。
4.如果在编译过程中提示:
No module named keras_applications
则需要安装 keras:
pip install keras
使用 pip 安装模块可能需要超级用户权限。
更新记录
2018年6月22日
TensorRT 4 正式版发布后,将编译引用的 TensorRT 版本改为最新版。
2018年7月5日
解决 numpy 和 tensorflow 的 ABI 版本不匹配的问题。
更详细的编译说明参见官方文档。
2018年7月11日
TensorFlow 1.9.0 正式版已发布。
2018年7月12日
针对 Python 3.7 作特别说明。
2018年8月11日
针对 numpy 1.15 和 keras_applications 作特别说明。
2018年11月25日
编译 tensorflow 1.12.0 需要使用 bazel 0.18.1。
关于 “在 Ubuntu 中编译 TensorFlow” 的 3 个意见
您必须登录才能发表评论。