在 Ubuntu 中编译 TensorFlow

原创文章,版权所有。转载请注明出处!

此篇文章为长期更新文章,最新更新日期为2018年11月25日,更新记录请参阅文档末尾。

由于编译过程耗时很长,下一步将研究编译过程自动化,以期提升工作效率。

因为官方提供的 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)

  1. 安装 Python 2.7 和 Python 3.5 、 Python 3.6 或 Python 3.7,安装完成后再安装 numpy、mock、protobuf、absl-py ,安装这些模块的同时也会一并安装所有依赖模块;如果使用 Python 2.7,则还要安装 enum34 模块;如果是在 Anaconda3 下创建的环境,也可以使用 pip 来安装依赖包。
  2. 注意:从 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 的语法规则。
  3. 安装 bazel
  4. 安装 Git
  5. 编译 tensorflow 1.12 需要安装 libc-ares-dev

如果要编译支持 GPU 的 TensorFlow ,则还需要修改 workspace.bzl 文件:

如果要编译支持 GPU 的 TensorFlow ,则还需要修改 workspace.bzl 文件:

(如果下载速度慢或不想注册,可以到天翼云盘下载)

  1. 安装 cuda 9.0 或 9.2;(含更新)
    1. 注意:NCCL 2.2 和 TensorRT 3.0 或 4.0 RC 仅支持 cuda 9.0。如果您需要 NCCL 2.2 和 Tensor 3.0 或 4.0 RC,则目前(2018年5月28日)只能使用 cuda 9.0。如果只需要默认的 NCCL 1.3,不需要 TensorRT,则可以使用 cuda 9.2。
    2. NCCL 2.2.13 和 TensorRT 4.0.1.6 支持 cuda 9.2(2018年6月21日),本文编译将仅考虑 cuda 9.2。
    3. 下载 cuda 9.0天翼云盘)或 cuda 9.2天翼云盘),包括更新包,并按照官方说明安装。
  2. 安装 cuDNN 7.1;
    1. cuDNN v5, v6 和 v7 可以共存,因此安装新版本不需要卸载旧版本。
    2. 下载 cuDNN 7.1
      下载安装包可能需要先用 NVIDIA 账户登录并做调查。使用 NVIDIA 账户登录并做完调查后,再访问该链接即可跳转到下载页面。
    3. 下载前需要同意软件许可协议,同意后,下载以下三个文件:
      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)
    4. 如果不想做调查,或官网下载不成功,可以到天翼云盘下载。
    5. 按照安装指导中的说明安装。
    6. 安装完成后验证安装
  3. 安装 NCCL 2.2(可选)
    1. 下载 NCCL 2.2
      下载安装包可能需要先用 NVIDIA 账户登录并做调查。使用 NVIDIA 账户登录并做完调查后,再访问该链接即可跳转到下载页面。
    2. 下载前需要同意软件许可协议,同意后,可以选择适当版本:
      1. 如果需要编译,则应当选 NCCL 2.2.13 O/S agnostic and CUDA 9.2
      2. 如果只需要使用启用 NCCL 2.x 的 TensorFlow ,则选择 NCCL 2.2.13 for Ubuntu 16.04 and CUDA 9.2
    3. 如果不想做调查,或者官网下载不成功,可以到天翼云盘下载。
    4. 下载后,按照安装说明安装即可。
    5. 注意:NCCL 1.x 和 NCCL 2.x 互不兼容,要使用哪个版本需要视具体代码而定。
  4. 安装 TensorRT 4.0(可选)
    1. TensorRT 4.0 还未发布正式版。待正式版发布后将重新编译。目前最新版本是 TensorRT 4.0 RC
    2. 下载 TensorRT 4.0
      下载安装包可能需要先用 NVIDIA 账户登录并做调查。使用 NVIDIA 账户登录并做完调查后,再访问该链接即可跳转到下载页面。
    3. 下载前需要同意软件许可协议,同意后,下载以下文件:
      TensorRT 4.0.1.6 for Ubuntu 1604 and CUDA 9.2 DEB local repo packages
    4. 按照安装指导中 4.1 节的说明安装。

