藉助深度學習加速NLP任務,將BERT 用於 SQuAD1 模型訓練時間從 7 個小時縮短到30 分鐘

本文最初發表在determined.ai 博客,由 InfoQ 中文站翻譯並分享。

在這個由兩部分組成的博文系列中,我們將演示如何加速跨多 GPU 的自然語言處理深度學習模型訓練,將 BERT 用於 SQuAD1 【1】模型訓練時間從近7 個小時縮短到僅30 分鐘

在本文中,我們將激發在自然語言處理中進行深度學習和分佈式訓練的需求,強調對有效的分佈式訓練最重要的因素,並提供了在Determind中運行的一系列 BERT 微調實驗的實證結果。在本文系列的第二部分中,我們將概述針對同一個自然語言處理任務的優化分佈式數據加載和模型評估的技術。

面向NLP的深度學習的“種子”

像 BERT、XLNet 和 GPT-3 這樣的神經語言模型在過去幾年裏屢次成爲頭條新聞。爲什麼會這樣呢?

針對常見的自然語言處理任務,如實體識別、問答系統,機器學習算法通常需要特徵向量作爲輸入。自然語言輸入被表示爲向量,從這一點開始,我們訓練模型來對文本進行分類、對文檔進行聚類、回答問題等【2】。

過去十年的大量研究表明,語言建模作爲下游自然語言處理任務模型最終質量的驅動因素,具有重要意義。反觀上個世紀的統計語言模型,像bag-of-wordstf-idf,對於自然語言處理任務,尤其是吸引我們的人工智能完備(AI-complete)自然語言處理任務來說,有效地封頂了技術水平,使其遠未達到“驚天動地”的地步。

我依然記得,在上世紀 90 年代末第一次嘗試 Babel Fish 機器翻譯引擎時,我得出結論是,天網還很遙遠——Babel Fish 經常給人一種這樣的感覺,它更像是一個逐字查找字典引擎,而不是語言理解和翻譯的人工智能。

自那以後,對許多自然語言處理任務來說,上述限制已經解除(可以說是消失了),我們在搜索網頁或與 Alexa 進行對話時,不斷地親身體驗到這些好處。2018 年,隨着一類新的語言模型的問世,自然語言處理的發展呈現了爆炸式的增長:首先是基於長短期記憶人工神經網絡(LSTM)的ELMo,其次是基於 Transformer 架構的BERT。這些語言模型的新思路是依賴於單詞上下文;而以前的非上下文詞嵌入,如word2vecGloVe,將給定單詞精確地編碼爲一個向量,而芝麻街(Sesame Street)模型被設計用來捕捉語言的細微差別,而非上下文詞嵌入從定義上來說是無法做到的。

神經語言模型的訓練成本

最先進的語言模型的訓練成本可能高得驚人。像 BERT 和 XLNet 這樣的模型需要學習數以億計的參數——從頭開始訓練許多神經語言模型的計算成本對大多數組織來說是令人望而卻步的。例如,XLNet需要在 512 個 TPU v3 上進行 5.5 天的訓練。在 GCP 上覆制它的成本將會超過 50 萬美元。語言模型的複雜性和訓練成本只會增加,比如,OpenAI 在 2020 年 5 月推出的 GPT-3 模型,可以學習 1750 億個參數,估計訓練成本將超過 1200 萬美元

