概要
为了兼容更多的老的硬件平台,谷歌预编译的TensorFlow二进制安装包(通过pip install tensorflow命令安装)中,是没有开启SSE4.x,SVX,FMA,MKL等的支持的,因此,对于目前主流的酷睿平台来说,这个安装包远无法发挥酷睿平台强大的计算能力,而在机器学习中,模型的训练往往会牵扯到非常耗时的巨大的计算量,并且我们在工作中可能需要随时调整我们的模型,以期获得更好的训练效果。在这个前提下,性能的优化显得尤为重要。本文将以Ubuntu 16.04为开发平台,展示如何在酷睿平台上对TensorFlow 1.4进行性能的优化,并给出一些真实的测试数据来展示优化的效果。
搭建TensorFlow 1.4开发环境
首先,我们用git命令clone TensorFlow 1.4的源码到本地
$ git clone https://github.com/tensorflow/tensorflow $ git checkout r1.4
第二个步骤是安装bazel(TensorFlow的编译工具),这里我们采用谷歌推荐的安装方法,好处是我们可以方便的用Ubuntu的apt命令随时更新bazel的版本
$ sudo apt-get install openjdk-8-jdk $ echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list $ curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add – $ sudo apt-get update && sudo apt-get install bazel
最后我们需要安装一些python工具,对于python 2.7版本(如果不确定当前python版本号,可以运行python –version来确认),我们需要:
$ sudo apt-get install python-numpy python-dev python-pip python-wheel
对于python 3.x版本,则是:
$ sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel
针对Intel酷睿平台的性能优化
针对酷睿平台的性能优化主要包含两个方面,其一是加入SSE4.x/AVX/AVX2/FMA等高级指令集的编译选项,其二是充分利用MKL加速库。为了达到这个目的,我们需要用以下的编译命令(而不是tensorflow官网上默认的命令):
$ bazel build --config=opt --config=mkl //tensorflow/tools/pip_package:build_pip_package
其中“--config=opt”的选项会自动启用可用的高级指令优化(例如SSE4.x/AVX/AVX2/FMA等,前提是你的设备支持这样的指令), “--config=mkl”选项会下载MKL库(目前MKL为2018版本,如果还没有下载到本地),并对TensorFlow源码用MKL优化编译。
编译的具体步骤可以参考如下命令行输出:
dec@dec-yoga:~/sources/tensorflow$ bazel clean # 清除上一次编译时的配置选项 WARNING: ignoring http_proxy in environment. .......... INFO: Starting clean (this may take a while). Consider using --async if the clean takes more than several minutes. dec@dec-yoga:~/sources/tensorflow$ ./configure # 进行编译配置 WARNING: ignoring http_proxy in environment. You have bazel 0.7.0 installed. Please specify the location of python. [Default is /usr/bin/python]: Found possible Python library paths: /usr/local/lib/python2.7/dist-packages /usr/lib/python2.7/dist-packages Please input the desired Python library path to use. Default is [/usr/local/lib/python2.7/dist-packages] Do you wish to build TensorFlow with jemalloc as malloc support? [Y/n]: jemalloc as malloc support will be enabled for TensorFlow. 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 Amazon S3 File System support? [Y/n]: n No Amazon S3 File System support will be enabled for TensorFlow. Do you wish to build TensorFlow with XLA JIT support? [y/N]: No XLA JIT support will be enabled for TensorFlow. Do you wish to build TensorFlow with GDR support? [y/N]: No GDR support will be enabled for TensorFlow. Do you wish to build TensorFlow with VERBS support? [y/N]: No VERBS support will be enabled for TensorFlow. Do you wish to build TensorFlow with OpenCL support? [y/N]: No OpenCL support will be enabled for TensorFlow. Do you wish to build TensorFlow with CUDA support? [y/N]: No CUDA support will be enabled for TensorFlow. Do you wish to build TensorFlow with MPI support? [y/N]: No MPI support will be enabled for TensorFlow. Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]: Add "--config=mkl" to your bazel command to build with MKL support. Please note that MKL on MacOS or windows is still not supported. If you would like to use a local MKL instead of downloading, please set the environment variable "TF_MKL_ROOT" every time before build. Configuration finished dec@dec-yoga:~/sources/tensorflow$ bazel build --config=opt --config=mkl //tensorflow/tools/pip_package:build_pip_package # 针对Intel酷睿平台进行优化编译
编译完成之后,就可以生成安装包并且安装
$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg $ sudo pip install /tmp/tensorflow_pkg/[生成的安装包文件名].whl
优化前后的性能对比
这里我们采用TensorFlow自带的MNIST示例代码来做对比。为了方便比较,我们给代码传入这样的参数:
--learning_rate=0.01 --max_steps=2000 --batch_size=5000 --hidden1=128 --hidden2=32
并且对代码稍加修改,在main函数最开始加上如下的MKL设置语句(实际上这些设置也可以通过命令行修改Ubuntu系统环境变量来做)。需要注意的是“OMP_NUM_THREAD”这一项设置,一般来说这一项设置通常设为当前硬件平台的核心数,有时候设置为核心数的若干倍时性能最佳。
os.environ["KMP_BLOCKTIME"] = '0' os.environ["KMP_SETTINGS"] = '1' os.environ["KMP_AFFINITY"]= 'granularity=fine,verbose,compact,1,0' os.environ["OMP_NUM_THREADS"]= '8'
然后再在run_training()调用语句前后加上时间戳,并且打印出run_training()所消耗的时间:
start = datetime.utcnow() print(start) run_training() end = datetime.utcnow() print(end) print("Time elapsed:", end-start)
最后我们安装/编译不同版本的TensorFlow并且运行我们修改过的MNIST示例代码,来得出我们的测试结果,在i5-7200U的笔记本上,我们得出的测试结果是:
TensorFlow版本 | 官方版本 (直接在Ubuntu shell中pip install tensorflow) | 高级指令优化版本 (bazel build--config=opt //tensorflow/tools/pip_package: build_pip_package) | 高级指令+MKL优化版本 (bazel build--config=opt--config=mkl //tensorflow/tools/pip_package: build_pip_package) |
---|---|---|---|
run_training()消耗时间(S) | 0:02:41.271874 | 0:01:09.590695 | 0:01:05.408182 (当 OMP_NUM_THREAD设为8时) |
在i7-6700的台式机上,我们得出的测试结果是:
TensorFlow版本 | 官方版本 (直接在Ubuntu shell中pip install tensorflow) | 高级指令优化版本 (bazel build--config=opt //tensorflow/tools/pip_package: build_pip_package) | 高级指令+MKL优化版本 (bazel build--config=opt--config=mkl //tensorflow/tools/pip_package: build_pip_package) |
---|---|---|---|
run_training()消耗时间(S) | 0:01:14.369093 | 0:00:38.657358 | 0:00:34.540627 (当OMP_NUM_THREAD设为8时) |
总结
在英特尔酷睿平台上,通过针对性的优化编译TensorFlow(SSE4.x,AVX, AVX2,FMA,MKL等),相比谷歌官方的默认编译版本,我们可以获得巨大的性能提升。在i5-7200U平台上,加入高级指令的优化,示例代码性能可以提高一倍以上,加入MKL优化之后还可以获得5%以上额外的性能提升。而在i7-6700平台上,MKL可以更多的发挥酷睿平台多核性能,带来高达10%以上的性能提升。
参考文献
Installing TensorFlow: https://www.tensorflow.org/install/
TensorFlow* Optimizations on Modern Intel® Architecture: https://software.intel.com/en-us/articles/tensorflow-optimizations-on-modern-intel-architecture
关于作者
裴凡江是英特尔软件与服务事业部的一名应用软件工程师,专注于在英特尔平台上与开发者的合作和业务拓展。力求将英特尔卓越的软硬件平台与开发者的软硬件产品完美结合,提供最优客户体验。