使用nGraph的Intel®Xeon®上的高性能TensorFlow

使用nGraph的Intel®Xeon®上的高性能TensorFlow

High-performance TensorFlow* on Intel® Xeon® Using nGraph

最近宣佈了nGraph的開源版本™一個C++庫、編譯器和運行時套件,用於在各種設備上運行深度神經網絡。基於Tensraph的優化項目,能公佈優化後的項目或反向代碼。與我們最初的TensorFlow集成相比,橋接代碼實現提供了高達10倍的性能。

設置很簡單(我們在bridge代碼庫中提供了說明):像平常一樣構建TensorFlow並選擇nGraph作爲TensorFlow設備,然後在現有的基於TensorFlow的DL模型中修改幾行Python代碼以針對nGraph。目前,nGraph支持Intel x86處理器上的工作負載,並將支持Intel®Nervana™ 神經網絡處理器(Intel®Nervana™ NNPs)可用時。未來對NVIDIA GPU的支持也在進行中。

英特爾至強處理器上的nGraph性能

新的nGraph TensorFlow橋比上個月開源的初始版本提供了顯著的改進。如圖1所示,與XLACPU編譯器相比,使用nGraph可以顯著提高訓練性能。雖然需要注意的是,XLA CPU的實現仍然是實驗性的,並且有很大的改進空間,但是我們的測量結果表明,nGraph與TensorFlow的IA優化的最新技術相比也非常好。圖2比較了MKL DNN優化的TensorFlow實現,它直接在TensorFlow的本地計算引擎中實現MKL-DNN優化,與nGraph TensorFlow橋代碼實現進行了比較。在使用ImageNet數據集的ResNet50等模型上,結合nGraph可以獲得更好的訓練性能(nGraph上爲68.9個圖像/秒,而TF-MKL-DNN上爲64個圖像/秒,提高了約7個百分點1)。結果還表明CIFAR10
ResNet模型的性能有了顯著的改進。然而,我們注意到,這個差距是由一個已知的問題造成的,這個問題與基線TF-MKL-DNN實現中MKL-DNN原語初始化的開銷有關。該問題的解決方案正在向上遊的TensorFlow進行。綜上所述,這些結果表明nGraph-TensorFlow集成所產生的開銷很小,並且可以實現TensorFlow最先進的IA性能。
在這裏插入圖片描述
Figure 1: Training speed using TensorFlow-XLA (2S Intel® Xeon® Platinum 8180 CPU) yields 68.9 img/sec at peak performance on
ResNet50-I1k with nGraph and 6.5 img/sec without.
在這裏插入圖片描述
Figure 2: Training speed of ResNet50-I1k using TensorFlow-XLA-nGraph (2S Intel® Xeon® Platinum 8180 CPU) yields 68.9 img/sec at peak performance with nGraph compared to 64 img/sec using MKL-DNN-optimized TensorFlow

How we did it

Performance optimizations in the nGraph CPU backend

nGraph CPU後端(有時稱爲“IA transformer”)實現了許多優化,在英特爾CPU平臺上爲給定型號提供了最優化的性能:

與框架無關的優化:

我們利用優化的內核庫,如MKL-DNN和Eigen來實現快速DNN內核。此外,我們還加入了圖優化過程,這些過程爲這些內核實現選擇了最佳的數據佈局,並減少了圖形級別的總體數據佈局轉換。我們還融合了BatchNorm和ReLu等操作,以更好地利用具有較低內存需求的融合內核實現。

TF/XLA特定的優化:

TensorFlow有一些API級別的缺陷,導致在模型中添加額外的Pad操作。這些操作可能導致不必要的數據佈局轉換,並且可以通過MKL-DNN提供的填充卷積核來避免。我們利用這一點將這些pad操作融合到現有的卷積算子中,相對於基本的TensorFlow模型,它提供了更好的性能提升。此外,XLA還添加了一些標識操作符,比如從Float32到Float32的類型轉換,這些操作符可以從圖中刪除而不影響正確性。

基於模式匹配的圖操作融合

nGraph-IR包含許多常見深度學習原語的內置原語,包括卷積、填充和批處理規範化。之所以選擇這些原語,是因爲它們可以相對容易地映射到後端庫(如“英特爾MKL-DNN”)提供的高度優化的計算內核上。

TensorFlow的tf2xla轉換器將一些高級TensorFlow操作分解爲根據低級張量操作定義的圖。一個經常發生的情況是TensorFlow的平均池操作。如果填充輸入張量,則由tf2xla將操作重寫爲包含以下內容的子圖:

a reduce-window operation to sum sliding windows of the graph;

a second reduce-window operation to compute the divisors to apply to each summed window; and

an element-wise division operation.

對圖的滑動窗口求和的減窗運算;

第二個reduce window操作,用於計算要應用於每個求和窗口的除數;以及

元素除法運算。

