如何用SSE4.2和AVX指令编译Tensorflow ?

这是运行脚本检查Tensorflow是否工作时收到的消息:

I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcublas.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcufft.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcurand.so.8.0 locally
W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:910] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero

我注意到它提到了SSE4.2和AVX,

  1. 什么是SSE4.2和AVX?
  2. 这些SSE4.2和AVX如何提高Tensorflow任务的CPU计算。
  3. 如何使用这两个库使Tensorflow编译?
279862 次浏览

它们是SIMD 向量处理指令集

对于许多任务来说,使用矢量指令更快;机器学习就是这样一项任务。

引用Tensorflow安装文档:

为了与尽可能多的机器兼容,TensorFlow默认只在x86机器上使用SSE4.1 SIMD指令。大多数现代pc和mac都支持更高级的指令,所以如果你正在构建一个只在你自己的机器上运行的二进制文件,你可以在你的bazel构建命令中使用--copt=-march=native来启用这些指令。

我刚刚遇到了同样的问题,似乎Yaroslav Bulatov的建议不包括SSE4.2支持,添加--copt=-msse4.2就足够了。最后,我成功地用

bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.2 --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

没有得到任何警告或错误。

对于任何系统来说,最好的选择可能是:

bazel build -c opt --copt=-march=native --copt=-mfpmath=both --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

(更新:构建脚本可能会吃__ABC0,可能是因为它包含=)。

-mfpmath=both只适用于gcc,不适用于clang。-mfpmath=sse可能同样好,如果不是更好的话,并且是x86-64的默认值。32位将默认构建为-mfpmath=387,因此更改它将有助于32位。(但如果你想要高性能的数字运算,你应该构建64位二进制文件。)

我不确定TensorFlow默认的-O2-O3是什么。gcc -O3支持完全优化,包括自动向量化,但有时会使代码变慢。


它的作用:__ABC0用于bazel build直接将一个选项传递给gcc,用于编译C和c++文件(但不是链接,所以你需要一个不同的跨文件链接时间优化选项)

x86-64 gcc默认只使用SSE2或更老的SIMD指令,所以你可以在任何 x86-64系统上运行二进制文件。(见https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html)。这不是你想要的。您希望制作一个二进制文件,利用CPU可以运行的所有指令,因为您只在构建它的系统上运行这个二进制文件。

-march=native启用了CPU支持的所有选项,因此它使-mavx512f -mavx2 -mavx -mfma -msse4.2成为多余的。(而且,-mavx2已经启用了-mavx-msse4.2,所以Yaroslav的命令应该没问题)。此外,如果你使用的CPU不支持这些选项之一(如FMA),使用-mfma会使二进制文件出现非法指令错误。

TensorFlow的__ABC0默认启用-march=native,所以使用它应该避免需要手动指定编译器选项。

-march=native启用了-mtune=native,因此它为你的CPU优化用于诸如AVX指令的哪个序列最适合未对齐的负载。

这些都适用于gcc、clang或ICC。(对于ICC,你可以使用-xHOST而不是-march=native。)

我先回答你的第三个问题:

如果您想在conda-env中运行一个自行编译的版本,可以这样做。这些是我运行的获取tensorflow并将其安装到我的系统上的一般指令。注意:这个版本是AMD A10-7850版本(检查你的CPU支持什么指令…它可能不同)运行Ubuntu 16.04 LTS。我在conda-env中使用Python 3.5。链接到tensorflow源安装页面和上面提供的答案。

git clone https://github.com/tensorflow/tensorflow
# Install Bazel
# https://bazel.build/versions/master/docs/install.html
sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel
# Create your virtual env with conda.
source activate YOUR_ENV
pip install six numpy wheel, packaging, appdir
# Follow the configure instructions at:
# https://www.tensorflow.org/install/install_sources
# Build your build like below. Note: Check what instructions your CPU
# support. Also. If resources are limited consider adding the following
# tag --local_resources 2048,.5,1.0 . This will limit how much ram many
# local resources are used but will increase time to compile.
bazel build -c opt --copt=-mavx --copt=-msse4.1 --copt=-msse4.2  -k //tensorflow/tools/pip_package:build_pip_package
# Create the wheel like so:
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
# Inside your conda env:
pip install /tmp/tensorflow_pkg/NAME_OF_WHEEL.whl
# Then install the rest of your stack
pip install keras jupyter etc. etc.

