當前位置:
首頁 > 新聞 > Facebook新研究優化硬體浮點運算,強化AI模型運行速率

Facebook新研究優化硬體浮點運算,強化AI模型運行速率

選自code.fb,作者:JEFF JOHNSON,機器之心編譯,參與:Geek AI、路。


近日,Facebook 發布文章,介紹了一項新研究,該研究提出了一種使人工智慧模型高效運行的方法,從根本上優化了浮點運算。

近年來,計算密集型的人工智慧任務推動了各種用於高效運行這些強大的新型系統的定製化硬體的出現。我們採用浮點運算來訓練深度學習模型,如 ResNet-50 卷積神經網路。但是,由於浮點數十分消耗資源,真正部署的人工智慧系統通常依賴於使用 int8/32 數學運算的少數幾個流行的整型量化技術。

Facebook 開發了一種使人工智慧模型高效運行的方法。基於 70 多年前計算機科學發展初期的思想,該方法從根本上優化了浮點運算。

Facebook 對浮點數進行了徹底的改造,使它比 int8/32 數學運算的效率高出 16%。該方法用於卷積神經網路時,網路仍能達到很高的準確率,此外它還具備以下優勢:

  • 該技術可以提高人工智慧研發的速度。當該方法被應用於人工智慧模型訓練中使用的更高精度的浮點數時,模型訓練的效率能夠提高 69%。
  • 如今,模型通常使用浮點數進行訓練,但是之後它們必須轉換成更高效的、可以部署到生產環境中的量化格式。如果使用該方法,在部署模型時就不需要重新訓練或重新學習。這樣一來,人工智慧開發者就可以更容易地部署高效的新模型。
  • 現在的整型量化方法正變得越來越複雜。在某些情況下,這些方法可能對某些特定任務「過擬合」(因此不能維持通用性)。高效的通用浮點運算可以在保持準確率的情況下避免過擬合問題。

論文「Rethinking float point for deep learning」詳細介紹了 Facebook 的這項技術。開發使用這些新技術執行浮點運算的新晶元需要耗費一定的時間。但這樣做可能得到的好處包括使數據中心的人工智慧計算速度更快,在移動設備上獲得更好的人工智慧運算性能的低功耗設計,以及在進行較少的軟體更改的情況下以更簡單、迅速的方法達到性能目標。摩爾定律正在逐漸減速,而「暗硅」(dark silicon)時代即將到來。持續的性能提升需要重新考慮幾十年前的底層硬體設計決策(比如 IEEE 754 浮點標準),以及在合適的情況下使用數學近似(mathematical approximation)。尤其是神經網路的出現成為對它們進行重新評估的絕佳契機,因為神經網路對數值運算的變化和實驗具有相當大的容忍度。

Facebook 為 ASIC/FPGA 做出的硬體設計和為評估編寫的 C++/PyTorch 代碼已經向人工智慧社區開放。

地址:http://github.com/facebookresearch/deepfloat

傳統的浮點運算

眾所周知,浮點數可以在合理的計算機存儲空間中表示大小實數,其使用的系統與科學計數法大體相似。這種格式可用於以固定寬度的編碼和基數(通常是二進位)表示 1,000,000 和 0.0625 這樣的值。需要注意的是,浮點數只能精確地表示有限的實數,因為我們擁有的比特位數是有限的。所有其他值都可以用一種四捨五入的形式表示為最接近的可以表示出來的浮點值。

傳統的二進位浮點格式包含符號(sign)、尾數(significand)和指數(exponent)。符號位表示數字是正的還是負的。尾數(其小數部分通常稱為尾數)是形如 0.bbb... 或 1.bbb... 的二進位定點數,其中小數部分 bbb… 由若干二進位位在基數點之後表示的。(在十進位運算中,基數點也稱為小數點,將整數與小數部分分開。)指數是一個有符號整數,它表示尾數需要乘以 2 的多少次冪。尾數有前導二進位 1(1.bbb…)的情況是規格化的,而尾數有前導二進位 0(0.bbb…)的情況是非規格化的(二者可以相互轉化)。現代計算機中常用的 IEEE 754 浮點標準有規格化和非規格化兩種尾數表示方法。尾數的前導位不需要被顯式存儲;在 IEEE 754 中,指數域決定前導位是 1 還是 0。

下圖顯示了以 16 位 IEEE 754 的 binary16 半精度浮點數對 -1.625 進行的編碼,它具有固定大小的 5 位指數和 10 位的尾數部分。IEEE 指數的偏置值為 -15,因此下面編碼的指數 15 實際上表示(15-15)即 0。

Facebook新研究優化硬體浮點運算,強化AI模型運行速率