如果要编译适用于 Python 3.7 的 TensorFlow,则还需要:

克隆源代码(Cloning from Origin)

将目录切换到放置源代码的目录,并运行以下命令:

该命令会克隆 TensorFlow 和所有子模块。

克隆完毕后切换到 tensorflow 文件夹,然后切换到 r1.9 分支:

切换完成后就可以开始配置编译参数了。

配置(Configuration)

编译前需要配置编译环境。

在 tensorflow 文件夹下运行:

如果遇到诸如“创建文件夹不成功:权限不足”等提示,则可以把相关文件夹变为当前用户所有,也可以使用超级用户权限。

运行后,按照提示,依次配置如下(以 Python 2.7 为例):

  1. Please specify the location of python. [Default is /usr/bin/python]:
    1. python 的具体位置可以使用 which python 命令查看;
    2. 如果是在 Ubuntu 中直接安装 Python 2.x,则就是默认目录,可以直接回车;
    3. 如果是在 Ubuntu 中直接安装 Python 3.x,则目录是 /usr/bin/python3;
    4. 如果是通过 Anaconda 安装 Python,则应当在 Anaconda 环境中使用 which python 命令查看 python 具体位置。
  2. Please input the desired Python library path to use. Default is [/usr/local/lib/python2.7/dist-packages]
    1. 如果是在 Ubuntu 中直接安装 Python 2.x 或 Python 3.x,则就是默认目录,可以直接回车;其中 Python 3.x 的路径名是具体安装的 Python 版本名;
    2. 如果是通过 Anaconda 安装 Python,则应当指定该环境对应的库目录,不能是公共目录。
  3. Do you wish to build TensorFlow with jemalloc as malloc support? [Y/n]:
  4. Do you wish to build TensorFlow with Google Cloud Platform support? [Y/n]:
  5. Do you wish to build TensorFlow with Hadoop File System support? [Y/n]:
  6. Do you wish to build TensorFlow with Amazon S3 File System support? [Y/n]:
  7. Do you wish to build TensorFlow with Apache Kafka Platform support? [Y/n]:
  8. Do you wish to build TensorFlow with XLA JIT support? [y/N]:
  9. Do you wish to build TensorFlow with GDR support? [y/N]:
  10. Do you wish to build TensorFlow with VERBS support? [y/N]:
  11. Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]:
    1. 以上九个参数全部按照默认值。
  12. Do you wish to build TensorFlow with CUDA support? [y/N]: y
    1. 如果要编译支持显卡的 TensorFlow ,则此步骤输入 y,否则输入 n。若输入 n,则跳过第 13 ~ 22 步。
    2. 注意:在此之前必须先安装好 cuda。
  13. Please specify the CUDA SDK version you want to use. [Leave empty to default to CUDA 9.0]:
    1. 如果安装的是 cuda 9.0,则可以按照默认值;如果安装的是 cuda 9.2,则输入“9.2”并回车。
  14. Please specify the location where CUDA 9.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    1. 如果当前操作系统只安装了一个 cuda,且没有修改过安装目录,则可以按照默认值;否则,需要指定具体位置。
    2. 如果当前操作系统安装了多个 cuda,则可以到 /usr/local 目录下确认具体要使用哪一个。
  15. Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7.0]: 7.1
    1. 如果安装的是 cuDNN 7.0,则可以按照默认值;如果安装的是 cuDNN 7.1,则输入“7.1”并回车。
    2. 如果选择使用 cuda,则此步骤不能跳过。
  16. Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    1. 如果当前操作系统只安装了一个 cuda,且没有修改过安装目录,并且安装 cuDNN 时也未修改目录,则可以按照默认值;否则,需要指定具体位置。
    2. 如果选择使用 cuda,则此步骤不能跳过。
    3. 若指定目录未找到 cuDNN 库,则会跳回第 15 步重新选择版本。
  17. Do you wish to build TensorFlow with TensorRT support? [y/N]:y
    1. 此步骤询问是否使用 TensorRT。如果需要使用,则输入“y”,否则输入“n”。
    2. 推荐使用 TensorRT,如果不需要加速推理,可以不使用。
  18. Please specify the location where TensorRT is installed. [Default is /usr/lib/x86_64-linux-gnu]:
    1. 如果按照安装指导中 4.1 节的说明安装 TensorRT,则可以按照默认值;否则需要指定具体位置。
  19. Please specify the NCCL version you want to use. [Leave empty to default to NCCL 1.3]:
    1. 如果没有单独安装 NCCL,则可以按照默认值;若选择默认值,则跳过第 20 步。
    2. 如果单独安装 NCCL,则需要指定版本,如“2.2”。
    3. 注意:NCCL 1.x 和 NCCL 2.x 互不兼容,要使用哪个版本需要视具体代码而定。
  20. Please specify the location where NCCL 2 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    1. 如果要选择使用 NCCL 2.x,则需要指定 NCCL 库的位置。
    2. 请按照下载页面的提示选择 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 安装包。
    3. 编译成功、安装代码包并运行具体代码时,如果提示“libnccl.so.2 未找到”,则应当返回下载页面并选择 NCCL 2.2.13 for Ubuntu 16.04 and CUDA 9.2,然后按照此说明安装。
  21. 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]
    1. 请根据此页面调整自己的计算能力值。这里就按照默认值。
    2. 如果需要提高或降低计算能力值,请依次输入每个设备的值,并以逗号隔开。
  22. Do you want to use clang as CUDA compiler? [y/N]:
  23. Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:
  24. Do you wish to build TensorFlow with MPI support? [y/N]:
  25. Please specify optimization flags to use during compilation when bazel option “–config=opt” is specified [Default is -march=native]:
  26. Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]:
    1. 以上五个参数全部按照默认值。

