在使用 Tensorflow 时,一直有一个奇怪的警告: Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA ,虽然不影响使用,但看着很烦,你可以用这个命令关闭它: os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' 。
不过,你有注意到吗?“ could speed up CPU computations”……嗯?!
背景
总之,根据官方所述,Tensorflow 默认不支持这些高级功能是为了增强 Tensorflow 框架的兼容性,让它能够尽可能地在更多平台使用,从而避免不必要的编译操作。但这样的代价就是只能使用各个 CPU 平台都有的指令集,而高级命令就不能添加,毕竟不同的 CPU 平台它们有不同的高级指令集技术。
由于我使用 macOS,GPU 是 AMD,所以使用 Tensorflow 就别想用 GPU 进行加速了,用 CPU 又很慢,就只能跑测试数据(体积小),但我还是希望它能快一点。
所以 Tensorflow 提示我,针对我的 CPU 来说,有更高级的功能可以开启以加速训练——但怎么开启呢?答案肯定是用源码重新编译 Tensorflow。
AVX2 和 FMA
FMA 是现代 CPU 支持的一种高级指令集,中文叫“积和熔加运算”;
AVX 是现代 CPU 支持的“高级向量扩展指令集”,显然,这个 AVX2 的意思就是 AVX 进阶版的意思,它引入了上文的 FMA 运算,并将浮点性能提升 2 倍。
总之,如果 Tensorflow 能够直接使用这些高级功能,那训练速度一定能快上不少,接下来,我们就试试从头开始编译一个 Tensorflow。
准备工作
Python
显然,我们要用 Python 来使用 Tensorflow,所以你需要有 Python 环境:
1 2 3 |
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" export PATH="/usr/local/bin:/usr/local/sbin:$PATH" brew install python |
这里我们使用 Brew 安装 Python3.
接下来是安装必要的依赖包:
1 2 3 |
pip3 install -U --user pip six numpy wheel setuptools mock 'future>=0.17.1' pip3 install -U --user keras_applications --no-deps pip3 install -U --user keras_preprocessing --no-deps |
如果你使用 pip 有问题,不妨参考一下我的这一篇文章:正确使用 PIP 安装 Python 包 避免 TypeError: ‘module’ object is not callable
源码
要从源码编译 Tensorflow,就肯定要下载它的源码,找到一个你喜欢的目录位置,执行列命令获取 Tensorflow 项目源码: git clone https://github.com/tensorflow/tensorflow.git ,进入目录 cd tensorflow ,我们要切换到稳定版分枝,首先到https://github.com/tensorflow/tensorflow/releases查找最新的稳定版标签,就本文撰写之时,稳定版标签是 v2.1.0 ,这里我们切换到稳定版: git checkout v2.1.0 .
Bazel
Tensorflow 是要使用 Bazel 来编译的,整体编译过程轻松简单,但安装 Bazel 却需要一点点小技巧。
首先,检查你的 Tensorflow 源代码文件 tensorflow/configure.py ,在其中大概 53 行的位置,有一行 _TF_MAX_BAZEL_VERSION = '0.29.1' ,这就是我们要用的 Bazel 版本。
请注意:Bazel 最新版是 2.0,直接使用 brew 安装 bazel 是无法编译 Tensorflow 的。
首先要确保你的 macOS 安装了最新版的 Xcode,然后执行命令: sudo xcodebuild -license accept ,然后到https://github.com/bazelbuild/bazel/releases下载 Bazel 安装包,注意文件名应该是这样的: bazel-0.29.1-installer-darwin-x86_64.sh 。
点击上文文件名链接直接下载指定版本的 bazel 安装包,将来 Tensorflow 源代码编译要求可能会变,到时候读者请自行对应 bazel 版本号。
由于 macOS 10.15 加强了系统安全措施,所以如果你直接执行脚本, bazel 是无法完成安装的,会提示类似“bazel 是有未知开发者发布,可能有害”之类的警告,从而拒绝运行。
使用命令: sudo spctl --master-disable 暂时关闭这个警告,允许运行任意开发者的程序。
关闭警告后,就可以安装和使用 Bazel 了: sh bazel-0.29.1-installer-darwin-x86_64.sh --user ,安装完成后使用 bazel --version 查看,结果应该是: bazel 0.29.1
编译 Tensorflow
最终,我们可以进行编译了,回到 tensorflow 目录,执行 ./configure 进行配置,它会询问你 Python 及其库的位置,如果你不是用 brew 安装的,那么可以用如下命令找到你 Python 的位置:
1 2 3 |
$ where python3 /usr/local/bin/python3 /usr/bin/python3 |
如果有多个结果,就选第一个即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
$ ./configure WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown". You have bazel 0.29.1 installed. Please specify the location of python. [Default is /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python]: /usr/local/bin/python3 Found possible Python library paths: /usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages Please input the desired Python library path to use. Default is [/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages] Do you wish to build TensorFlow with XLA JIT support? [Y/n]: n No XLA JIT support will be enabled for TensorFlow. Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]: n No OpenCL SYCL support will be enabled for TensorFlow. Do you wish to build TensorFlow with ROCm support? [y/N]: n No ROCm 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. Do you wish to download a fresh release of clang? (Experimental) [y/N]: n Clang will not be downloaded. Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native -Wno-sign-compare]: Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: n Not configuring the WORKSPACE for Android builds. Do you wish to build TensorFlow with iOS support? [y/N]: y iOS support will be enabled for TensorFlow. Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details. --config=mkl # Build with MKL support. --config=monolithic # Config for mostly static monolithic build. --config=ngraph # Build with Intel nGraph support. --config=numa # Build with NUMA support. --config=dynamic_kernels # (Experimental) Build kernels into separate shared objects. --config=v2 # Build TensorFlow 2.x instead of 1.x. Preconfigured Bazel build configs to DISABLE default on features: --config=noaws # Disable AWS S3 filesystem support. --config=nogcp # Disable GCP support. --config=nohdfs # Disable HDFS support. --config=nonccl # Disable NVIDIA NCCL support. Configuration finished |
接下来的参数配置几乎无需设定,全部默认即可,我们不需要 GPU 支持(添加了也没用),不过最后有个 iOS 支持,这里我选择了 y,全部通过后,配置完成,就可以进行编译了。
使用命令 bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package 编译 Tensorflow 安装包,默认编译命令就是针对本地 CPU 进行编译,也就是启用所有当前 CPU 支持的指令集,这样编译出来的 Tensorflow 就是加速的啦!
编译过程很慢,在我 16G 内存 2.5 GHz Quad-Core Intel Core i7 CPU 下要 36301 秒能完成,整整 10 小时(给错了参数,10小时完全浪费了)要54219.95秒才能完成,整整15个小时(15 年中款 15寸rmbp)!
1 2 3 |
INFO: Elapsed time: 54219.950s, Critical Path: 1802.92s INFO: 22004 processes: 22004 local. INFO: Build completed successfully, 22776 total actions |
另,我在编译时看到了这个警告:
1 |
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/util/ConfigureVectorization.h:300:10: warning: "Disabling AVX support: clang compiler shipped with XCode 11.[012] generates broken assembly with -macosx-version-min=10.15 and AVX enabled. " [-W#warnings] |
我还以为无法支持 AVX 要再来一遍呢……但似乎并不影响最终效果。
生成安装包
使用命令 ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg 来生成 .whl 安装包:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg Sat Jan 18 03:59:17 AEST 2020 : === Preparing sources in dir: /var/folders/dn/p_qzcyss2m3gdnkkyl_bw_d00000gn/T/tmp.XXXXXXXXXX.MxFJDO4r ~/Downloads/tensorflow ~/Downloads/tensorflow ~/Downloads/tensorflow /var/folders/dn/p_qzcyss2m3gdnkkyl_bw_d00000gn/T/tmp.XXXXXXXXXX.MxFJDO4r/tensorflow/include ~/Downloads/tensorflow ~/Downloads/tensorflow Sat Jan 18 03:59:32 AEST 2020 : === Building wheel warning: no files found matching 'README' warning: no files found matching '*.pyd' under directory '*' warning: no files found matching '*.pd' under directory '*' warning: no files found matching '*.so.[0-9]' under directory '*' warning: no files found matching '*.dll' under directory '*' warning: no files found matching '*.lib' under directory '*' warning: no files found matching '*.csv' under directory '*' warning: no files found matching '*.h' under directory 'tensorflow_core/include/tensorflow' warning: no files found matching '*' under directory 'tensorflow_core/include/third_party' Sat Jan 18 04:00:00 AEST 2020 : === Output wheel file is in: /tmp/tensorflow_pkg |
然后我们用 pip 安装它: pip install /tmp/tensorflow_pkg/tensorflow-2.1.0-cp37-cp37m-macosx_10_15_x86_64.whl
最后,可别忘了开启之前关闭了的安全警告: sudo spctl --master-enable
测试安装结果
1 2 3 4 5 6 7 8 |
$ python3 Python 3.7.6 (default, Dec 30 2019, 19:38:26) [Clang 11.0.0 (clang-1100.0.33.16)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow as tf >>> t = tf.constant('logcg') 2020-01-18 20:04:43.088104: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fefdc983db0 initialized for platform Host (this does not guarantee that XLA will be used). Devices: 2020-01-18 20:04:43.088134: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version |
现在已经不再提示 Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA了,尝试跑个模型,终于达到了可以忍耐的时长。
:)
参考文献
- Building TensorFlow from source for SSE/AVX/FMA instructions: worth the effort?
- Build from source
- https://github.com/bazelbuild/bazel/issues/9304
本文由 落格博客 原创撰写:落格博客 » 在 macOS 上编译 Tensorflow 以开启 AVX2 和 FMA
转载请保留出处和原文链接:https://www.logcg.com/archives/3283.html