人工智慧運算的現狀和未來

為許多人工智慧系統賦能的神經網路通常使用 32 位 IEEE 754 binary32 單精度浮點數進行訓練。將位數降低到 16 位(半精度浮點數或類似 bfloat16 的格式)會獲得一定的性能提升,但與同樣位寬整數運算的效率相比,它仍然相形見絀。這些浮點變數可以很容易地使用原來的 32 位浮點神經網路數據,但要將整數量化到 8 位(或更少)常常需要學習量化參數並對模型進行再訓練。許多 int8/32 量化方案可以像原始的浮點模型達到同樣的準確率,但是它們也可能在處理任務時發生過擬合現象,從而無法在 ImageNet 驗證集以外的任務上保證其準確率。

但是對於今天的計算機運算來說,除了整數、定點或浮點運算外,還有許多其他的選擇。其中一些方法可以追溯到 20 世紀 50 年代:

  • 非線性尾數映射
  • 二進位隨機數
  • 熵編碼

Facebook 使用這一思路創造出了一種浮點運算,其性能超過 int8/32。該方法的實現與目前硬體中的浮點運算及其變體(如非規格化的清零行為或字大小/欄位位寬度變化,如 bfloat16 或 minifloat)有很大的區別。與 int8/32 量化不同的是,該實現仍然是一種通用的浮點運算,可以直接對其運算結果進行解釋。

實現更高效浮點運算的關鍵

為了開發一種高效浮點運算的新方法,Facebook 研究人員認真分析了硬體浮點數低效的各種原因:

  1. 字(word)大小過大:有很大一部分算力被用於移動數據:從外部的 DRAM 到內部的 SRAM,從 SRAM 到寄存器,或從寄存器到寄存器(觸發器)。浮點的字大小越大,消耗的算力就越多。
  2. 通用的定點數機制:尾數是定點數,定點數的加法器、乘法器和除法器是算術運算所必需的。浮點類型的精度(尾數長度)越高,這些組件就越大。硬體乘法器和除法器通常比硬體加法器更消耗資源(晶元面積、功耗和延遲)。
  3. 通用的浮點數機制:該機制處理基數點的「浮點」,因此是浮點表示法的一部分。例如,用於重新規格化的前導零(LZ)計數器、用於尾數對齊的移位器和舍入邏輯。浮點精度也對該機制所使用的硬體資源有很大的影響。
  4. IEEE 754 的專有機制:這為 IEEE 754 標準中實現的逐漸下溢提供了非規格化的支持,並提供了額外的移位器、LZ 計數器和尾數重新規格化所需要的其他修改。非規格化的處理增加了大多數浮點操作的複雜性和計算開銷。

減小字大小

縮小字(word)的大小可以顯著地提升算力的利用率。我們可以嘗試將 32 位數據壓縮為 8 位或 16 位。典型的浮點數固定大小欄位編碼迫使我們做出困難的選擇,是減少動態範圍(指數)還是減小精度(尾數),而我們需要的是二者的折中。

我們可以用不同的方式來處理這種權衡。浮點數本身就是(無限精度)實數的量化形式。適用於見過的數據分布的量化器在數據複製的過程中誤差會較小。對於在通用計算機上遇到的數據分布,我們通常沒有太多的先驗知識。然而,神經網路的分布在實際中是接近高斯分布的,有時還會受到批歸一化等過程的控制。標準浮點數儘可能保證尾數在 10^-5 的精度與在 10^5 的精度相當,但大多數神經網路在一個相對較小的範圍內(如 -10.0 到 10.00)執行計算。這個範圍內的小數字(例如 0.0001)會被頻繁使用,而大數字的使用頻率較低。理想情況下,我們可以改變數化器,在需要的地方提供更高的精度,並保持一定的小數字動態範圍。

縮減(tapered)浮點數可以幫助實現這些目標並減小字的大小。Gustafson 提出的 Posit 方法是一種效果很好的縮減形式。Posit 使用無前綴編碼將指數編碼為可變位數,其餘部分為尾數。它在+/-1.0 左右將精度最大化,而在 0 或+/-∞ 處的精度則較低。它的壓縮和擴展都是有損的,以損失某些地方的精度為代價來保證在其他地方的動態範圍。因此,與 IEEE 風格的浮點數相比,它可以提供更高的精度(在某些地方)和更大的動態範圍。當我們不知道待處理數據的數據分布時,posit 可以擴展到其他無前綴編碼中(比如霍夫曼編碼)。

定點數機制

