節點嵌入訓練加快300倍:開源高性能圖嵌入系統GraphVite技術解讀

GraphVite是一個專爲高速、大規模的訓練場景設計的通用圖嵌入系統,已於本週正式開源。該系統旨在提供一個包含一系列圖嵌入方法的通用高性能框架,進一步推動圖學習算法的研究與發展。GraphVite支持多GPU並行,可以擴展到百萬級甚至十億級的圖,在百萬節點的圖上,只需要約一分鐘就能完成節點表示的學習。GraphVite由唐建教授帶領的MilaGraph團隊開發,相關論文已發表於WWW19會議。本文是AI前線第88篇論文導讀,我們將對GraphVite及其技術實現進行具體介紹。

image

GraphVite 總覽

目前,GraphVite已爲3種應用提供了完整的訓練和評價框架,包括節點嵌入、知識圖譜嵌入以及圖和高維數據可視化。此外,它還包含了9種流行的模型以及這些模型在一系列標準數據集上的基準測試結果。

GitHub項目入口:https://github.com/DeepGraphLearning/graphvite

image

GraphVite現支持的三種任務

爲了展示GaphVite的速度,MilaGraph提供了在三種應用上最好的開源實現與GraphVite的訓練速度報告,報告基於24個CPU線程以及4個Tesla V100GPU的硬件系統。在Youtube數據集上,節點嵌入任務的訓練速度如下:

image

Youtube數據集上節點嵌入任務訓練時間

在FB15k數據庫上實現的知識圖譜任務報告如下:

image

在MNIST數據集上實現的高維數據可視化任務報告如下:

image

可以看出在以上三個任務中,相較於目前最好的開源實現,GraphVite最多可以提升300多倍的速度。並且,在提高了速度的同時,GraphVite沒有任何性能上的犧牲,這點可以從該項目提供的基準測試報告中發現。在使用與上述速度報告相同硬件的情況下,GraphVite的說明文檔中還提供了使用GraphVite實現的所有模型的基準測試結果。在節點嵌入任務上,作者在Youtube、Flicke和Friendster-small三個數據集上提供了每個模型的micro-F1和macro-F1指標。

image

Youtube數據集上三種不同模型的結果報告

在知識圖譜嵌入任務上,作者對TransE、DistMult、ComplE、SimplE和RotatE四種方法進行了測試。

image

Youtube數據集上五種不同模型的結果報告

作者在兩個流行的數據集上對圖及高維數據可視化任務進行了測試。LargeVis所需的訓練時間和資源如下表所示。請注意,超過95%的GPU內存成本來自KNN Graph的構建,並且可以在必要時與速度進行權衡。

image

在MNIST和ImageNet數據集上LargeVis的測試結果

其中,MNIST數據集上3D可視化結果如下:

image

與類似的工作Pytorch-BigGraph相比,GraphVite速度更快,測試結果如下:

image

同時,GraphVite還比前者多了節點嵌入以及可視化兩個功能,爲研究和開發提供了更多的便利。

理解GraphVite

GraphVite爲什麼可以這麼快?這是因爲GraphVite根據CPU和GPU各自的優勢,解決了混合節點嵌入系統的三大挑戰。

混合節點嵌入系統的難點主要包含:1)基於mini-batch的SGD方法無法直接用關於大型網絡上的節點嵌入,2)由於GPU與CPU總線帶寬的差異,在CPU與GPU之間的數據轉送會成爲系統瓶頸,3) 多CPU與GPU設備間的同步成本巨大。

GraphVite使用了並行在線增廣方法在CPU上有效地擴充網絡規模。同時使用了並行負採樣方法對多GPU的嵌入訓練進行協調。GraphVite還使用了一種協作策略來降低CPU和GPU之間的同步成本。

image

GraphVite系統結構圖,灰色及黃色部分分別表示並行數據增廣過程與嵌入訓練過程。

並行在線增廣

對於節點嵌入方法,其第一階段需要使用隨機遍歷來擴充原始網絡。由於增廣網絡通常比原始網絡要大一到兩個數量級,因此,如果原始網絡已經非常大,則其網絡結構將很難被加載到主存儲器中。GraphVite採用了並行在線增廣,可以在不顯示網絡增強的情況下生成增廣的邊樣本。

作者首先繪製一個出發節點(depature node),其選擇概率與每個節點的度成正比。然後從出發節點開始執行隨機遊走,並在特定的增廣距離s內挑選節點對產生邊樣本。由於隨機遊走中生成邊樣本具有相關性,因此訓練效果可能會變差。作者受到強化學習中廣泛使用的經驗回放方法的啓發,收集邊樣本到樣本池,並在對它混洗(shuffle)後再轉發到GPU進行嵌入訓練。當每個線程預先分配有獨立的樣池時,上述方法可以並行化處理。算法2給出了並行在線增廣的詳細過程:

image