关于第二个问题:

在我看来,一个带有优化的自编译版本是非常值得努力的。在我的设置中,以前需要560-600秒的计算现在只需要300秒!虽然确切的数字会有所不同,但我认为在您的特定设置上,您可以期望大约35-50%的速度提高。

最后你的第一个问题:

上面已经给出了很多答案。总结一下:AVXSSE4.1, SSE4.2, MFA是X86 cpu上不同种类的扩展指令集。许多都包含处理矩阵或向量运算的优化指令。

我将强调我自己的误解,希望能为您节省一些时间:并不是说SSE4.2是取代SSE4.1的指令的新版本。SSE4 = SSE4.1(一组47条指令)+ SSE4.2(一组7条指令)

在tensorflow编译的上下文中,如果你的计算机支持AVX2和AVX,以及SSE4.1和SSE4.2,你应该把这些优化标志都放进去。不要像我一样,认为SSE4.2更新,应该超越SSE4.1。这显然是错误的!我不得不重新编译,因为这花了我40分钟。

让我们从为什么一开始你会看到这些警告的解释开始。


很可能你没有从源代码安装TF,而是使用了类似pip install tensorflow的东西。这意味着您安装了预先构建的(由其他人)二进制文件,这些二进制文件没有针对您的体系结构进行优化。这些警告确切地告诉您:在您的体系结构上有一些可用的东西,但它将不会被使用,因为没有使用它编译二进制文件。下面是来自文档的部分。

TensorFlow在启动时检查它是否已经被编译 优化CPU可用。如果优化不是 包括,TensorFlow将发出警告,例如AVX, AVX2和FMA

好的是大多数情况下,你只是想学习/实验TF,这样一切都能正常工作,你不应该担心它


什么是SSE4.2和AVX?

维基百科对SSE4.2AVX有很好的解释。要擅长机器学习,并不需要这些知识。你可以把它们想象成一组额外的指令,让计算机对一条指令使用多个数据点来执行自然并行化的操作(例如添加两个数组)。

SSE和AVX都是SIMD(单指令,多数据)抽象思想的实现

Flynn分类学中的一类并行计算机。它描述了 具有多个执行相同任务的处理元件的计算机 同时对多个数据点进行操作。因此,这样的机器 利用数据级的并行性,而不是并发性:有 同时(并行)计算,但只有一个进程 (指令)在给定时刻

这足以回答你的下一个问题。


这些SSE4.2和AVX如何提高TF任务的CPU计算

它们允许更有效地计算各种向量(矩阵/张量)操作。你可以在这些幻灯片中阅读更多


如何使用这两个库使Tensorflow编译?

你需要有一个二进制文件来利用这些指令。最简单的方法是自己编译。正如Mike和Yaroslav所建议的,您可以使用以下bazel命令

bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.2 --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

当从源代码构建TensorFlow时,你将运行configure脚本。configure脚本问的其中一个问题如下:

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]

configure脚本将把你指定的标志附加到构建TensorFlow pip包的bazel命令上。一般来说,你可以用以下两种方式之一来回应这个提示:

  • 如果构建TensorFlow的CPU类型与运行TensorFlow的CPU类型相同,则应该接受默认值(-march=native)。这个选项将针对您机器的CPU类型优化生成的代码。
  • 如果你在一种CPU类型上构建TensorFlow,但将在不同的CPU类型上运行TensorFlow,那么考虑提供一个更具体的优化标志,如 gcc 李文档< / >。< / >

在如上所述配置TensorFlow之后,你应该能够通过在你正在运行的任何bazel命令中添加--config=opt标志来构建完全针对目标CPU优化的TensorFlow。

要隐藏这些警告,可以在实际代码之前执行此操作。

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import tensorflow as tf

我编译了一个小型的Mac Bash脚本(很容易移植到Linux)来检索所有CPU特性,并应用其中的一些来构建TF。我在TF大师和使用有点经常(一对夫妇在一个月)。

https://gist.github.com/venik/9ba962c8b301b0e21f99884cbd35082f

我最近从源代码安装了它,下面是从源代码安装它所需的所有步骤,上面提到的说明是可用的。