我們可以設法避免在尾數上進行的乘法和除法運算。尾數可以被看作是小數部分的映射 f(x),它將取值範圍在 [0, 1) 間的定點數 x 映射到 [1, 2) 中。(這種方法在 Lindstrom 等人 2018 年的論文《Universal Coding of the Reals: Alternatives to IEEE Floating Point》中有詳細的介紹。)在典型的規格化浮點運算中,f(x) 是仿射函數 1+x(我們稱之為線性域數)。

當 f(x) = 2^x 時,我們可以使用對數數字系統(LNS)將乘法和除法變成加法和減法。不過,添加 LNS 需要大量的硬體查找表來計算兩個對數域數的和或差。這是採用 LNS 的一個主要問題,因為這些表可能比硬體乘法器更難以處理。注意,典型的浮點數已經是對數(指數)和線性(尾數)表示的組合,但是 LNS 表示完全是基於對數的。

浮點數機制

在計算機線性代數中,有效的操作是「乘加」:計算值「c」和 a 與 b 乘積「a x b」的和,得到「c + a x b」。通常情況下,對於 ResNet-50 等模型,單個累加器中可能會對數千個這樣的乘積求和;在部署過程中運行一個模型時涉及數百萬獨立累加操作,而訓練模型時則需要進行數以億計的累加操作。

