TensorFlow如何充分使用所有CPU核數,提高TensorFlow的CPU使用率,以及Intel的MKL加速

TensorFlow如何充分使用所有CPU核數,提高TensorFlow的CPU使用率,以及Intel的MKL加速
許多朋友使用服務器時,碰巧服務器沒有安裝GPU或者GPU都被占滿了。可是,服務器有很多CPU都是空閑的,其實,把這些CPU都充分利用起來,也可以有不錯的訓練效果。
但是,如果你是用CPU版的TF,有時TensorFlow並不能把所有CPU核數使用到,這時有個小技巧David 9要告訴大家:
- with tf.Session(config=tf.ConfigProto(
- device_count={"CPU":12},
- inter_op_parallelism_threads=1,
- intra_op_parallelism_threads=1,
- gpu_options=gpu_options,
- )) as sess:
在Session定義時,ConfigProto中可以嘗試指定下面三個參數:
- device_count, 告訴tf Session使用CPU數量上限,如果你的CPU數量較多,可以適當加大這個值
- inter_op_parallelism_threads和intra_op_parallelism_threads告訴session操作的線程並行程度,如果值越小,線程的復用就越少,越可能使用較多的CPU核數。如果值為0,TF會自動選擇一個合適的值。
David 9親自試驗,訓練似乎有1倍速度的提高。
另外,有的朋友的服務器上正好都是Intel的CPU,很可能需要把Intel的MKL包編譯進TensorFlow中,以增加訓練效率。這里David 9把MKL編譯進TF的關鍵點也指出一下。
- Run “./configure” from the TensorFlow source directory, and it will download latest Intel MKL for machine learning automatically in tensorflow/third_party/mkl/mklml if you select the options to use Intel MKL
- Execute the following commands to create a pip package that can be used to install the optimized TensorFlow build.
- PATH can be changed to point to a specific version of GCC compiler:
export PATH=/PATH/gcc/bin:$PATH - LD_LIBRARY_PATH can also be changed to point to new GLIBC :
- export LD_LIBRARY_PATH=/PATH/gcc/lib64:$LD_LIBRARY_PATH.
- Build for best performance on Intel Xeon and Intel Xeon Phi processors:
- bazel build --config=mkl --copt="-DEIGEN_USE_VML" -c opt //tensorflow/tools/pip_package:
- build_pip_package
- PATH can be changed to point to a specific version of GCC compiler:
3. Install the optimized TensorFlow wheel
- bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/path_to_save_wheel
- pip install --upgrade --user ~/path_to_save_wheel /wheel_name.whl
與官網編譯TF的大致流程類似,就是先./configure,再用bazel編譯TensorFlow。
最后用編譯好的bazel工具生成whl的包,用來安裝pip TensorFlow。
唯一的不同要注意用–config=mkl的選項編譯TensorFlow:
bazel build –config=mkl –copt=”-DEIGEN_USE_VML” -c opt //tensorflow/tools/pip_package: build_pip_package
這樣,用pip安裝完成TF后,mkl就集成在TF中了。
參考文獻:
- https://software.intel.com/es-es/articles/tensorflow-optimizations-on-modern-intel-architecture
- https://richardstechnotes.wordpress.com/2016/08/09/encouraging-tensorflow-to-use-more-cores/
- https://www.tensorflow.org/install/install_sources
現代英特爾® 架構上的 TensorFlow* 優化
By Elmoustapha O. (Intel), IDZSupport K., published on 2017 年 8 月 9 日
英特爾:Elmoustapha Ould-Ahmed-Vall,Mahmoud Abuzaina,Md Faijul Amin,Jayaram Bobba,Roman S Dubtsov,Evarist M Fomenko,Mukesh Gangadhar,Niranjan Hasabnis,Jing Huang,Deepthi Karkada,Young Jin Kim,Srihari Makineni,Dmitri Mishura,Karthik Raman,AG Ramesh,Vivek V Rane,Michael Riera,Dmitry Sergeev,Vamsi Sripathi,Bhavani Subramanian,Lakshay Tokas,Antonio C Valles
谷歌:Andy Davis,Toby Boyd,Megan Kacholia,Rasmus Larsen,Rajat Monga,Thiru Palanisamy,Vijay Vasudevan,Yao Zhang
作為一款領先的深度學習和機器學習框架,TensorFlow* 對英特爾和谷歌發揮英特爾硬件產品的最佳性能至關重要。本文 向人工智能 (AI) 社區介紹了在基於英特爾® 至強和英特爾® 至強融核™ 處理器的平台上實施的 TensorFlow* 優化。在去年舉辦的首屆英特爾人工智能日上,英特爾公司的柏安娜和谷歌的 Diane Green 共同宣布了雙方的合作,這些優化是英特爾和谷歌工程師密切合作取得的成果。
我們介紹了在優化實踐中遇到的各種性能挑戰以及采用的解決方法,還報告了對通用神經網絡模型示例的性能改進。這些優化帶來了多個數量級的性能提升。例如,根據我們的測量,英特爾® 至強融核™ 處理器 7250 (KNL) 上的訓練性能提升了高達 70 倍,推斷性能提升了高達 85 倍。基於英特爾® 至強® 處理器 E5 v4 (BDW) 和英特爾至強融核處理器 7250 的平台為下一代英特爾產品奠定了基礎。用戶尤其希望今年晚些時候推出的英特爾至強(代號為 Skylake)和英特爾至強融合(代號為 Knights Mill)處理器將提供顯著的性能提升。
在現代 CPU 上優化深度學習模型的性能面臨眾多挑戰,和優化高性能計算 (HPC) 中其他性能敏感型應用所面臨的挑戰差別不大:
- 需要重構代碼,以利用現代矢量指令。這意味着將所有關鍵基元(如卷積、矩陣乘法和批歸一化)被向量化為最新 SIMD 指令(英特爾至強處理器為 AVX2,英特爾至強融核處理器為d AVX512)。
- 要想實現最佳性能,需要特別注意高效利用所有內核。這意味着在特定層或操作實施並行化以及跨層的並行化。
- 根據執行單元的需要,提供盡可能多的數據。這意味着需要平衡使用預取、緩存限制技術和改進空間和時間局部性的數據格式。
為了滿足這些要求,英特爾開發了眾多優化型深度學習基元,計划應用於不同的深度學習框架,以確保通用構建模塊的高效實施。除了矩陣乘法和卷積以外,創建模塊還包括:
- 直接批量卷積
- 內積
- 池化:最大、最小、平均
- 標准化:跨通道局部響應歸一化 (LRN),批歸一化
- 激活:修正線性單元 (ReLU)
- 數據操作:多維轉置(轉換)、拆分、合並、求和和縮放。
請參閱 本文,獲取關於面向深度神經網絡的英特爾® 數學核心函數(英特爾® MKL-DNN)的優化基元的更多詳情。
在 TensorFlow 中,我們實施了英特爾優化版運算,以確保這些運算能在任何情況下利用英特爾 MKL-DNN 基元。同時,這也是支持英特爾® 架構可擴展性能的必要步驟,我們還需要實施大量其他優化。特別是,因為性能原因,英特爾 MKL 使用了不同於 TensorFlow 默認布局的另一種布局。我們需要最大限度地降低兩種格式的轉換開銷。我們還想確保數據科學家和其他 TensorFlow 用戶不需要改變現有的神經網絡模型,便可使用這些優化。
圖形優化
我們推出了大量圖形優化通道,以:
- 在 CPU 上運行時,將默認的 TensorFlow 操作替換為英特爾優化版本。確保用戶能運行現有的 Python 程序,在不改變神經網絡模型的情況下提升性能。
- 消除不必要且昂貴的數據布局轉換。
- 將多個運算融合在一起,確保在 CPU 上高效地重復使用高速緩存。
- 處理支持快速向后傳播的中間狀態。
這些圖形優化進一步提升了性能,沒有為 TensorFlow 編程人員帶來任何額外負擔。數據布局優化是一項關鍵的性能優化。對於 CPU 上的某些張量運算而言,本地 TensorFlow 數據格式通常不是最高效的數據布局。在這種情況下,將來自 TensorFlow 本地格式的數據布局轉換運算插入內部格式,在 CPU 上執行運算,並將運算輸出轉換回 TensorFlow 格式。但是,這些轉換造成了性能開銷,應盡力降低這些開銷。我們的數據布局優化發現了能利用英特爾 MKL 優化運算完全執行的子圖,並消除了子圖運算中的轉換。自動插入的轉換節點在子圖邊界執行數據布局轉換。融合通道是另一個關鍵優化,它將多個運算自動融合為高效運行的單個英特爾 MKL 運算。
其他優化
我們還調整眾多 TensorFlow 框架組件,以確保在各種深度學習模型上實現最高的 CPU 性能。我們使用 TensorFlow 中現成的池分配器開發了一款自定義池分配器。我們的自定義池分配器確保了 TensorFlow 和英特爾 MKL 共享相同的內存池(使用英特爾 MKL imalloc 功能),不必過早地將內存返回至操作系統,因此避免了昂貴的頁面缺失和頁面清除。此外,我們還認真優化了多個線程庫(TensorFlow 使用的 pthread 和英特爾 MKL 使用的 OpenMP),使它們能共存,而不是互相爭奪 CPU 資源。
性能實驗
我們的優化(如上述優化)在英特爾至強和英特爾至強融核平台上實現了顯著的性能提升。為了更好地展示性能改進,我們提供了以下最佳方法(或 BKM)和 3 個通用 ConvNet 性能指標評測的基准和優化性能值。
- 以下參數對英特爾至強(代號為 Broadwell)和英特爾至強融核(代號為 Knights Landing)的性能非常重要,建議您針對特定的神經網絡模型和平台優化這些參數。我們認真優化了這些參數,力求在英特爾至強和英特爾至強融核處理器上獲得 convnet 性能指標評測的最佳性能。
- 數據格式:建議用戶針對特定的神經網絡模型指定 NCHW 格式,以實現最佳性能。TensorFlow 默認的 NHWC 格式不是 CPU 上最高效的數據布局,將帶來額外的轉換開銷。
- Inter-op / intra-op:建議數據科學家和用戶在 TensorFlow 中試驗 intra-op 和 inter-op 參數,為每個模型和 CPU 平台搭配最佳設置。這些設置將影響某層或跨層的並行性。
- 批處理大小 (Batch size):批處理大小是影響可用並行性(以使用全部內核)、工作集大小和總體內存性能的另一個重要參數。
- OMP_NUM_THREADS:最佳性能需要高效使用所有可用內核。由於該設置控制超線程等級(1 到 4),因此,對英特爾至強融核處理器的性能尤為重要。
- 矩陣乘法中的轉置 (Transpose in Matrix multiplication):對於某些矩陣大小,轉置第二個輸入矩陣 b 有助於改進 Matmul 層的性能(改進高速緩存的重復使用)。以下 3 個模型所用的所有 Matmul 運算亦是如此。用戶應在其他尺寸的矩陣中試驗該設置。
- KMP_BLOCKTIME:用戶應試驗各種設置,以確定每個線程完成並行區域執行后等待的時間,單位為毫秒。
英特爾® 至強® 處理器(代號為 Broadwell - 雙插槽 - 22 個內核)上的示例設置
英特爾® 至強融核™ 處理器(代號為 Knights Landing - 68 個內核)上的示例設置
- 英特爾® 至強® 處理器(代號為 Broadwell – 雙插槽 – 22 個內核)的性能結果
- 英特爾® 至強融核™ 處理器(代號為 Knights Landing – 68 個內核)的性能結果
- 英特爾® 至強® 處理器(代號為 Broadwell)和英特爾® 至強融核™ 處理器(代號為 Knights Landing)上不同批處理尺寸的性能結果 - 訓練
利用 CPU 優化安裝 TensorFlow
按照“現已推出英特爾優化型 TensorFlow 系統” 中的指令安裝包含 pip 或 conda 的預構建二進制軟件包,或按照以下指令從源構建:
- 運行 TensorFlow 源目錄中的 "./configure",如果您選擇了使用英特爾 MKL 的選項,將自動下載 tensorflow/third_party/mkl/mklml 中的面向機器學習的最新版英特爾 MKL。
- 執行以下命令創建 pip 程序包,以安裝經過優化的 TensorFlow 創建。
- 可更改 PATH,使其指向特定 GCC 編譯器版本:
export PATH=/PATH/gcc/bin:$PATH - 也可以更改 LD_LIBRARY_PATH,使其指向新 GLIBC:
export LD_LIBRARY_PATH=/PATH/gcc/lib64:$LD_LIBRARY_PATH. - 專為在英特爾至強和英特爾至強融核處理器上實現最佳性能而創建:
bazel build --config=mkl --copt=”-DEIGEN_USE_VML” -c opt //tensorflow/tools/pip_package:
build_pip_package
- 可更改 PATH,使其指向特定 GCC 編譯器版本:
- 安裝優化版 TensorFlow 系統
- bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/path_to_save_wheel
pip install --upgrade --user ~/path_to_save_wheel /wheel_name.whl
- bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/path_to_save_wheel
系統配置
對人工智能意味着什么
優化 TensorFlow 意味着高度可用、廣泛應用的框架創建的深度學習應用現在能更快速地運行於英特爾處理器,以擴大靈活性、可訪問性和規模。例如,英特爾至強融核處理器能以近乎線性的方式跨內核和節點橫向擴展,可顯著減少訓練機器學習模型的時間。我們不斷增強英特爾處理器的性能,以處理更大、更困難的人工智能工作負載,TensorFlow 也能隨着性能的進步而升級。
英特爾和谷歌共同優化 TensorFlow 的合作體現了雙方面向開發人員和數據科學家普及人工智能的不懈努力,力求在從邊緣到雲的所有設備上隨時運行人工智能應用。英特爾相信這是創建下一代人工智能算法和模型的關鍵,有助於解決最緊迫的業務、科學、工程、醫學和社會問題。
本次合作已經在基於英特爾至強和英特爾至強融核處理器的領先平台上實現了顯著的性能提升。這些優化現已在谷歌的 TensorFlow GitHub 存儲庫中推出。我們建議人工智能社區嘗試這些優化,並期待獲得基於優化的反饋與貢獻。