其他答案已经描述了为什么会显示这些消息。我的回答给出了如何isinstall的一步一步,这可能会帮助那些像我一样在实际安装上挣扎的人。

  1. 安装巴泽尔
从它们可用的释放中下载,例如0.5.2。 解压它,进入目录并配置它:bash ./compile.sh。 将可执行文件复制到/usr/local/bin: sudo cp ./output/bazel /usr/local/bin

  1. 安装Tensorflow

克隆tensorflow: git clone https://github.com/tensorflow/tensorflow.git 进入克隆目录进行配置:./configure

它会提示你几个问题,以下是我对每个问题的建议回答,当然,你可以根据自己的喜好选择回答:

Using python library path: /usr/local/lib/python2.7/dist-packages
Do you wish to build TensorFlow with MKL support? [y/N] y
MKL support will be enabled for TensorFlow
Do you wish to download MKL LIB from the web? [Y/n] Y
Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]:
Do you wish to use jemalloc as the malloc implementation? [Y/n] n
jemalloc disabled
Do you wish to build TensorFlow with Google Cloud Platform support? [y/N] N
No Google Cloud Platform support will be enabled for TensorFlow
Do you wish to build TensorFlow with Hadoop File System support? [y/N] N
No Hadoop File System support will be enabled for TensorFlow
Do you wish to build TensorFlow with the XLA just-in-time compiler (experimental)? [y/N] N
No XLA JIT support will be enabled for TensorFlow
Do you wish to build TensorFlow with VERBS support? [y/N] N
No VERBS support will be enabled for TensorFlow
Do you wish to build TensorFlow with OpenCL support? [y/N] N
No OpenCL support will be enabled for TensorFlow
Do you wish to build TensorFlow with CUDA support? [y/N] N
No CUDA support will be enabled for TensorFlow
  1. pip包。为了构建它,你必须描述你想要的指令(你知道,那些Tensorflow通知你的指令是缺失的)。

构建pip脚本:bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.1 --copt=-msse4.2 -k //tensorflow/tools/pip_package:build_pip_package

构建pip包:bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

安装你刚刚构建的Tensorflow pip包:sudo pip install /tmp/tensorflow_pkg/tensorflow-1.2.1-cp27-cp27mu-linux_x86_64.whl

现在你下次启动Tensorflow时,它不会再抱怨缺少指令了。

这是最简单的方法。只有一步。

它对速度有很大的影响。以我为例,每一步训练所花费的时间几乎减半。

< p >参考 tensorflow的自定义构建 < / p >

多亏了所有这些回复+一些试验和错误,我设法用clang将它安装在Mac上。所以分享一下我的解,也许对别人有用。

  1. 请参考Documentation - Installing TensorFlow from Sources . sh文档

  2. 当提示

    当bazel选项"——config=opt"被指定时,请指定在编译过程中使用的优化标志[默认值是-march=native] < / p >

然后复制粘贴这个字符串:

-mavx -mavx2 -mfma -msse4.2

(默认选项会导致错误,其他一些标志也是如此。我没有得到错误与上述标志。顺便说一句,我对所有其他问题都回答了n)

安装后,我验证了一个~2倍到2.5倍的加速训练深度模型相对于另一个安装基于默认车轮- 在macOS上安装TensorFlow

希望能有所帮助

使用SSE4.2和AVX编译TensorFlow,可以直接使用

bazel build -config=mkl ——配置= "选择" ——科普特人=“3 = broadwell” ——科普特人= " o3 " / / tensorflow /工具/ pip_package: build_pip_package < / p >

< p >来源: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/docker/Dockerfile.devel-cpu-mkl < / p >

2.0兼容方案:

在终端(Linux/MacOS)或命令提示符(Windows)中执行以下命令,使用巴泽尔安装Tensorflow 2.0:

git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow


#The repo defaults to the master development branch. You can also checkout a release branch to build:
git checkout r2.0


#Configure the Build => Use the Below line for Windows Machine
python ./configure.py


#Configure the Build => Use the Below line for Linux/MacOS Machine
./configure
#This script prompts you for the location of TensorFlow dependencies and asks for additional build configuration options.


#Build Tensorflow package


#CPU support
bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package


#GPU support
bazel build --config=opt --config=cuda --define=no_tensorflow_py_deps=true //tensorflow/tools/pip_package:build_pip_package