浮點融合乘加(FMA)是一種常見的乘加方法,它能夠減小誤差,但它比標準的浮點加法器或乘法器複雜得多。一種稱為 Kulisch 累加的技術可以避免 FMA 的複雜操作。類似的操作在第一台可編程數字計算機 Konrad Zuse Z3 上被採用過。Gustafson 也在他最近的浮點研究中提出了 Kulisch 累加的標準用法(https://www.crcpress.com/The-End-of-Error-Unum-Computing/Gustafson/p/book/9781482239867)。其思想不是在浮點運算中進行累加,而是在定點運算中維護一個運行時的和(running sum),這個和需要足夠大以避免下溢或溢出。與浮點加法不同的是,Kulisch 累加可以精確地表示任意數量的浮點值的和。不論順序如何,求和方法都是滿足結合率並可復現的。在完成所有求和工作之後,我們通過尾數對齊和舍入將其轉換回浮點數。

下圖顯示了一個累加步驟的示例。Kulisch 累加器當前包含值 35.5,我們將其與 0.84375 相加,表示為線性域浮點值。這個被求和的浮點值可能以前來自於標量值的乘積,或者只是我們希望累加的單個值。在浮點指數的基礎上,通過對齊尾數的基數點,將浮點數轉換為定點數。該轉換使用了一個調整因子,它是累加器最多尾數位(在下面的例子中是 6)的有效指數。然後將對齊後的尾數和累加器與進位相加。(為簡單起見,此處省略了 Kulisch 累加器可能支持下溢和溢出所需的額外精度位)。在高於 32 位的浮點數中,Kulisch 累加的代價很高,因為累加器、移位器和加法器的大小可能大於 500 位,但是對於較小的浮點類型來說,它是非常實用的。

Facebook新研究優化硬體浮點運算,強化AI模型運行速率

Kulisch 累加不能直接用於對數域求和。但是,正如 Kulisch 累加以不同於參數(浮點數)的形式(定點數)執行求和運算一樣,這裡也可以採用類似的方法,因此我們不需要一個巨大的 LNS 和/差查找表。我們可以在線性域中對 log 值取近似,在線性域中做 Kulisch 累加,然後在所有求和工作都完成時將其轉換回 log 域。這種方法對於通用線性代數非常有效,因為向量內積需要在累加器中多次重複求和。

IEEE 754 的專有機制

有助於減小字大小的 posit 編碼也避免了這個問題,因為 posit 的尾數總是規格化的。緩慢的下溢立刻防止了精度下降,而不是逐漸緩解精度下降,這在 IEEE 754 非規格化表示中是通過尾數部分中前導一的位置解決的。Posit 逐漸減小到更小的數字上,導致在指數上使用尾數部分的位,從而擴展了動態範圍並降低了精度。Posit 的縮減(taper)技術在功能上類似於非規格化的逐漸下溢,但是沒有重新規格化尾數的開銷。Posit 緩慢溢出也以類似的方式支持縮減。

融合這些方法

為了獲得性能的提升,研究人員考慮將這四種技術結合起來。對數域表示避免了硬體乘法器,我們將 posit 用於對數。為了與 int8/32 抗衡,研究人員考慮使用一種稱為 (8, 1, alpha, beta, gamma) 對數的 8-bit 格式,其中 (8,1) 是 posit 參數。這種編碼在最大和最小正值之間提供了超過 1600 萬:1 的比率,同時在 1.0 左右保留了 4 位(對數域)精度,所有這些都是用 8 位表示的(只有 256 個可能的值)。alpha、beta 和 gamma 值可以控制對數到線性以及線性到對數的轉換準確率。

Facebook新研究優化硬體浮點運算,強化AI模型運行速率

如上所述,我們在線性域中執行對數域的求和。這個結果是非常近似的,但與 FMA 不同的是,對於序列和,這裡沒有 Kulisch 累加的線性域誤差。我們稱這種技術為 ELMA,或精確的對數線性乘加。對數域乘法是精確的,所有的線性域求和過程也都是精確的,但是對數到線性的轉換是近似的,返回的線性到對數的轉換也是近似的。這種折中在實踐中是可以接受的。

Facebook新研究優化硬體浮點運算,強化AI模型運行速率

硬體查找表用於轉換,但它們要比 LNS 加法所需表小得多。使用更大的 alpha、beta 和 gamma 參數會得到更精確的結果,但也會消耗更多的晶元面積和功耗。與浮點型 FMA 相比,ELMA 乘加電路及其核心更加簡單。它使用三個加法器、一個查找表和一個移位器就完成了大部分工作:

Facebook新研究優化硬體浮點運算,強化AI模型運行速率

直接替代方法

與 int8/32 不同,Facebook 研究人員針對神經網路的 8 位對數格式不需要學習量化參數、激活採樣或對原始網路進行再訓練。只需要獲取網路(如 ResNet-50)的 32 位浮點參數,然後使用「取與該參數最近的偶數」的規則對其進行轉換。使用 posit 編碼可以在如此小的類型中保證所需的動態範圍和精度。

使用 ELMA 的 (8, 1, 5, 5, 7) 對數與原始的 ResNet-50 的運算方法相同,在 ImageNet 驗證集上獲得了 75.23% 的 top-1 準確率和 92.66% 的 top-5 準確率,分別比原始網路的準確率降低了 0.9% 和 0.2%。這些結果與許多現有的 int8/32 量化方法類似。在 int8/32 量化中使用的調優訓練和模型調整可以進一步提高該方法的性能,但是這裡基線的結果是在對軟體進行最少修改的情況下實現的。所有的數學仍然在通用浮點運算中執行,使用壓縮編碼作為量化器。ELMA 設計也可以被用於非線性代數任務(如多項式計算)。

硬體效率

研究人員使用一種商用 28 納米 ASIC 工藝技術將 (8, 1, 5, 5, 7) 對數的 ELMA 以 int8/32 乘加 0.96 倍的功耗作用於獨立的處理單元(PE)。在一個完整的 32×32 矩陣乘法的脈動陣列中,使用對數 ELMA 處理單元方案的功耗是使用 int8/32 處理單元版本的 0.865 倍。該方案之所以能夠省電主要是因為取消了硬體乘法器。

擴展到 16 位後,即使沒有非規格化的支持(這在很大程度上降低了 IEEE 754 的效率),這種方法使用的功耗是 IEEE 754 半精度 FMA 的 0.59 倍,而使用的晶元面積是後者的 0.68 倍,同時還降低了延遲。得益於這些 16 位浮點數上的性能提升,我們可以在相同的時間內支持更複雜的人工智慧模型的訓練。然而,與 32 位的 IEEE 754 單精度 FMA 相比,ELMA 並沒有更加有效,這是由於 Kulisch 累加器過於龐大(增加了加法器/移位器尺寸和觸發器功率),而且禁止使用從對數到線性的查找表。

未來的工作

實現人工智慧技術的極大發展需要計算效率的顯著提高,而這隻有通過新方法才能實現,而不僅僅是建立在舊方法的基礎上。例如,軟體模擬工作常常很慢,無法有效地在前沿的人工智慧模型上測試新的運算方法。不幸的是,在 FPGA/ASIC 硬體上進行實驗比在軟體上還要困難得多,這使得這些潛在的提升空間在很大程度上沒有得到充分的開發。然而,如果開發出利用這些技術的新硬體,它將有利於廣泛的人工智慧研究和應用。

Facebook 計劃研究硬體上的 16 位 ELMA 的設計,並將其在人工智慧模型訓練和其他任務上的性能表現與 IEEE 754 半精度浮點數和 bfloat16 進行對比。這些新想法和數值近似方法並不總是適用的,但是人工智慧提供了一個獨特的機會來探索它們的邊界,並幫助推翻人們關於硬體可能完成的任務的舊有看法。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

來勢洶洶PyTorch!ICLR論文提及頻率直追TensorFlow
Kaggle Grandmaster是怎樣煉成的

TAG:機器之心 |