爲了更好的訓練效果,對樣本池進行混洗非常重要,但同時它也會減慢網絡增廣的速度。原因是普通的洗牌方法包含大量隨機內存訪問,並且不能由CPU緩存加速。如果服務器有多個CPU插槽,速度損失將更加嚴重。爲了緩解這個問題,作者提出了一種僞混洗技術,它以更加緩存友好的方式對相關樣本進行洗牌,並顯着提高系統的速度。

並行負採樣

在嵌入訓練階段,作者將訓練任務分爲多個子任務並將它們分配給多個GPU設備。子任務必須設計成具有很少的共享數據的形式以最小化GPU之間的同步成本。爲了瞭解如何將模型參數分配給多個GPU而不重疊,作者首先介紹了ε-梯度可交換的概念:

image

其中,作者將0-梯度可交換稱爲梯度可交換。由於節點嵌入訓練過程的稀疏性質,在網絡中會存在很多形成梯度可交換對的集合。例如,對於兩個邊緣樣本集例如,對於兩個邊緣樣本集X1,X2⊆E,如果它們不共享任何源節點或目標節點,則X1和X2是梯度可交換的。即使X1和X2共享一些節點,如果學習率α和迭代次數有界,它們仍然可以是ε-梯度可交換的。

image

基於節點嵌入中觀察到的梯度交換性,作者提出了一種用於嵌入訓練階段的並行負採樣算法。對於n個GPU,我們將頂點和上下文行分別劃分爲n個分區(上圖的左上角)。這導致樣本池的n×n分區網格,其中每個邊緣屬於其中一個塊。這樣,任何不共享行或列的塊都是可梯度交換的。只要限制每個塊上的迭代次數,同一行或列中的塊都是ε-梯度可交換的。

作者將集(episode)定義爲並行負抽樣中使用的塊級步驟。在每一集中,我們分別向n個GPU發送n個正交塊及其對應的頂點和上下文分區。然後,每個GPU使用ASGD更新自己的嵌入分區。因爲這些塊是相互梯度可交換的並且不共享參數矩陣中的任何行,所以多個GPU可以在沒有任何同步的情況下同時執行ASGD。在每集結束時,我們從所有GPU收集更新的參數並分配另外n個正交塊。這裏ε-梯度可交換由n個正交塊中的總樣本數控制,我們將其定義爲集的大小。較小的集有利於ε-梯度可交換嵌入式訓練。但是同時也會導致更頻繁的同步。因此作者調整了集的大小,以便在速度和ε-梯度可交換之間有一個很好的權衡。上圖給出了具有4個分區的並行負採樣的示例。

雖然作者使用等於n的分區數量來說明了負採樣的有效性,但是並行負採樣可以很容易地推廣到任何數量大於n的分區的情況,只需在每集中處理n個子組中的正交塊。算法3給出了用於多個GPU的混合系統的並行負採樣算法的詳細步驟:

image

協作策略

我們的並行負採樣使不同的GPU能夠同時訓練節點嵌入,只需要在集之間進行同步。但是,應該注意到,樣本池也在CPU和GPU之間共享。如果它們在樣本池上同步,則只有同一階段的設備可以同時訪問樣本池,這意味着硬件在一半時間內處於空閒狀態。爲了提高效率,作者提出了一種協作策略來降低同步成本。

作者主存儲器中分配兩個樣本池,讓CPU和GPU始終在不同的樣本池上工作。 CPU首先填充樣本池並將其傳遞給GPU。之後,並行在線增廣和並行負採樣分別在CPU和GPU上執行。當CPU填滿新的樣本池時,將交換這兩個池。通過協作策略,CPU和GPU之間的同步成本降低,混合系統的速度幾乎翻倍。

實驗

作者使用了Youtube、Reiendster-small、Hyperlink-PLD和Friendster四個數據庫對GraphVite的性能進行了測試。部分實驗結果已在第一章中展示,詳細的實驗結果在論文原文以及GraphVite官方網站https://graphvite.io/)的Docs中都有詳細的展示。

快速入門

GraphVite可以在CUDA>=9.2的Linux系統上運行,兼容Python2.7和Python3.5/3.6/3.7版本。GraphVite對待新手十分友好,它提供了關於節點嵌入任務的快速入門示例供用戶學習。用戶可以選擇通過Conda源進行安裝或使用源碼編譯,使用Conda安裝僅需在命令行輸入命令:

conda install -c milagraph graphvite

如果僅需要嵌入訓練而不要測試部分,還可以選擇更加輕量級的最小化GraphVite系統:

conda install -c milagraph graphvite-mini

或者用戶也可以選擇使用源碼編譯:

git clone https://github.com/DeepGraphLearning/graphvite
cd graphvite
conda install -y --file conda/requirements.txt
mkdir build
cd build && cmake .. && make && cd -
cd python && python setup.py install && cd -

安裝完成GraphVite後,直接執行即可查看示例,在終端輸入:

conda install -c milagraph graphvite-mini

示例需要運行約一分多鐘的時間,然後會輸出結果:

Batch id: 6000
loss = 0.371641

macro-F1@20%: 0.236794
micro-F1@20%: 0.388110
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章