自然語言處理的循序遷移學習工作流示例。通常,昂貴的預訓練會產生一個普遍有用的語言模型,可用於解決特定的下游自然語言處理任務。( 來源:《BERT:面向語言理解的深度雙向 Transformer 的預訓練》(BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding)")

由於研究社區和支持語言模型研究的組織的貢獻,任何人都可以免費使用高質量的預訓練模型。不僅模型檢查點是可用的,而且更廣泛的機器學習庫生態系統,使得只需幾行代碼就可以在你所選擇的框架中直接使用這些預訓練模型。因此,在合理的預算下,上述針對自然語言處理的順序遷移學習方法是很容易實現的。在我們的例子中,我們爲 SQuAD 訓練了 BERT,來生成一個可以提取關於給定段落問題答案的模型。每個實驗需要不到 20 美元的計算成本來進行 GCP 訓練,我們得到了高質量的 F1 成績,在 87% ~89% 的範圍中。爲了便於比較,人類的表現爲86.8%,而最先進的技術表現爲93%

基線:單 GPU 訓練

讓我們首先在單塊 GPU 上爲 SQuAD 訓練一個 BERT 模型。在這個Python 示例中,我們使用了 Hugging Face 的Transformer庫的預訓練模型、特徵化和數據加載方法,以及引用超參數。在單塊 GPU 上進行訓練,大約需要兩個輪數(epoch),驗證數據集的 F1 得分爲 88.4%。這結果還算不錯,但是這個訓練花去了 7 個多小時!等待結果需要很長的時間,而且這還只是一個使用固定超參數的常見基準自然語言處理任務。如果你或你的團隊需要訓練更多的數據、調整超參數,爲其他自然語言處理任務訓練模型,或者爲自定義的下游任務開發和調試模型,那麼話費一天活更長的時間來訓練摸個模型,將會使進度變得非常緩慢。

應用分佈式訓練

在本文的其餘部分,我們將展示如何使用determinated 的分佈式訓練功能,以大約14 倍的速度執行相同的訓練任務,同時達到相同的模型正確率!在這個過程中,我們將揭示影響擴展性能的關鍵因素,併爲有效的分佈式訓練提供實用的指導。

藉助 determined 的標準化模型範例,在多塊 GPU 上訓練一個模型不需要更改代碼。接下來的每個結果,無論是在一臺機器上使用 2 塊 GPU 進行訓練,還是在多臺機器上使用 16 塊 GPU 進行訓練,都只需更改配置即可。

讓我們看看如何在午休時間而不是一整天的工作時間裏,通過在 determined 上進行分佈式訓練來訓練上述同樣的模型。在這篇博文中,我們專注於優化訓練循環。在本文系列的第二部分中,我們將重點討論訓練工作流中影響整體運行時間的其他組件,即數據加載和驗證。爲此,以下時間並不包括數據加載和驗證的時間。

擴展初步結果

下面的圖表顯示了從 1 塊 NVIDA K80 GPU 擴展到 8 塊 NVIDIA K80 GPU(都在 GCP 的單機上)的訓練時間。在這些實驗中,我們固定了每塊 GPU 的批次大小和訓練輪數的總數量。

這是一個不錯的初步結果,儘管我們沒能實現線性擴展,但我們做到了將擴展效率保持在 80% 以上,而且我們還設法將 BERT SQuAD 模型的訓練時間縮短到一個小時。我們在所有四個實驗的驗證數據集上獲得了 87% ~88% 的 F1 得分。

做得更好:梯度聚合和 RAdam

在上面的結果中,隨着訓練並行度的增加,擴展效率呈現明顯的下降趨勢。這是怎麼回事兒?也許我們可以接受這樣擴展的結果,但如果我們有一個更重的訓練工作量,想分配到 64 塊 GPU 呢?這種趨勢對我們並不利。

對於可能發生的情況,一種自然的理論是,訓練是受通信限制的。爲了將訓練分佈在 8 塊 GPU 上,Determined 將訓練數據集分成 8 個碎片,獨立訓練 8 個模型(每塊 GPU 一個)的小批次,然後聚合並進行通信傳遞梯度更新,以使將模型的所有 8 個副本都具有相同的權重。然後,我們對每一個批次都重複這個正向傳遞和反向傳遞,然後進行梯度聚合的過程。正如我們在博文產品文檔所討論的那樣,像大批量訓練這樣的通信減少技術,可以幫助減少訓練時間。當 GPU 通過 PCI-E 而不是更高帶寬(但更昂貴)的 NVLink 連接時,這種技術就特別有前途。

讓我們看看這一理論是否適用於我們的模型。使用 Determined,你可以通過配置的改變來調整每槽的批次大小,但請記住,就算是很小的增加,也會很快耗盡 GPU 的內存,因爲正向傳遞和反向傳遞所需的居間態與模型的大小呈線性關係,而且還與批次大小有關。相反,我們要保持 GPU 的內存需求適中,以便能夠在低成本的 NVIDIA K80 上運行。我們通過利用 Determined 的分佈式訓練優化實現了這一目標,降低了 GPU 間通信和每塊 GPU 的內存需求。這個聚合頻率配置選項指定在跨 GPU 通過通信傳遞梯度更新之前要執行的正向傳遞和反向傳遞的次數。在下表中,我們看到增加聚合頻率確實有助於運行時:

這太棒了!如果我們可以將訓練時間減少 31 分鐘,那麼我們的每 GPU 的擴展效率將從 0.93 提高到完美的 1。不過,我遺漏了一些東西——對於上面的三行,我們的驗證數據集 F1 得分分別爲 87.3%、85% 和 52.1%。

差一點點就成功了。這是怎麼回事呢?因爲大批次的隨機梯度下降並不總是“有效”,特別是,在這種情況下,很難找到學習率的最佳點。有時,線性縮放規則(Linear Scaling Rule)會起作用,如果我們將批次大小乘以 k,我們還得將(先前調整過的)學習率乘以 k。在我們的例子中,使用AdamW優化器,線性縮放根本沒有幫助;事實上,當應用線性縮放規則時,我們的 F1 得分甚至會更糟。學習率預熱策略也會有所幫助,在大批次訓練中,早期使用較小的學習率。不過,根據我們的經驗,RAdam優化器更適合大批次訓練,而不需要進行大量的學習率調整。當我們換成RAdam 實現時,我們的結果看起來要好得多:

在這種情況下,我們可以看到,即使相當基金的聚合頻率爲 10,也可以保持驗證性能。併爲我們提供從 1 塊 GPU 到 2 塊 GPU 的完美訓練擴展。在聚合頻率爲 100 的情況下,結果表明,即使訓練時間加速達到了收益遞減的地步,RAdam 仍然足夠健壯,即使在極端情況下,也有相當好的表現。實際上,我們建議測試聚合頻率低於 16,以便在不犧牲模型性能的同時縮短訓練時間。

超動力的多機訓練

我們已經取得了長足的進步,利用 Determined 的分佈式訓練的能力,爲 SQuAD 訓練 BERT 的時間從單塊 GPU 上的近 7 個小時縮短到單臺機器上 8 塊 GPU 上的不到 1 個小時。

爲了進一步縮短訓練時間,我們還能夠做些什麼呢?特別是考慮到 GCP 上的單個實例最多允許8 塊 GPU的事實。有了 Determined,模型開發人員可以像在單機上進行多塊 GPU 訓練一樣,輕鬆擴展到多機訓練。當基線單塊 GPU 訓練時間需要幾天到幾周的時候,這一點就特別有價值了。

在爲 SQuAD 訓練 BERT 的情況下,在兩個實例中將訓練擴展到 16 塊 GPU 時,我們將訓練時間進一步減少到 30 分鐘。與我們的第一個單塊 GPU 訓練工作相比,我們實現了每 GPU 擴展效率爲 0.83 。

值得注意的是,當我們擴展到多臺機器時,通信限制對我們的影響變得更大,以至於如果要保持有效批次大小不變的話,那麼在 16 塊 GPU 上的訓練時間實際上會大雨在單機上 8 塊 GPU 上的訓練時間。通過將聚合頻率增加到 2,並使用 RAdam 優化器,我們可以更好的進行擴展,在驗證數據集上的 F1 得分仍然達到了 87%。

下一步打算

在本文中,我們使用了 Determined 對分佈式訓練的支持,對 BERT 的訓練時間進行了優化,從近 7 個小時縮短到僅 30 分鐘。除了切換到 RAdam 優化器之外,我們在不改變模型本身的一行代碼的情況下就實現了這些性能的提升!

在本文中,我們專注的是優化訓練循環。在下一篇文章中,我們將跳出訓練循環,進一步優化分佈式環境下的模型訓練。我們將利用一些即將推出的產品增強功能來實現這一目標,敬請期待。

我希望本文已經向讀者表明,在真實世界的自然語言處理的遷移學習用例上,使用 Determined 進行分佈式訓練既簡單,又極具價值。如果你想讓模型的訓練工作在午休時間即可完成,而不是通宵達旦,請不妨一試!

尾註

【1】 SQuAD,是Stanford Question Answering Dataset(斯坦福問答數據集)的縮寫。該數據集是一個流行的閱讀理解基準數據集,用於從給定段落中提取問題答案。

【2】 這就是順序遷移學習(Sequential Transfer Learning,STL)的範式,其中一個(通常成本昂貴)預訓練任務完成一次,由此產生的預訓練模型是我們訓練下游適應任務訓練模型的起點。這篇博文對自然語言處理中的順序遷移學習和其他風格的遷移學習做了很好的解釋。

原文鏈接:

https://determined.ai/blog/faster-nlp-with-deep-learning-distributed-training/

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