原文:High Performance Deep Learning
作者:Gaurav Menghani(谷歌研究院 | 軟體工程師)
深度學習技術的突破性進展彰顯了其令人難以置信的潛力,提供了讓人興奮的新的 AI 增強軟體和系統。
但是,從財政、計算再到環境等幾個角度上考慮,訓練最強大的模型是極其昂貴的。
提高這些模型的效率會在很多領域產生深遠的影響,因此,基於這一需求,未來所開發的模型只會有助於進一步擴大深度學習所提供的範圍、適用性和價值。
本文將基於 arxiv 論文 Efficient Deep Learning: A Survey on Making Deep Learning Models Smaller, Faster, and Better,首先展示深度學習領域模型的快速增長,及其在繼續擴大規模的階段激發了對效率和效能的需求。隨後將給出一個基本框架,介紹實現高效深度學習的可用工具和技術,並進一步為每個重點領域提供詳細的示例,盤點工業界和學術界迄今為止的重要探索。
如今,無數應用中都有著機器學習的身影。過去十年中,採用神經網路的深度學習一直是訓練新機器學習模型的主要方法。
它的崛起通常要歸功於 2012 年舉辦的 ImageNet 競賽。就在同年,多倫多大學的一支團隊提交了一個名為 AlexNet (以首席開發人員 Alex Krizhevsky 命名)的深度卷積網路(deep convolutional network),比接下來提交的最好成績還要高出 41%。
在此之前,人們曾嘗試過深度和卷積的網路,但不知為何從未兌現承諾。
90 年代,卷積層的概念最早由 LeCun 等人提出。類似地,若干神經網路也在 80 年代、90 年代陸續地進入大眾視野。究竟是何原因讓深度網路花費如此長的時間才超越手工調優的特徵工程(feature-engineered)模型呢?
1. 計算(Compute):AlexNet 是早期依賴圖形處理單元(GPU, Graphics Processing Units)進行訓練的模型之一。
2. 演算法(Algorithms):採用 ReLU 作為啟用函數,使得梯度反向傳播地更深。先前的深度網路迭代採用的是 Sigmoid 或 Tanh 啟用函數,除了很小的輸入範圍外,在 1.0 或 - 1.0 處達到飽和。因此,改變輸入變數會導致非常微小的梯度,而當存在很多層時,梯度基本上就消失了。三個啟用函數的影象如下所示:
簡言之,ReLU 不會出現梯度消失的問題,而且從計算的角度上看,Sigmoid 和 Tanh 啟用函數均需要計算指數,複雜度高,而 ReLU 通過簡單的閾值便可得到啟用值。
3. 資料(Data):ImageNet(全球最大的影象識別資料庫)包含有 > 1M 的數千個類型、數百張有標註的影象。隨著網際網路產品的出現,從使用者行為中收集標註資料的成本也不斷降低。
鑑於這一開拓性的工作,人們競相使用越來越多的參數來創建更深層的網路。如 VGGNet、Inception,、ResNet 等模型架構,在隨後的幾年裡相繼打破了以往 ImageNet 的競賽記錄。如今,這些模型也已在現實世界中進行了部署。
我們在自然語言理解(NLU, Natural Language Understanding)領域也看到了類似的效果,Transformer 架構在 GLUE 任務上顯著優於之前的基準測試。
隨後,BERT 和 GPT 模型都演示了在 NLP 相關任務上的改進,並且 BERT 衍生了幾個相關的模型架構,對其各個方面進行了優化。而 GPT-3 只需要給定的提示便可續寫生動逼真的故事,作為最強的文字生成模型成功地引發了人們的關注。
在谷歌搜尋引擎(Google Search)中使用 BERT 可以提高結果的相關性,而 GPT-3 可作為 API 供感興趣的使用者使用。
可以推斷,深度學習研究一直關注於改善現有的技術水平,因此,我們看到了在影象分類、文字分類等基準上的不斷優化。神經網路的每一次新突破都會導致網路複雜性、參數數量、訓練網路所需的訓練資源數量以及預測延遲等方面的增加。
現在,諸如 GPT-3 的自然語言模型僅訓練一次迭代都要花費數百萬美元,而且其中還不包括嘗試不同的超參組合(微調)或手動 / 自動運行偵錯模型架構的成本。毫不誇張地說,這些模型的參數數量高達數十億甚至數萬億。
與此同時,這些模型令人難以置信的效能也催生出將其應用於新任務的需求,力求突破現有的技術瓶頸。這就產生了一個有趣的問題,這些模型的傳播速度會受其效率的限制。
更具體地說,隨著深度學習新時代的到來,以及模型變得越來越大並在不同的領域傳播,我們難免會面臨著以下問題:
1. 可持續的伺服器端擴展(Sustainable Server-Side Scaling):訓練和部署大型深度學習模型的成本很高。雖然訓練可能只是一次性成本(如果使用預訓練的模型可能是免費的),但是部署和讓推理持續很長時間段仍可能很昂貴。此外,對用於培訓和部署這些大型模型的資料中心的碳足跡(carbon footprint),也是一種非常現實的擔憂。像谷歌、Facebook、亞馬遜等大型組織每年在其資料中心上的資本支出高達數十億美元。因此,任何效率的提高都是非常顯著的。
2. 啟用裝置部署(Enabling On-Device Deployment):隨著智慧手機和物聯網裝置(IoT devices)的出現,其上部署的應用程式必須是實時的。因此,對裝置上的 ML 模型便產生了一定的需求(其中模型推理直接發生在裝置上),這就使得優化它們將要運行裝置的模型成為當務之急。
3. 隱私和資料敏感性(Privacy & Data Sensitivity):當用戶資料可能對處理 / 受到各種限制(如歐洲 GDPR 法律)敏感時,能夠使用少量資料進行訓練是至關重要的。因此,用一小部分資料有效地訓練模型就意味著需要更少的資料收集。類似地,啟用裝置上的模型意味著模型推理可以完全在使用者的裝置上運行,而無需再將輸入資料傳送到伺服器端。
4. 新應用程式(New Applications):效率還可以啟用在現有資源約束下無法執行的應用程式。
5. 模型爆炸(Explosion of Models):通常,在同一裝置上可能併發地提供多個 ML 模型。這便進一步減少了單個模型的可用資源。這可能發生在伺服器端,其中多個模型可能位於同一臺機器上,也可能位於用於不同功能的不同模型的應用程式中。
我們所確定的核心挑戰是效率。效率可能是一個看似寬泛的術語,我們此處明確了需要重點調查研究的兩個方面。
1. 推理效率(Inference Efficiency):這主要處理部署用於推理的模型(依據給定輸入計算模型輸出)的人可能會提及的問題。比如,這種模型小嗎?快不快?具體來說,這個模型包含多少參數?磁碟大小、推理階段的 RAM 消耗、推理延遲各為多少呢?
2. 訓練效率(Training Efficiency):這涉及到訓練模型的人可能提問的問題,比如模型訓練需要多長時間?訓練需要多少裝置?模型能適應記憶體嗎?此外,還可能包括以下問題,模型需要多少資料才能在給定任務上實現預期的效能呢?
如果在給定的任務上有兩個同樣出色的模型,可能想要選擇其中一個更好地、更為理想的模型,在上述兩個方面都可以做到最佳。
如果要在推理受到限制的裝置(如移動和嵌入式裝置)或昂貴的裝置(雲伺服器)上部署模型,則需要注意推理效率。同樣地,如果一個人要用有限或昂貴的訓練資源上從頭開始訓練一個大型模型,那麼開發旨在提高訓練效率的模型將會有所幫助。
無論優化的目標是什麼,我們都希望達到最佳效果。這意味著,選擇的任何模型對於所關注的權衡而言都是最好的。作為圖 2 中的一個例子,綠點表示帕累托最優(pareto-optimal)模型,其中沒有其他模型(紅點)在相同推理延遲或相反的情況下獲得更高的準確性。與此同時,帕累托最優模型(綠點)形成所謂的帕累託邊界。根據定義,帕累託邊界模型比其他模型更有效,因為它們在給定的權衡下表現最好。因此,當尋求效率時,更應該將帕累託相關的最新發現和進展放在考慮範圍之內。
反過來,高效的深度學習可被定義為一組演算法、技術、工具和基礎結構的集合,它們可以協同工作,允許使用者訓練和部署帕累托最優模型,這些模型只需花費更少的資源來訓練和 / 或部署,同時實現類似的結果。
在關注模型質量的同時,其效率方面也不容忽視。當一個組織開始考慮構建高效的深度學習模型,以通過方案提高交付能力時,這些執行方案所需的軟體和硬體工具便是實現高效能的基礎。
接下來,本文將大致分為以下兩部分進行介紹:首先是建模技術的四大支柱 —— 壓縮技術(Compression Techniques)、學習技巧(Learning Techniques)、自動化(Automation)、高效模型的架構和層(Efficient Model Architectures & Layers),然後是已有的基礎設施與硬體基礎。
如先前所述,壓縮技術作為通用技術可以幫助神經網路實現一層或多層的更有效表示,但可能會在質量上有所取捨。效率可以來自於改進一個或多個足跡指標,如模型大小、推理延遲、收斂所需的訓練時間等,以儘可能換取少的質量損失。通常,模型可能被過度參數化(over-parameterized)。在這種情況下,這些技術還有助於改進對未知資料的泛化。
(1)剪枝(Pruning):這是一種流行的壓縮技術,我們可以對無關緊要的網路連線進行剪枝,從而使網路變得稀疏。LeCun 等人在其所發表的題為 「最優腦損傷」(OBD, Optimal Brain Damage)的論文中,將神經網路中的參數(層間連線)減少了 4 倍,同時還提高了推理速度和泛化能力。
Hassibi 等人和 Zhu 等人在 OBD 方法的基礎上提出了 Optimal Brain Surgeon 工作,這是一種效能較好的網路剪枝技術,利用誤差函數的二次導數資訊,解析預測權值擾動對函數的影響程度,以自頂向下的方式削弱或消除部分連線權,實現網路的結構化。這些方法採用預訓練到合理質量的網路,然後迭代刪除顯著性得分最低的參數,顯著性得分用於衡量特定連線的重要性,這樣對驗證損失的影響就會最小化。一旦剪枝結束,網路就會用剩餘的參數進行微調。重複這個過程,直到網路被剪枝到所需的級別。
l 顯著性(Saliency):這是決定應該剪枝哪個連線的啟發式方法。這可以基於連線權相對於損失函數的二階導數,連線權的大小等等。
l 非結構化 v/s 結構化(Unstructured v/s Structured):非結構化剪枝是剪枝方法中最靈活的一種,對於所有給定的參數都是 「一視同仁」。而在結構化剪枝中,參數在 size> 1 的塊中進行修剪(例如在權矩陣中進行 row-wise 修剪或在卷積濾波器中進行 channel-wise 修剪)。結構化剪枝允許在大小和延遲方面更容易地利用推理時間,因為這些修剪後的參數塊可以被智慧地跳過以進行儲存和推理。
l 分佈(Distribution):可以在每層設定相同的剪枝預算,或者在每層的基礎上進行分配。經驗直覺告訴我們,某些層相對來說更容易剪枝一些。例如,通常情況下,前幾層如果足夠小,則無法容忍顯著的稀疏。
l 排程(Scheduling):然而,額外的標準是該剪枝多少以及何時進行呢?我們是想在每輪中修剪等量的參數,還是在剪枝開始時較快,然後逐漸放慢呢?
l 再生(Regrowth):在某些情況下,允許網路再生剪枝的連線,這樣網路就會以相同百分比的連線剪枝不斷運行。
就實際使用而言,具備有意義的塊大小的結構化剪枝可以輔助提高延遲。在保留相同 Top-1 精度的情況下,Elsen 等人構建的稀疏卷積網路使用約 66% 的參數,比稠密網路高出 1.3 - 2.4 倍。他們通過其庫將 NHWC(輸入資料格式:channels-last)標準密集表示轉換為特殊的 NCHW(channels-first)「塊壓縮稀疏行」 (BCSR, Block Compressed Sparse Row)表示,這適用於使用其高速核心在 ARM 裝置、WebAssembly(相對 JavaScript 而言的另一種可以在瀏覽器中執行的程式語言)等上的進行快速推理。儘管他們也引入了一些約束以限制可加速的稀疏網路類型,但總的來說,這是朝著實際改進剪枝網路的足跡指標邁出的有希望的一步。
(2)量化(Quantization):量化是另一種非常流行的壓縮技術。它沿用了這樣一種思路,即典型網路中幾乎所有權值都是 32 位浮點值,如果我們願意降低一些模型質量的話,如準確率、精度、召回率等指標,便可實現以較低精度的格式(16 位、8 位、4 位等)來儲存這些值。
例如,當模型持久化時,以將權值矩陣(weight matrix)中的最小值對映為 0,而將最大值對映為(其中 b 是精度位數),併線性地將它們之間的所有值外推(extrapolate)為整數。通常,這足以減少模型的大小。例如,如果 b = 8,則將 32 位浮點權值對映為 8 位無符號整數(unsigned integers),該操作可以將空間減少 4 倍。在進行推理(計算模型預測)時,我們可以使用陣列的量化值和最小 & 最大浮點值恢復原始浮點值(由於舍入誤差)的有損表示(lossy representation)。鑑於要量化模型的權重,於是此步被稱為權重量化(Weight Quantization)。
由於大量的參數,有損表示和舍入誤差對於內建冗餘的大型網路可能問題不大,但對於小型網路而言,由於其對誤差的敏感性強,可能會降低精度。
可以以實驗的方式模擬訓練過程中權重量化的舍入行為來解決這個問題。通過在模型訓練圖中新增節點來量化和反量化(dequantize)啟用函數和權重矩陣,這樣神經網路操作的訓練時間輸入看起來與推理階段相同。這種節點稱為偽量化(Fake Quantization)節點。這種訓練方式使得網路對推理模式下的量化行為具有更強的魯棒性。請注意,現在正在訓練中進行啟用量化(Activation Quantization)和權重量化。Jacob 等人和 krishnamoori 等人詳細描述了訓練時間模擬量化這一步驟。
由於權值和啟用都是在模擬的量化模式下運行的,這意味著所有層接收的輸入都可以以較低的精度表示,在模型經過訓練後,它應該具備很強的魯棒性,能夠直接在低精度下執行數學運算。例如,如果我們訓練模型在 8 位域中複製量化,則可以部署該模型對 8 位整數執行矩陣乘法和其他操作。
在諸如移動、嵌入式和物聯網裝置之類的資源受限的裝置上,使用 GEMMLOWP 等庫可以將 8 位操作提速 1.5 - 2 倍,這些庫依賴於硬體支援,如 ARM 處理器上的 Neon intrinsic。此外,Tensorflow Lite 等框架允許使用者直接使用量化操作,而不必為底層實現而煩惱。
除了剪枝和量化,還有其他一些技術,如低秩矩陣分解、K-Means 聚類、權值共享等等,這些技術在模型壓縮領域也十分活躍。
總的來說,壓縮技術可以用來減少模型的足跡(大小、延遲等),同時換取一些質量(準確性、精度、召回率等)的提升。
(1)蒸餾(Distillation):如前所述,學習技術嘗試以不同的方式訓練模型,以獲得最佳效能。例如,Hinton 等人在其開創性工作中探索瞭如何教會小型網路從大型網路 / 大型網路的集合中提取暗知識(dark knowledge| Hinton said: 「Dark knowledge is the most of what deep learning methods actually learn」)。他們使用一個更大的教師模型(teacher model)在現有標籤資料生成軟標籤。
軟標籤為原始資料中的每個可能的類別分配概率,而不是硬二進位制值。直覺上,這些軟標籤捕獲了模型可以學習的不同類之間的關係。例如,卡車更像汽車而非蘋果,這一模型可能無法直接從硬標籤中學習。學生網路(student network)學習最小化這些軟標籤的交叉熵損失(cross-entropy loss),以及原始真實的硬標籤。損失函數的每個權重可以根據實驗結果進行縮放。
Hinton 等人曾在論文中表示,能夠用一個蒸餾模型來接近 10 個模型整合的語音識別任務的準確性。其他綜合研究表明,小型模型質量有著顯著提高。簡單舉個例子,Sanh 等人能夠蒸餾一個學生模型,該模型保留了 BERT-Base 97% 的效能,同時在 CPU 上的佔用率要少 40%,而速度上快約 60%。
(2)資料增強(Data Augmentation):通常對於大型模型和複雜任務來說,擁有的資料越多,改進模型效能的機會就越大。然而,常常採用 「人在迴路」(human in the loop)的解決辦法,所以獲取高質量的標記資料通常既緩慢又昂貴。監督學習就是從這些人工標註的資料中學習。當有資源支付標註費用的時候,它非常有效,但我們能夠且應該做得更好。
資料增強主要指在計算機視覺領域中對影象進行資料增強,從而彌補訓練影象資料集不足,達到對訓練資料擴充的目的,進而提升模型的效能。通常,它涉及到對資料進行轉換,這樣就不需要重新標註,該過程成為標籤不變轉換(label-invariant transformations)。例如,如果您正在教神經網路對包含狗或貓的影象進行分類,旋轉影象將不會改變標籤。此外,其他的轉換形式還有水平 / 垂直翻轉、拉伸、裁剪、新增高斯噪聲等。類似地,如果您正在檢測給定文字的情感傾向性,引入拼寫錯誤可能不會改變標籤。
這種標籤不變轉換已經在流行的深度學習模型中廣泛使用。當您有大量的類和 / 或特定類的示例很少時,它們尤其方便。
還有其他轉換方式,如 Mixup,它以加權的方式混合來自兩個不同類的輸入,並將標籤視為兩個類的類似加權組合。其思想是,模型應該能夠提取出與這兩個類相關的特性。
這些技術將資料效率引入到 pipeline 中。這和教孩子在不同的上下文中識別現實生活中的物體實質上沒有太大的區別。
(3)自監督學習(Self-Supervised Learning):在鄰近的領域有了快速的進展,我們可以學習一些通用模型,這些模型完全不需要使用標註來從資料中提取意義。採用對比學習(contrastive learning)這樣的方法,我們可以訓練一個模型,使它學習輸入的表示,這樣類似的輸入將有類似的表示,而不相關的輸入會生成明顯差異的表示。其中,這些表示是 n 維向量(embeddings),在我們可能沒有足夠的資料來從頭訓練模型的其他任務中,它可以作為有用的特徵。我們可以把使用未標註資料的第一步看作是預訓練,下一步視為微調。
這種對未標註資料進行預訓練和對標註資料進行微調的兩步過程也迅速得到了 NLP 社群的認可。ULMFiT 率先提出了訓練通用語言模型的想法,該模型學習如何解決預測給定句子中的下一個單詞的任務。
我們發現,使用大量預處理但未標註的資料,如 WikiText-103(源自英文維基百科頁面),是預訓練步驟的一個不錯的選擇。這就足以讓模型學習語言的一般屬性。此外,對於二進位制分類問題,微調這種預訓練模型只需要 100 個標註示例,而相比之下,其他情況則需要 10000 個標註的示例。
該想法也在 BERT 模型中進行了探索,其中預訓練步驟涉及學習雙向掩碼語言模型(Masked Language Model),使得模型必須在句子中預測缺失的單詞。
總的來說,學習技術有助於我們在不影響足跡的情況下提高模型質量。這可以用於改進部署的模型質量。如果原始模型的質量令人滿意的話,你還可以通過簡單地減少網路中的參數數量來交換新獲得的質量收益,以改進模型大小和延遲,直到回到最低可行的模型質量。
有了正確的軟體、硬體和技術以後,有效地開發高效能模型的能力,現在取決於如何利用自動化來加速實驗過程,並構建最高效的資料模型架構。
如果讓自動化幫助網路設計和調優,它將大大減少人類的參與成本和隨之而來的偏見。然而,其隨之而來的代價是計算成本增加。
(1)超參數優化(Hyper-Parameter Optimization):屬於此類工作的常用方法之一是超參數優化(HPO, Hyper-Parameter Optimization)。調整超參數(如初始學習率,權值衰減等)對於加快收斂速度至關重要。當然,還有一些決定網路架構的參數,比如全連線層的數量,卷積層中的過濾器數量等等。雖然我們可以通過實驗建立直覺思維,但找到最佳超參數值需要手動搜尋能夠優化給定目標函數的準確值,往往是驗證集上的損失值。
如果使用者之前對超參數調優有經驗,那麼可以使用網格搜尋演算法(Grid Search,也稱為參數掃描)來自動化 HPO。在這種情況下,根據使用者提供的每個參數的有效範圍搜尋給定超參數的所有獨特且有效的組合。例如,如果學習率(lr, learning rate)的可能值為 {0.01,0.05},權重衰減(weight decay)的可能值為 {0.1,0.2},則有 4 種可能的組合:{lr=0.01, decay=0.1}、{lr=0.01, decay=0.2}、{lr=0.05, decay=0.1} 和 {lr=0.05, decay=0.2}。
以上每種組合都是一次試驗,然後每次試驗都可以並行運行。一旦所有試驗完成,超參數的最優組合便被找到。由於該方法會嘗試所有可能的組合,嘗試總數增長非常快,因此遭受維度的詛咒。
另一種方法是隨機搜尋(Random Search),其中從使用者提供的可能值範圍所構建的搜尋空間中進行隨機取樣試驗。類似於網格搜尋,每個試驗仍然是獨立並行運行。然而,鑑於試驗獨立同分布(iid, independently and identically distributed)的特點,隨機搜尋很容易根據可用的計算能力進行擴展,從而找到最優試驗的可能性隨著試驗次數的增加而增加。如果到目前為止最好的試驗足夠好,這就允許預先搜尋。整個超參搜尋的過程可視為一個在有限資源限制下的優化問題,在資源分配方面,類似於隨機搜尋的典型演算法有 SHA(succession Halving)和 HyperBand,可以把更多的資源分配給精度更高或者優化速度更快的演算法。
基於貝葉斯優化(BO, Bayesian Optimization)的搜尋是一種更好的調優方法,它保留了一個單獨的模型以用於預測給定的試驗是否有可能改進到目前為止發現的最佳試驗。該模型學會根據過去試驗的表現來預測可能性。BO 優於隨機搜尋,因為前者具有一定的導向性。因此,需要更少的試驗就可以達到最佳。由於試驗的選擇依賴於過去試驗的結果,因此該方法是順序的。然而,與純粹邏輯的 BO 相比,可以在同一時間並行地產生多個試驗(基於相同的估計),這可能引發更快的收斂,其代價可能是一些浪費的試驗。
在實際使用方面,HPO 可以通過幾個軟體工具包提供給使用者,這些工具包包括演算法本身以及一個易於使用的介面(指定超參數及其範圍),包括 Vizier [8](一個內部谷歌工具,也可以通過谷歌雲進行黑箱調優)。亞馬遜提供了 Sagemaker,其功能類似,也可以作為 AWS(Amazon Web Services)服務訪問。NNI、Tune 和 Advisor 是其他可以在本地使用的開源 HPO 軟體包。這些工具包為不樂觀的早期停止策略提供了一個選項。Vizier 使用中位數停止規則,如果一個試驗在時間步長 t 上的效能低於所有試驗運行到該時間點的中位數效能,則終止試驗。
(2)神經架構搜尋(NAS, Neural Architecture Search):可以把 NAS 看作是 HPO 的擴展版本,在其中搜索改變網路架構本身的參數。NAS 可考慮由以下部分組成:
丨搜尋空間(Search Space):卷積、全連線、池化等操作及其相互連線是圖中允許的神經網路操作。這都是由使用者提供的。
丨搜尋演算法和狀態(Search Algorithm & State):這是控制架構搜尋本身的演算法。通常,適用於 HPO 的標準演算法(網格搜尋、隨機搜尋、貝葉斯優化和進化演算法等)也同樣可用於 NAS,以及強化學習(Reinforcement Learning)和梯度下降(Gradient Descent)。
丨評估策略(Evaluation Strategy):這定義了用於評估模型適合的度量指標。它可以是簡單的常規度量,如驗證損失(validation loss)、準確性(accuracy)等;或者也可以是一個複合度量(compound metric),如 MNasNet,可以根據精度和模型延遲創建單一的定製度量指標。
具有搜尋空間和狀態的搜尋演算法可被視為生成樣本候選網路的 「控制器」。評估階段對生成的候選進行適合的訓練和評估,然後將這個適應值(fitness value)作為反饋傳遞給搜尋演算法,該演算法將使用它來生成更好的候選物件。
Zoph 等人在 2016 年發表的論文中證明,端到端神經網路架構可以通過強化學習生成。在這種情況下,控制器本身就是一個遞迴神經網路(RNN, Recurrent Neural Network),它一次生成一層前饋網路的架構超參數,如濾波器數量、步幅、濾波器大小等。訓練控制器本身很昂貴(需要 22400 個 GPU 小時),因為整個候選網路必須從頭開始訓練,才能實現單一的梯度更新。在後續論文中,作者改進了搜尋空間以搜尋單元(cells):一個 「正常單元」(Normal Cell),可以接收輸入,處理並返回相同空間維度的輸出。「縮減單元」(Reduction Cell)處理其輸入並返回其空間維度按比例縮小 2 倍的輸出。每個單元都是塊的組合。控制器的 RNN 每次生成一個塊,它選擇過去兩個塊的輸出,分別進行操作並將其組合為單個輸出。正常和縮減單元堆積以交替的方式堆疊,用於構建 CIFAR-10 和 ImageNet 的端到端網路。
與中的端到端網路搜尋相比,單獨學習這些單元而不是學習整個網路似乎可以將搜尋時間提高 7 倍,同時擊敗當時 CIFAR-10 的最先進的搜尋技術。
其他方法,如進化技術(evolutionary techniques)、可區分架構搜尋(differentiable architecture search)、漸進式搜尋(progressive search)、,參數共享(parameter sharing)等,這些方法的共同之處在於試圖降低架構搜尋的成本。
在評估候選網路時,不僅要關注質量,還要關注模型大小、延遲等記憶體佔用指標。架構搜尋可以輔助實現多目標搜尋和優化。例如,MNasNet 將模型在目標移動裝置上的延遲直接合併到目標函數中,如下所示:
其中,是候選模型,是準確率指標,給定模型在裝置上的延遲,表示目標延遲。的取值建議設為0.07。
概括來說,自動化對模型的效率起著至關重要的作用。HPO 現在是訓練模型的自然步驟,可以提取顯著的質量改進,同時最大限度地減少人工參與。而且 HPO 也可以在獨立的軟體庫以及雲服務中使用。類似地,NAS 的最新進展也使得以學習的方式構建體系結構成為可能,同時對質量和記憶體空間都有限制。假設 NAS 運行完成需要 GPU 的運行時長達數百小時,並且在領先的雲端計算服務上,GPU 每小時的成本約為 3 美元,這使得使用 NAS 方法完全經濟可行,並且在針對多個目標進行優化時,成本上與模型體系結構的手動實驗不同。
另一個常見主題是重新設計比基線更好的高效層和模型,這些層和模型可以用於特定任務或作為一般的黑盒。
(1)視覺(Vision):視覺領域中高效層的經典示例之一是使用了卷積層,它改進了視覺模型中的全連線(FC, Fully Connected)層。不過,FC 層存在兩個主要問題:
丨 FC 層忽略輸入畫素的空間資訊。直觀地說,很難通過孤立地觀察單個畫素值來構建對給定輸入的理解。此外,還忽略了鄰域的空間局部性。
丨使用 FC 層還會在處理中等大小的輸入時導致參數數量的激增。一個 100 × 100 的 RGB 影象有 3 個通道,第一層的每個神經元有 3 × 104 個連線,這使得網路也容易過度擬合(overfitting)。
卷積層通過學習過濾器來避免這種情況,每個過濾器都是固定大小的 3D 權重矩陣(33, 55 等),第三維與輸入通道的數量相同。每個過濾器都對輸入進行卷積操作,生成給定過濾器的特徵對映。每個過濾器都可以學習檢測邊緣等特徵(水平、垂直、對角線等),從而在特徵對映中發現該特徵存在的更高值。總的來說,單個卷積層的特徵對映可以從影象中提取有意義的資訊。堆疊在上面的卷積層將使用前一層生成的特徵對映作為輸入,逐步學習更復雜的特徵。
卷積層效率背後的核心思想是,在影象的任何位置都使用相同的過濾器,不論應用在哪。讓我們再回到帶 3 個通道的 100×100 RGB 影象的例子,5 × 5 濾波器意味著總共有 75 個(5 × 5 × 3)參數。每一層都可以學習多個獨特的過濾器,並且仍處在非常合理的參數預算之內。這還具有正則化的效果,其中參數數量的顯著減少,可以更容易的優化和更好的泛化。
丨 用 1 x 1 個過濾器進行逐點卷積(point-wise convolution),這樣得到的特徵對映現在達到 output_channels 的深度。
這兩種操作堆疊在一起(有任何中間非線性啟用)會得到與常規卷積相同形狀的輸出,但參數要少得多。類似地,計算量減少了一個數量級,因為逐點卷積對每個輸入通道的深度卷積要便宜得多。Xception 模型架構演示了在 Inception 體系結構中使用深度可分離卷積,允許在保持參數數量相同的情況下,實現更快地收斂,並在 ImageNet 資料集上獲取更高的精度。
MobileNet 模型架構是為移動和嵌入式裝置設計的,它也使用深度可分離層而不是常規的卷積層。這有助於減少 7-10 倍的參數數量和乘法運算,並允許在移動端部署計算機視覺(CV, Computer Vision)任務。使用者可以預期 10-100 毫秒之間的延遲,只不過具體還得取決於模型。MobileNet 還通過深度倍增器(depth multiplier)提供了一個旋鈕(knob),用於擴展網路,使使用者能夠在準確性和延遲之間進行權衡。
(3)注意力機制(Attention Mechanism):在自然語言方面,我們也看到了快速的進步。對於序列到序列(sequence-to-sequence)模型,一個持久存在的問題是資訊瓶頸(information-bottleneck)。這些模型通常由編碼器(Encoder)和解碼器(Decoder)構成。其中,編碼器對應輸入序列,負責將資訊編碼到上下文向量中;而解碼器對應輸出序列,響應生成上下文的輸出序列。這類任務的一個典型例子是機器翻譯,其中輸入序列是源語言中的句子,輸出序列是目標語言中的句子。
傳統的做法是在編碼器和解碼器中都使用 RNN。然而,第一個解碼器層只能看到最終編碼器步驟的隱藏狀態。這就造成了一種 「瓶頸」,因為解碼器的第一步必須從最終隱藏狀態中提取所有資訊。
Bahdanau 等人最初在機器翻譯中引入了注意力機制,使解碼器能夠看到編碼器的所有狀態,目前已成為神經網路結構的重要組成部分。這是一種根據序列與另一向量(即 query vector)的相似性來突出輸入序列的相關部分並將輸入序列壓縮為上下文向量的方法。在機器翻譯等序列到序列任務中,這允許基於所有編碼器狀態(表示為 keys 和 values)和解碼器以前的隱藏狀態(query vector)來裁剪(tailoring)解碼器的輸入。上下文向量是基於解碼器先前隱藏狀態的編碼器狀態的加權和。由於 Attention 創建了編碼器狀態的加權和,因此權重也可以用於視覺化網路的行為。
(4)Transformer & Friends:Transformer 架構是 Google 於 2017 年在釋出的經典文章 「Attention is all you need」 中提出,該模型致力於解決 sequence to sequence 問題,掀起了對解碼器和編碼器的重點關注。在編碼器中,它們採用自注意機制(self-attention),其中鍵、值和查詢向量都是從前面的編碼器層派生而來。更重要的是,Transformer 網路的訓練成本比可與之媲美的替代方案要低兩個數量級。
另一個核心思想是,self-attention 允許並行化獲取輸入序列中 tokens 之間關係的過程。RNN 固有地迫使過程一步一步地發生。例如,在 RNN 中,token 的上下文可能只有在處理了整個序列之後才能完全理解。而有了注意力,所有的 tokens 都被一起處理,並且可以學習成對的關係。這就使得利用優化的訓練裝置(如 GPUs 和 TPUs)變得更容易。
正如在上文所介紹的,BERT 模型架構在幾個 NLU 基準測試中擊敗了最先進的水平。BERT 的網路架構使用的就是多層的 Transformer 結構,通過注意力機制有效的解決了 NLP 中棘手的長期依賴問題,更徹底的捕捉語句中的雙向關係。當然,它也可以用作通用編碼器,更好地處理其他任務。與之相類似的模型,如 GPT 家族也在許多 NLU 任務上得到了廣泛的應用。
在介紹完上述的四個重點領域(壓縮技術、學習方法、自動化和高效架構)之後,本文將以對訓練和部署高效能模型至關重要的基礎設施簡介作為結束。
為了能夠有效地訓練和運行推理,必須有強大的軟體和硬體基礎設施基礎。
Tensorflow (TF) 是一種流行的機器學習框架,已被許多大型企業用於實際的生產過程。它為模型效率提供了最廣泛的軟體支援。
Tensorflow Lite for On-Device Use Cases:Tensorflow Lite (TFLite) 是一組工具和庫,旨在用於邊緣裝置等低資源環境中的推理。
TensorflowJS (TF.JS) 是 TF 生態系統中的一個庫,可用於在瀏覽器中或使用 Node.js 訓練和運行神經網路。這些模型也可以通過 WebGL 介面通過 GPU 加速 。它既支援匯入在 TF 中訓練的模型,也支援在 TF.JS 中從頭開始創建新模型。還有 TF 模型優化工具包 ,它提供在模型圖中新增量化、稀疏性、權重聚類等。
用於伺服器端加速的 XLA:XLA(加速線性代數)是一種圖形編譯器,它可以通過為圖形定製的操作(核心)生成新的實現來優化模型中的線性代數計算。
PyTorch 是學術界和工業界都在使用的另一個流行的機器學習平臺,它在可用性和功能方面可以與 Tensorflow 相媲美。
裝置上用例:PyTorch 還具有一個輕量級直譯器,可以在移動裝置上運行 PyTorch 模型。PyTorch 還提供訓練後量化和其他圖優化。
通用模型優化:PyTorch 提供了即時 (JIT) 編譯工具,用於從 TorchScript 中的程式碼生成模型的可序列化中間表示,TorchScript 是 Python 的一個子集,並添加了類型等功能 - 檢查。它幫助在用於研究和開發的靈活 PyTorch 程式碼與可部署用於生產推理的表示之間建立橋樑。這是在移動裝置上執行 PyTorch 模型的主要方式。
PyTorch 中 ,XLA 的替代品似乎是 Glow 和 TensorComprehension 編譯器。它們有助於生成從更高級別的 IR(如 TorchScript)派生的較低級別的中間表示 (IR)。
PyTorch 還提供了一個模型調整指南,其中詳細介紹了 ML 從業者可以使用的各種方法。其中的一些核心思想是:
丨使用 PyTorch JIT 融合逐點運算(加、減、乘、除等)。
丨啟用緩衝區檢查點允許僅將某些層的輸出保留在記憶體中,並在向後傳遞期間計算其餘層。這特別有助於廉價計算具有大輸出(如啟用)的層。
丨啟用特定於裝置的優化,例如 cuDNN 庫和使用 NVIDIA GPU 的混合精度訓練(在 GPU 小節中解釋)。
丨 Train with Distributed Data Parallel Training,適用於資料量大,有多個 GPU 進行訓練的情況。
可以通過優化運行神經網路的硬體的軟體堆棧來進一步提高效率。例如,ARM 的 Cortex 系列處理器支援 SIMD(單指令多資料)指令,該指令允許使用 Neon 指令集對操作(處理批量資料)進行向量化。QNNPACK 和 XNNPACK 庫針對移動和嵌入式裝置的 ARM Neon 以及 x86 SSE2、AVX 架構等進行了優化。前者用於 PyTorch 的量化推理模式,後者支援 32 位浮點 - 點模型和 TFLite 的 16 位浮點。同樣,還有其他低階庫,如 Accelerate for iOS 和 NNAPI for Android,它們試圖從更高級別的 ML 框架中抽象出硬體級加速決策。
GPU:圖形處理單元 (GPU) 雖然最初設計用於加速計算機圖形,但在 2007 年之後, CUDA 庫的可用性擴大。AlexNet 在 2012 年贏得了 ImageNet 競賽標準化 GPU 在深度學習模型中的使用。從那以後,英偉達釋出了多次迭代的 GPU 微架構,越來越關注深度學習效能。它還引入了 Tensor Cores,這是一種專用的執行單元,支援一系列精度(fp32、TensorFloat32、fp16、bfloat16、int8、int4)的訓練和推理。
降低精度乘法累加 (MAC) 操作:B x C 是一項昂貴的操作,因此它以降低的精度完成。
Tensor Cores 優化了標準的乘法累加 (MAC) 操作,A = (B × C) + D。其中,B 和 C 的精度降低(fp16、bfloat16、TensorFloat32),而 A 和 D 的精度為 fp32 . 根據模型架構和所選 GPU,NVIDIA 報告稱,通過這種降低精度的 MAC 操作,訓練速度提高了 1 到 15 倍。
NVIDIA 最新的 Ampere 架構 GPU 中的 Tensor Cores 還支援更快的稀疏推理。他們展示了推理時間高達 1.5 倍的加速,以及單個層高達 1.8 倍的加速。除此之外,NVidia 還提供了 cuDNN 庫 ,其中包含標準神經網路操作的優化版本,例如完全連線、卷積、啟用等等。
在 GPU 和 TPU 上訓練和推理期間使用的資料類型。bfloat16 起源於 TPU,僅 NVidia GPU 支援 Tensor Float 32。
TPU:TPU 是專用積體電路 (ASIC),由谷歌設計用於使用 Tensorflow 加速深度學習應用程式,並經過微調以並行化和加速線性代數運算。TPU 架構支援使用 TPU 進行訓練和推理,並可通過其 Google Cloud 服務向公眾開放。
TPU 晶片的核心架構利用了 Systolic Array 設計,其中將大量計算拆分為網狀拓撲,每個單元計算部分結果並將其按順序傳遞給下一個單元,每個時鐘 - step(以類似於心臟收縮節律的有節奏方式),無需將中間結果儲存在記憶體中。
每個 TPU 晶片有兩個 Tensor Cores,每個都有一個脈動陣列網格。一塊 TPU 板上有 4 個相互連線的 TPU 晶片。為了進一步擴展訓練和推理,可以在網狀拓撲中連線更多數量的 TPU 板以形成 「pod」。根據公開發布的數字,每個 TPU 晶片 (v3) 可以達到 420 teraflops,而一個 TPU pod 可以達到 100+ petaflops。TPU 已在 Google 內部用於諸如 Google 搜尋訓練模型、通用 BERT 模型、DeepMind 的 AlphaGo 和 AlphaZero 等應用。與 GPU 類似,TPU 支援 bfloat16 資料類型,這是一種以全浮點 32 位精度訓練的低精度替代方案。
EdgeTPU 也是谷歌設計的定製 ASIC 晶片。與 TPU 類似,它專門用於加速線性代數運算,但僅用於推理,並且在邊緣裝置上的計算預算要低得多。它進一步僅限於操作的子集,並且僅適用於 int8 量化 Tensorflow Lite 模型。EdgeTPU 晶片本身比 1 美分硬幣還小,因此適合部署在多種物聯網裝置中。它已部署在類似 Raspberry Pi 的開發板中,在 Pixel 4 智慧手機中作為 Pixel Neural Core,也可以獨立焊接到 PCB 上。
Jetson:Jetson 是 Nvidia 的一系列加速器,用於為嵌入式和物聯網裝置啟用深度學習應用程式。它包括 Nano,這是一個為輕量級部署而設計的低功耗 「模組系統」(SoM),以及更強大的 Xavier 和 TX 變體,它們基於 NVidia Volta 和 Pascal GPU 架構。Nano 適用於家庭自動化等應用,其餘適用於工業機器人等計算密集型應用。