在 macOS 上编译 Tensorflow 以开启 AVX2 和 FMA

在使用 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 环境:

这里我们使用 Brew 安装 Python3.

接下来是安装必要的依赖包:

如果你使用 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 的位置:

如果有多个结果,就选第一个即可。

接下来的参数配置几乎无需设定,全部默认即可,我们不需要 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)!

另,我在编译时看到了这个警告:

我还以为无法支持 AVX 要再来一遍呢……但似乎并不影响最终效果。

生成安装包

使用命令 ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg 来生成 .whl 安装包:

然后我们用 pip 安装它: pip install /tmp/tensorflow_pkg/tensorflow-2.1.0-cp37-cp37m-macosx_10_15_x86_64.whl

最后,可别忘了开启之前关闭了的安全警告: sudo spctl --master-enable

测试安装结果

现在已经不再提示 Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA了,尝试跑个模型,终于达到了可以忍耐的时长。

:)

参考文献

 

本文由 落格博客 原创撰写:落格博客 » 在 macOS 上编译 Tensorflow 以开启 AVX2 和 FMA

转载请保留出处和原文链接:https://www.logcg.com/archives/3283.html

About the Author

R0uter

如非声明,本人所著文章均为原创手打,转载请注明本页面链接和我的名字。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注