雖然這些操作中的每一個都直接在nGraph中得到支持,但它們的性能將不及nGraph的AvgPool原語,後者直接映射到MKL-DNN提供的優化實現。對於最大池、卷積反向傳播和其他一些重要的原語,也會出現類似的情況。

爲了解決這個問題,我們在TensorFlow到nGraph橋內部實現了一個HLO融合過程。這個融合過程,如下面的圖3所示,補充了nGraph CPU後端本身實現的許多與框架無關的優化。當HLO融合被納入時,從HLO到nGraph的轉換分三步進行。首先,搜索由tf2xla生成的原始圖形(圖3a),以查找與高級操作對應的模式(在圖3b中由橙色節點表示)。第二,每個識別出要融合的子圖被包裝在一個HLO融合指令中(圖3c)。最後,將融合後的HLO圖轉換爲nGraph圖(圖3d),並將融合指令映射到高級nGraph操作。
在這裏插入圖片描述
Figure 3: Illustration of nGraph graph generation.

fusion pass目前識別卷積反向傳播、平均和最大池的正向和反向傳播、ReLU的正向和反向傳播以及sum、product和max等縮減操作(請注意,其他一些高級操作,包括批處理規範化,在HLO中已被視爲原始操作,因此,沒有必要將它們熔合。)

它是如何工作的?

TensorFlow的XLA框架爲“後端”設備提供了一種機制,用於註冊接收以HLO格式表示的計算圖,並提供一個能夠在運行時執行計算的可執行對象。我們開發了一個XLA插件,它註冊爲“NGRAPH”設備,遵從並執行HLO計算。

一個動態加載的插件框架

目前,XLA插件設備源代碼需要駐留在TensorFlow樹中,並且必須與TensorFlow源代碼樹的其餘部分一起構建。添加一個新設備需要理解TensorFlow代碼和構建系統,這兩者都相當複雜。此外,上游和維護新代碼是困難的,有時是不可取的,因爲插件實現中的每一個更改都需要經過TensorFlow團隊的審覈,即使它可能與TensorFlow無關。

我們開發的動態可加載的XLA插件,其中實際的XLA插件源代碼位於TensorFlow源代碼樹之外,它內置於一個動態共享對象(DSO)庫中,具有許多nGraph固有的優化。在XLA方面,我們創建了一個插件適配器,該適配器加載插件DSO並使用插件DSO提供的屬性註冊XLA設備。

Graph compilation and execution

From TensorFlow* computation graph to nGraph

TensorFlow*使用XLA創建HLO計算圖。HLO的中間表示(IR)隨後被移交給nGraph插件DSO。nGraph橋的源代碼位於一個名爲nGraph tensorflow bridge的單獨GitHub存儲庫中。
當工作負載部署到目標nGraph設備時,nGraph tensorflow bridge可以將HLO-IR轉換爲nGraph-IR,然後對其進行編譯以生成特定設備的可執行代碼。然後,該可執行文件返回到TensorFlow,以便後續執行計算。

Figure 4: Transformation of TensorFlow graph to nGraph IR.
在這裏插入圖片描述
Configuration details

Hardware configuration: 2S Intel® Xeon® Platinum 8180 CPU @ 2.50GHz (28 cores), HT enabled, turbo enabled, scaling governor set to “performance” via intel_pstate driver, 384GB (12 * 32GB) DDR4 ECC SDRAM RDIMM @ 2666MHz (Micron* part no. 36ASF4G72PZ-2G6D1),800GB SSD 2.5in SATA 3.0 6Gb/s Intel Downieville
SSDSC2BB800G701 DC S3520, client ethernet adapter: Intel PCH Integrated 10 Gigabit Ethernet Controller

Software configuration: Ubuntu 16.04.3 LTS (GNU/Linux
4.4.0-109-generic x86_64). Datasets were hosted on NFS storage.

Software Release Versions:

  1. ngraph-tensorflow, Commit- c2cc26b
  2. ngraph-tensorflow-bridge, Commit- f9b9e5a
  3. ngraph, Commit- eec1922

Scripts:https://github.com/NervanaSystems/ngraph-tensorflow bridge/tree/master/test/resnet

Command lines

Resnet cifar10: KMP_BLOCKTIME=1 OMP_NUM_THREADS=56 KMP_AFFINITY=granularity=fine,compact,1,0 python cifar10_main.py --data_dir /path/to/dataset --model_dir /path/to/saved_model/ --batch_size 128 --resnet_size $RESNET_SIZE --data_format channels_first --inter_op 2 --select_device NGRAPH

# (RESNET_SIZE was tested at 8, 20, 56)

Resnet Imagenet(I1k): KMP_BLOCKTIME=0 OMP_NUM_THREADS=56
KMP_AFFINITY=granularity=fine,compact,1,0 python imagenet_main.py --data_dir /path/to/dataset --model_dir /path/to/saved_model/ --batch_size 128 --resnet_size 50 --data_format channels_first --inter_op 2 - select_device NGRAPH

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章