编译(Building)

编译过程大约耗时接近一个小时。

参数解释:(输入命令 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(Install Built TensorFlow)

若在 Python 2.7 下编译,则运行:

若在 Python 3.5 下编译,则运行:

注意:若在 Anaconda3 创建的环境下,则直接使用 pip 命令即可,无须超级用户权限。

验证安装(Verifying Installation)

以 Python 2.7 为例,使用 TensorFlow 的验证代码:

推荐在 Python 命令行下执行。

执行第一句后,如果 TensorFlow 安装正确,则不会有任何提示。执行第二句后亦如此。

执行第三句后,如果当前 CPU 支持 AVX2 指令,且 TensorFlow 也成功启用 AVX2 指令,则不会提示未启用 AVX2。同时,执行此句后还会出现有关显卡的信息。

执行第四句后输出“Hello, TensorFlow!”。

解决问题(Troubleshooting)

1. 如果在“验证安装”环节执行第一句后出现以下错误:

则问题出在 h5py 2.7.x 版与 numpy 1.4.x 不兼容。h5py 2.8 已改正此问题。你可以选择将 numpy 降级到 1.3.x,但我不推荐这么做。推荐的做法是自行编译 h5py 并安装。方法如下:

选定一个目录存放 h5py,然后克隆仓库:

克隆结束后切换到 2.8.0 标签:

切换后开始安装:(安装前请先卸载旧版)

此命令可能需要超级用户权限。如果是 Python3,则使用 pip3。

2. 如果在执行 import tensorflow as tf 后提示:

请使用 numpy 1.4.x 版本即可。

3.如果在编译结束后和执行 import tensorflow as tf 后提示:

此原因出在,numpy 1.15 开始,对 dtype 的尺寸做了更改。如果要保持兼容性,请使用 numpy 1.14.5。

4.如果在编译过程中提示:

则需要安装 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 个意见

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据