算法(“燃料”):大多數深度學習算法在基本形式上自20世紀80年代以來就已存在,如深度神經網絡、卷積網絡和使用隨機梯度下降和反向傳播進行訓練的方法。
數據(“空氣”):大型標記數據集一直存在,特別是對于無監督學習所需的數據。對于監督學習,像Pascal和ImageNet這樣的大型標記數據集自2000年代初就已存在。
計算(“火花”):點燃算法和數據需要足夠的計算能力,即在合理的時間內,使用足夠多的數據來訓練一個足夠大的模型。
當前人工智能的復興,包括生成式AI如ChatGPT在內,可歸因于深度學習的進步。基于深度學習的系統如今在語音識別、物體分類以及諸如象棋等游戲中的表現已經超越了人類能力。
深度學習的成功得益于強大且高效的計算硬件。盡管深度學習的算法自上世紀80年代就存在,但直到最近十年,隨著強大GPU的問世,這項技術才變得實用。深度學習的進展現在受到硬件性能的限制。在過去的十年中,GPU上深度學習推理的效率提高了1000倍。其中很大一部分增益歸功于數據表示的改進,從Kepler一代GPU的FP32開始,并在Hopper一代中擴展到Int8和FP8。
本次演講將回顧這一歷史,并討論數字表示的進一步改進,包括對數表示、最佳剪裁和每向量量化。
簡介:
Bill Dally于2009年1月加入NVIDIA擔任首席科學家,此前在斯坦福大學任職12年,擔任計算機科學系主任。Dally及其斯坦福團隊開發了系統架構、網絡架構、信號傳輸、路由和同步技術,在今天的大多數大型并行計算機中都可以找到。Dally此前曾在麻省理工學院從事研究,從1986年到1997年,在那里他和他的團隊建造了J-Machine和M-Machine,這是實驗性的并行計算機系統,開創了機制與編程模型的分離,并展示了非常低的開銷同步和通信機制。
從1983年到1986年,他在加州理工學院(CalTech)設計了MOSSIM模擬引擎和Torus路由芯片,開創了“蟲洞”路由和虛擬通道流控制。他是美國國家工程院的院士,美國藝術與科學學院的院士,IEEE和ACM的會士,并獲得了ACM Eckert-Mauchly獎,IEEE Seymour Cray獎和ACM Maurice Wilkes獎。他發表了250多篇論文,擁有120多項授予的專利,并是四本教科書的作者。Dally獲得了弗吉尼亞理工大學電氣工程學士學位,斯坦福大學電氣工程碩士學位和加州理工學院計算機科學博士學位。他曾是Velio Communications和Stream Processors的聯合創始人。
-----
現在,身為一名計算機架構師,致力于深度學習,這確實是一個令人心潮澎湃的時刻。
我將嘗試與大家分享一些事情。就像現在的大多數人一樣,當我準備這場演講時,我首先讓ChatGPT為我草擬了一份講稿。因此,這就是演講的初稿。
那么,如何構建一個關于深度學習硬件的演講呢?這讓我相當困惑。于是我說,好吧,這不行。一切都得依靠工程指導。我不得不思考,Bill Dally可能會對深度學習硬件有何見解。這或許是一個合理的演講主題,但并非我所要探討的內容。然而,我覺得這個想法很有趣。
如果你想更深入地了解——我總是喜歡在演講中穿插一些最新的資料——這是昨天《華爾街日報》上的一篇文章,是我與該報記者進行的一次訪談,內容關于我們如何繼續推動深度學習的發展。這確實是本次演講的核心議題。但我會比記者更深入地探討一些技術細節。
順便一提,這是我們的Grace Hopper超級芯片的照片。左邊是H100 GPU,右邊是Hopper多核CPU。實際上,它們的結合非常出色,盡管我作為一名并行計算的信徒,這款CPU的主要目的是為GPU提供更多的高帶寬內存。它是一個出色的內存控制器。
當我們研究像現在每個人都在使用的大型語言模型這樣的技術時,我認為,他們真正在做的是將數據提煉成價值,這確實是——計算機科學的主要目標之一。
我們通常從大量數據出發。人們往往會利用他們可以從互聯網上搜集到的所有信息來訓練這些模型。這些數據集包含高達10的12次方個token——一個token大致相當于一個單詞——當通過分詞器處理它時,通常會得到1.5到2個token對應一個單詞的比例——以及可能達到十億級別的圖像數量。這就是數據集規模。我們希望從中提取價值。這種價值體現在能夠回答問題、提升工作效率,比如通過擁有教學助手來幫助老師給予學生更多個性化關注,或者輔助醫生做出更準確的診斷。大型語言模型正廣泛應用于這些領域。
思考這個問題的方式就像是在考慮如何將學生送入大學。這就是你擁有萬億級別token數據集的意義所在。實際上,我之前做過類似的幻燈片。現在,大型模型的訓練已經涉及10萬億甚至更多的token。對于萬億token數據集,需要在AWS上投入相當可觀的資金來購買計算時間。
順便提一下,購買GPU也是一筆不小的開銷。在AWS上,這些費用是資本化的,即使只租用三個月并付清了費用,他們也不會將GPU轉讓給你。然后運行一個訓練作業。現在,擁有了一個訓練有素的模型。
這是一個在本科教育階段接受過廣泛訓練的大型語言模型,相當于對互聯網上的所有標記都有了一個基礎的文科教育背景。但在實際應用中,你可能希望模型更加專業化,比如專門用于醫學或教學領域。這時,就需要將模型送入研究生院進行深造。在研究生院,你可以進行一系列的組合操作,其中之一就是所謂的預訓練(pretuning),即在特定數據集上繼續訓練模型。
在NVIDIA內部,我們使用的模型名為ChipNeMo,它旨在提高我們的硬件設計師的工作效率。NeMo是我們的通用大型語言模型,而ChipNeMo則是在240億個標記上進行了預訓練,這些標記主要來源于自1990年代中期以來我們設計GPU的架構文檔、Verilog代碼、腳本等。ChipNeMo最顯著的應用是幫助高級設計師節省時間,因為高級設計師通常需要花費大量時間回答初級設計師的問題,例如“紋理單元是如何工作的?”等。通過向ChipNeMo提問,高級設計師可以得到準確且有力的答案,因為ChipNeMo已經閱讀了所有相關的架構文檔。
在預訓練之后,你還需要進行微調,使模型更加符合人們的喜好。這通常是通過讓模型生成多個查詢回復,并讓人類對這些回復進行評分來實現的。通過收集人類的反饋,你可以不斷優化模型,使其生成的回復更符合人們的口味。在這個過程中,人類的參與至關重要,因為他們的反饋是提升模型質量的關鍵。
有意思的是,盡管開始時對模型進行文科教育的成本很高,但人們可以通過微調來降低這一成本。據我估算,微調的費用大約在10萬到100萬美元之間。盡管這個數字可能很高,但人們已經通過利用僅花費幾千美元的GPU時間,完成了非常有效的微調工作。因此,一旦擁有了專業模型,就可以開始實際應用了。
從長遠來看,深度學習的大部分計算都集中在推理階段。在深度學習探索的早期階段,訓練工作確實非常繁重,因為人們需要進行大量的實驗。然而,一旦他們找到了合適的模型,他們就可以定期重新訓練這些模型,并在模型上進行推理。這個過程可能會持續幾個月甚至更長時間,然后再重新進行整個訓練過程。因此,大量的工作實際上是在推理階段完成的。即使每個查詢可能只需要一秒鐘的GPU時間,但當進行足夠多的查詢時,這實際上會占據訓練階段花費的幾個月的時間。
這張幻燈片的最新補充部分,我稍微插入了關于檢索增強生成的內容。這是近四五個月來非常流行的一種做法。在運行大型語言模型和進行推理之前,我們會使用查詢來查詢數據庫,提取所有相關文檔。對于ChipNeMo模型,我們回到了最初的240億個標記文檔數據庫,提取了所有相關的架構文檔,然后將它們與原始查詢一起輸入到模型的輸入窗口中,然后運行推理代碼。這種做法可以防止大型語言模型使用虛構的信息,因為它主要基于實際文檔進行操作。它可以為我們提供真實文檔的引用,并大大提高準確性。
接下來,我將先介紹一些動機,然后我們將討論我們是如何走到這一步的。而講座中最令人興奮的部分將是我們接下來將走向何方。
讓我們從一些動機和歷史背景開始探討。當前的深度學習革命是由硬件推動的。我喜歡將深度學習視為由三個要素構成的。它們分別是算法、數據和計算能力,這可以類比為燃料、空氣和火花。
首先,算法是這里的“燃料”。大多數這些算法,至少在它們的基本形式上,自20世紀80年代以來就已經存在了。深度神經網絡、卷積網絡,以及使用隨機梯度下降和反向傳播進行訓練的方法,這些都在80年代就已經出現——在某些情況下,甚至更早。
接下來是“空氣”,即數據。大型標記數據集一直存在,特別是對于無監督學習所需的數據。而對于監督學習,像Pascal和ImageNet這樣的大型標記數據集自2000年代初就已經存在了,所以在真正的“火花”點燃之前至少有10年的時間。
然而,點燃這種燃料和空氣混合物的“火花”是足夠的計算能力。這指的是在合理的時間內,使用足夠多的數據來訓練一個足夠大的模型。以最初的ImageNet數據集為例,它大約包含1000萬張圖像。而足夠大的模型則是AlexNet。我稍后會展示這個訓練對下一張幻燈片的要求。當時,訓練這樣一個模型需要花費兩周的時間,實際上是在一對采用Fermi架構的GPU上完成的。
自那時起,深度學習的進展受限于我們能夠應用的計算力。考慮到AlexNet的訓練時間,它基本上是每秒千億次浮點運算的百分之一——也就是說,如果我們有一臺每秒千億次的機器,你會花費百分之一的時間在上面。我估算這大約是一個小時的四分之一,即15分鐘,在每秒千億次的機器上。在2012年至2016年的ConvNet時期,我們提高了大約兩個數量級的計算力。因此,當我們達到ResNet時,我們大約擁有了每秒千億次的計算能力。
自2018年開始使用BERT進行大型語言模型的訓練以來,我們每年大約提高了一個數量級的計算力。對于GPT-4,雖然OpenAI沒有發布該模型的詳細信息,但根據網絡上的各種傳言,我估算在2023年訓練GPT-4大約需要100萬臺每秒千億次的機器。在大約十年的時間里,最先進的深度學習模型的計算需求增加了10的8次方倍。我們付出了巨大的努力,個體GPU的性能提高了約1000倍,另外的10的6次方倍增加來自于GPU數量的擴展和訓練時間的增加。
接下來,讓我稍微談談歷史。這是我想稱之為“黃氏定律”的曲線,以我們的創始人、NVIDIA的Jensen Huang命名。在深度學習領域,我們的推理性能在過去十年基本上每年翻一番,從大約四開始。這是Kepler世代單芯片推理中的INT8 TOPS,而在Hopper世代中則達到了4000。在10年內,性能增加了1000倍。如果每年翻一番,那么應該是1024倍。那么我們是如何實現這一壯舉的呢?實際上,我將在下一張幻燈片中為你揭曉。
主要的收益按照其貢獻程度列在這里。其中最大的收益來自于使用更小的數字。以Kepler為例,它原本并非專為深度學習設計,而是為科學計算打造,支持FP64和FP32圖形處理。因此,在推理過程中,人們使用INT8在FP32環境中完成操作,導致數字需要放大四倍。然而,昂貴的算術運算是乘法,其成本與比特數的平方成正比,因此成本實際上增加了16倍,而非4倍。
在2017年的ISCA會議上,Dave Patterson發表了關于Google TPU V1的演講,聲稱其比NVIDIA GPU更高效。然而,TPU V1的整體性能優勢——更確切地說是能源效率優勢——主要歸功于其執行INT8操作的能力。Patterson將TPU V1與Kepler進行比較,盡管當時他本可以將其與更先進的Volta甚至Turing進行比較。Kepler是五年前的產品,主要支持FP32。因此,這一切都與這16倍的成本增加有關。
接下來的主要收益來自于執行復雜指令。我將為此展示一張幻燈片,并詳細介紹相關內容。即使在GPU的簡化管道中,不進行分支預測和亂序執行,執行一條指令的成本仍然比該指令中的算術運算的成本高出約20倍。在更低的精度下,情況更糟,尤其是針對FP16。為了分攤這一成本,需要用一條指令完成更多的工作。因此,添加復雜指令成為了一個重要的優化方向。我們從Kepler世代的最大指令FMA轉變為Pascal世代的四元素點積DP4,再到我們的矩陣乘法指令,如HMMA用于半精度矩陣乘積累加和IMMA用于8位整數矩陣乘積累加。這些指令的引入分攤了一些開銷,為我們帶來了額外的12.5倍性能提升。
這里展示了四代工藝技術,它們以顏色進行區分——黑色、綠色、藍色等。Kepler和Maxwell采用了28納米工藝,而Pascal、Volta和Turing則采用了16納米工藝。Ampere是7納米工藝,而Hopper更是達到了5納米工藝。然而,從28納米到5納米的巨大躍遷只為我們帶來了大約2.5倍的性能提升。我內部有一個電子表格,一直在跟蹤這些數據。因此,我們并沒有從傳統的工藝技術提升中獲得太多好處,主要的提升來自于更先進的架構。另一個重要的架構貢獻是稀疏性。當我展望未來時,我相信稀疏性將為我們帶來更多的性能收益。目前,我們僅在權重上利用了2比1的稀疏性,但我們可以實現更高級別的稀疏性,并將其應用于激活上。
此外,我還想提到,算法領域的進步也非常顯著。我認為,僅通過多年來模型效率的提升,我們就已經實現了另外1000倍的性能增長。以ConvNet時代為例,當大家都在ImageNet競賽上競爭時,從VGGNet到GoogleNet的轉變就是一個很好的例子。GoogleNet是一個更高效的網絡,它去掉了完全連接的后端,采用了可分離卷積和旁路等技術,使網絡效率提高了數個數量級。因此,他們能夠在不增加太多操作的情況下,實現性能上的巨大提升。這樣的模型還有很多。
讓我們來談談復雜指令及其重要性。正如我之前提到的,即使對于具有非常簡化管道的GPU,執行指令的開銷因子也約為20。而對于執行復雜、亂序CPU操作的CPU,比如執行FP16操作,這個開銷因子更接近1000。這也是為什么我們不希望在CPU上進行深度學習的原因之一,除非我們全部使用MMX指令進行。
如果我們的工作僅限于融合乘加運算,那么我們實際上在執行兩個算術運算。這意味著,我們的大部分能量都消耗在了開銷上,就像一個大公司運營的成本。但如果我們能夠至少執行八個操作——比如,一個點積運算就需要四次乘法和四次加法,總共八個操作——那么有效負載的能量就會增加到六。盡管開銷能量保持不變,但開銷相對于有效負載的比例會下降到五倍。盡管如此,我們仍然在開銷上花費的能量比在實際操作上花費的要多。
在Volta世代,我們引入了一個被市場人員稱為張量核心的功能,它實際上是一個專門用于執行矩陣乘法的指令。HMMA,即半精度矩陣乘積累加,能夠接收兩個FP16的4x4矩陣,并執行矩陣乘法。這意味著你需要將每個元素與另一個矩陣的每個元素相乘,這是一個n的三次方操作,即4x4x4,總共64次乘法。然后,你需要將這些結果全部加起來,并存儲到一個FP32的4x4矩陣中。這樣,總共進行了128次操作。盡管操作的總能量是110,但現在的開銷比例已經降低到了22%。
到了Turing世代,我們又引入了整數版本的該操作,即IMMA。它接收兩個8x8的INT8矩陣,進行乘法運算并求和。而在Hopper世代,我們更進一步,引入了四分之一精度矩陣乘加法,使用FP8進行運算。需要強調的是,一旦我們擁有了這些大型指令,我們的完全可編程GPU在深度學習方面的效率就可以與硬連線的加速器,如TPU或其它專用芯片相媲美。因為這些專用芯片也并非毫無開銷。它們同樣需要移動數字,而不僅僅是進行矩陣乘法運算。它們的開銷可能也在15%到20%左右。因此,在這個時間點上,我們的效率與專用加速器相當,同時我們還擁有可編程引擎的所有優勢,背后是一個成熟的編程系統和幾十年來積累的庫支持。
聽眾:這是能源開銷方面的討論,對吧?還有其它的嗎?
Bill Dally:沒錯,能源確實是一個很好的衡量標準。
那么,我們目前進展到了什么階段呢?如今,我們有了Hopper。它具備一千萬億次的TensorFloat-32運算能力。根據數據的稠密程度或稀疏程度,它的FP16或BF16運算能力為1到2千萬億次,而FP8或INT8的運算能力為2到4千萬億次。它的內存帶寬超過3TB/s,高達94TB,這里的94是準確的,配備了96GB的HBM3內存。此外,它還擁有18個NVLink端口,為我們提供了900GB/s的帶寬,而整個芯片的功耗為700瓦。不過,有一點需要指出的是,將這個部件運往中國是違法的,這種做法其實并不明智,因為對這種部件的出口限制只會促使中國的程序員為華為部件編寫代碼,這對美國并無益處。
這個部件擁有一些令人印象深刻的功能。事實上,我親自為這個部件中的動態規劃指令撰寫了建議書,以加速生物信息學代碼的運行。因此,如果你需要進行動態規劃來進行基因序列匹配,這個部件將會表現出極高的運算速度。
關于比值——當我分享我們在加速器上所做的一些實驗時,我會詳細解釋這一點——它達到了每瓦9兆次的運算性能。這是基于INT8或FP8數學運算的結果。這也是我們評估不同深度學習解決方案效率的一種方式。盡管我們已經實現了1000倍的性能提升,但我們還需要達到10的8次方倍的目標。那么,剩下的性能提升從哪里來呢?答案在于使用多個GPU。事實上,你必須使用多個GPU,因為單一的GPU無法容納像GPT-4這樣規模高達1.2萬億參數的模型。在進行訓練時,每個參數大約需要20字節的存儲空間,這不僅包括了參數本身,還包括了動量系數、訓練算法以及其它一些開銷。因此,要保存一個GPT-4的完整副本,我們需要大約20個GPU。
因此,我們將工作劃分為兩個維度的并行化。
首先是張量并行,這涉及多個GPU協同工作在一個模型副本上。具體來說,我們將單個矩陣進行切片處理,通常只在一個維度上進行切片,例如將矩陣切分成列條。然后,我們進行相應操作,并將結果匯總。
另一個維度是管道并行,我們將網絡的不同層分別部署在不同的GPU上,并將結果逐層傳遞。值得注意的是,早期的層并不會閑置,而是在處理后續數據批次的同時,開始處理下一批訓練數據。隨著規模的進一步擴大,我們還會采用數據并行策略。這意味著我們將運行模型的不同副本,并將一個訓練數據批次分割到這些副本中,使它們各自進行訓練。之后,它們會交換權重更新,以確保在下一次迭代中每個副本都擁有相同的權重集。
為了實現這些并行化策略,我們設計了一系列硬件。首先是DGX服務器,它配備了8個H100 GPU和四個我們的NV交換機。這些交換機負責連接從H100 GPU引出的NVLink互連。盡管我不能詳細介紹每個細節,但這款服務器具備32 petaFLOPS的計算能力,功耗為11千瓦,背板輸出達到900GB/s。
除了上述的四個NV交換機外,為了連接更多這樣的服務器,我們還設計了一個類似披薩盒的裝置。這個盒子里裝有兩個NV交換機,通過它和使用主動光纜,可以構建更大規模的系統。
因此,通常向客戶提供的解決方案看起來像這樣:一個DGX超級機架。在這個機架中,每個小金色前面板板子上都裝有一個HGX100,它集成了8個GPU。可以使用NVLink將多個這樣的機架連接起來,或者在某些情況下,采用InfiniBand網絡——中間那些是InfiniBand量子交換機——并將所有這些設備整合在一起。
這樣做的好處有很多。首先,軟件是預配置的。因此,當從NVIDIA購買這樣的機器,并在你的數據中心中將其連接好,插入所有主動光纜后,只需簡單地開機,便可以在一小時內開始訓練深度學習模型。相反,如果嘗試從頭開始配置所有網絡設置并進行調整,那可能需要耗費一個月的時間。我過去曾與Cray和其它公司合作構建了許多超級計算機。但通常情況下,從我們在洛斯阿拉莫斯或橡樹嶺等地將這些機器完全組裝并放置在地板上,到它們能夠運行一個有用的問題,往往需要六個月的時間。這是因為啟動和調整過程需要花費大量時間。而通過使用預配置的系統,我們已經解決了這些問題。可以簡單地開機,它就能立即投入工作。這并不是因為硬件存在故障,而是需要花費大量時間來準備和調整軟件。
觀眾:那么這臺機器是否更側重于訓練任務呢?
Bill Dally:其實它同樣適用于推理任務。此外,還可以根據自己的需求配置所需的帶寬。機器內部的帶寬是預配置的,有八個GPU通過NV交換機連接在一起。但在背板上,可以選擇是否將所有GPU都連接起來。同時,我們還提供了PCIe插槽,用于安裝InfiniBand網卡。因此,可以根據實際需要決定連接多少網卡。這樣,可以為每個盒子提供所需的帶寬。
對于訓練任務來說,另一個突出的優點是,無論是NVLink網絡還是InfiniBand網絡都支持網絡集合功能。這意味著在進行數據并行訓練時,每個GPU都需要交換權重。通過網絡集合功能,你只需發送你的權重并接收總和,而無需進行逐個交換和相加的操作。這極大地提高了數據并行訓練的有效網絡帶寬。
接下來,讓我們來談談軟件方面的一些內容。
有時我想說,關于深度學習的一點是,雖然任何人都可以構建一個矩陣乘法器,但真正讓它變得有用的是軟件。在NVIDIA,我們從2010年開始致力于深度學習軟件的研發。當時,在早餐時我遇到了我的斯坦福同事Andrew Ng,他正在跟我分享關于在互聯網上找貓的事情。我一聽就覺得,天哪,GPU在這方面比CPU更擅長。于是我指派了一位NV研究部的同事——實際上是一個名叫Bryan Catanzaro的編程語言研究員——與Andrew一起工作,去尋找互聯網上的貓。他編寫的軟件后來演變成了cuDNN。當然,后來Andrew挖走了Bryan,讓他在百度工作了一段時間。不過Bryan最終又回到了NVIDIA。從那時起,我們就一直在構建大量的軟件。
這是我們的軟件堆棧的不同層次。我們擁有三個主要的軟件堆棧——AI堆棧、HPC堆棧,以及我們稱之為Omniverse的圖形堆棧。在此基礎上,我們還建立了許多垂直領域,涵蓋了從Clara的醫療診斷到Modulus的物理模擬,再到Drive的自動駕駛汽車技術等各種領域。這里涉及到的軟件工作量可能高達成千上萬人年。這種努力在MLPerf基準測試中得到了真正的體現。
我認為MLPerf是一個非常好的衡量標準——我喜歡查看它以了解競爭對手的情況,也了解整個深度學習社區的發展狀況。這真的很棒。
我的意思是,在CPU領域,當我在80年代和90年代從事CPU架構工作時,有SPECmark基準測試,大家都會在這個基準上進行競爭。但隨著時間的推移,它們變得有些不自然了。我認為MLPerf基準測試真正出色的地方在于,它們定期推出新的基準測試。現在他們有一個LLM基準測試,還有一個很好的推薦基準測試。他們緊跟行業發展的步伐,幾乎沒有延遲。
我想通過這張幻燈片傳達的觀點并不是Hopper比H100剛推出時快6.7倍。事實上,當H100首次推出時,與首次推出的Ampere相比,它的性能提高了2.5倍。這是硬件的進步,更是Ampere軟件的改進以及龐大的軟件基礎所帶來的優勢。人們可以構建出非常出色的矩陣乘法器,但除非他們在深度學習軟件上投入了成千上萬人年的努力,否則很難在競爭中脫穎而出。這一點在MLPerf的結果中得到了體現。
這里只是我剪輯的一些文章標題。最近的一篇是昨天——11月8日。雖然你可能需要仔細閱讀文章,才能找到稱贊NVIDIA的部分,但在其它文章中,我都強調了NVIDIA在這些方面的優勢。
現在的情況就像是電影中的場景,主角們在跑步,后面緊跟著蒙古軍隊和一大群野獸。他們必須拼命地跑才能保持領先。這就像是現在的NVIDIA,因為每個人和他們的狗都在嘗試構建AI硬件,因為他們認為這是下一個淘金熱的機會。我們試圖保衛我們的領先地位,不是通過阻礙他們的方式,而是試圖比他們跑得更快。然而,尷尬的是,他們中的大多數人都會絆倒摔倒,但只需要一個人繼續奔跑。如果我們絆倒了,結果就不會好。
那么我們該如何保持領先,就像在古代戰爭中超越蒙古軍隊一樣,確保我們在AI硬件領域的領先地位呢?
一個很好的方法是繪制一張圖表,展示推理過程中能量的流向。在這張圖表中,我們可以看到數學、數據路徑和數學占據了47%的比例,這意味著我們有一半的能量用于進行數學計算。為了改進這一點,我們需要進行更高效的數學計算,這可以通過采用更好的數字表示或利用稀疏性來減少計算量來實現。
接下來,我們看到圖表中的另一個大塊是內存,包括累積緩沖區、輸入緩沖區、權重緩沖區和累積收集器,還有6%的能量用于數據傳輸。這主要涉及到將數據從片外存儲器傳輸到片上存儲器,以及從大的片上存儲器傳輸到較小的片上存儲器。
那么,我們應該如何改進呢?在數字表示方面,我們可以采取多種策略。這里,我將討論其中幾種。我們學到的一個重要經驗是,我們應該使用我們能夠應對的最經濟的數字表示。為了實現這一點,我們需要將數字精確地縮放到該數字表示的動態范圍內。接下來,我會分享一些我們發現的有效方法。
此外,我對長數字特別感興趣,并會介紹一些使長數字加法變得更容易的技巧,因為通常來說,乘法相對容易,因為它們可以轉化為加法,但加法卻更復雜,因為它們需要轉換回整數。
目前,我們主要在權重上使用稀疏性。然而,我們還可以考慮在激活上使用稀疏性,并利用其它低密度特性來利用稀疏性。為了減少那6%的數據移動,我們可以優化平鋪策略——基本上是一種更好的循環調度方式,以最大限度地減少移動并提高重用率。
在電路方面,我們也做了很多工作。考慮到內存消耗了大約一半的能量,我們可以通過一些簡單的方法來提高內存效率。例如,我們發現這些內存通常是“一次寫入,多次讀取”的。因此,在寫入時使它們在能源上相對昂貴是可以接受的。一種利用這一點的方法是使用每個單元格具有一個位線的設計。這樣,你可以寫入單元格,然后激活該位線,內存的輸出就會輸出。這種方法使得寫入操作變得非常節能。這只是我們正在考慮的一項改進。我們還有許多其它的改進方案,我會在接下來的部分繼續介紹。
針對我們接下來的計劃,我們將持續聚焦于優化數學計算和內存使用,以確保我們的硬件在處理深度學習任務時達到更高的效率。此外,我們還將不斷探索新的數字表示技術和稀疏性利用方法,以進一步降低能量消耗并提升性能。總而言之,我們的目標是維持在AI硬件領域的領先地位,持續創新和改進,以滿足不斷增長的深度學習需求。
沒錯吧?那么,當你在進行讀取操作時,你所做的就是從位于乘法器前面的一大堆位線中選擇一個,這個讀取過程幾乎不消耗能量。相反,寫入操作是能量消耗的主要環節。因此,你就不需要在每次讀取時都切換位線。你只需要進行一次寫入操作。情況會有所不同。但在讀取時,你只需要切換乘法器的輸入即可。
優化通信電路可以帶來諸多好處。如果讓我指導一個電路專業的學生來設計一種從芯片一端到另一端傳遞位的信號方式,并鼓勵他們盡可能多地消耗能量,他們很可能會采用我們現今的常規做法——利用邏輯電平,其中電源代表1,地線代表0。但實際上,只需稍微增加一些晶體管面積,你就不再需要1伏特的電壓來表示1或0了。那么高的電壓簡直是浪費,且可能對設備造成損害。實際上,你只需要確保足夠的能量使Eb/N0達到大約20分貝,就足以保證數據傳輸的準確性了——可能僅需50毫伏的電壓就足夠了。因此,通過改進通信電路,我們可以實現很多優化。
我想分享一件令我非常興奮的事情,我們正在為此付出巨大的努力,那就是通過直接在GPU上方堆疊DRAM來擴大我們的內存帶寬,并同時降低內存的能量消耗。但我們必須承認,這個過程中存在許多技術難題需要我們去解決,可能需要幾代人的努力才能最終實現。
讓我們從數字表示開始討論。
當你問一個數字系統有多好時,實際上你關心的有兩個方面。首先是準確性,即實際數字與理論數字之間的差距。在數字系統中,數字必須覆蓋整個數字線,因此準確性主要關注的是在將任意數字轉換為數字系統時可能產生的最大誤差,因為我們通常需要對數字進行四舍五入以匹配可表示的值。另一方面是動態范圍,即數字系統可以表示的數字范圍有多大。這既涉及到準確性,也涉及到成本。數字位數是一個關鍵因素。在存儲和傳輸數據時,存儲器和線路并不關心這些位的具體值,而是關心你引用了多少位。因此,理論上使用的位數越少越好。但同時,我們還要考慮執行操作的成本,比如進行乘積累加時所需的資源消耗。
接下來,我會簡要介紹一些代表性的數字。使用整數,事實上,其準確性并不理想。原因在于其誤差與數值大小無關。不論處理的是小數還是大數,誤差都是一個半最低有效位。稍后我會在下一張幻燈片上通過圖表來展示這一點。因此,它們在最壞情況下的誤差達到了33%。這是1.5和1之間的差異,因為我們必須將1.5四舍五入到2或1。這相當于從1中取走了一半,顯然并不理想。相比之下,浮點數的表現要好得多,對數的表現也更好。我應該選擇使用對數8和FP8,但我稍后會通過圖表來展示這一點。
關于符號,它的表現相當不錯。那么,符號具體是什么呢?事實證明,你可以使用反向傳播和隨機梯度下降來訓練各種模型。例如,我和宋曾在ICLR上發表了一篇論文,大約是在2015年,我們訓練了一個16條目的碼本,以獲取代表我們所擁有的權重分布的最佳16個權重。這是一個很好的方法,因為如果你只限于使用16個值,或者64個、256個值,這取決于你使用的位數,這就是你能找到的最佳方式來代表那些權重。這將有助于最小化存儲和移動的能量消耗。然而,在實際執行數學運算時,你必須表示你選擇的那些點。這意味著你需要在表中進行高精度的查找,而這本身就是一個相當耗時的過程。接下來,我們進行了16位數學運算。最終,我們用這些4位符號進行了16位數學運算,這完全抵消了我們在能量消耗方面的任何優勢。這個想法雖然巧妙,但并不實用。
接著,我們來看尖峰表示。我之所以要提到它,是因為如果要從所有能源效率極低的表示方法中挑選一個,尖峰表示無疑是首選。在CMOS技術中,什么會消耗能量呢?答案是線路切換。假設我需要表示一個介于1和128之間的整數。在尖峰表示中,如果平均表示,比如在64這個數值上,我必須切換這條線路64次。然而,如果我選擇使用7位整數來表示0到128,我擁有7個位,其中大約一半會發生翻轉,而不是切換。這樣一來,就只需要翻轉3.5次。比較一下,這就是1.75次切換與64次切換的差距。因此,尖峰表示與整數表示相比,能量開銷高達32倍,這顯然不是一個理想的選擇。
再來看模擬表示。關于模擬表示,我有一整套的論述來解釋為什么它在執行單個操作時表現良好,但在系統級別上卻不盡如人意。不過,為了簡潔起見,我就不深入探討了。簡而言之,無論是存儲還是移動模擬信號,通常都需要將其轉換為數字信號。然而,這種轉換會消除你從模擬操作中獲得的任何優勢,因為并沒有簡單直接的方法來存儲或移動模擬信號。
現在,讓我們來談談表示和分布。如果你對網絡進行剪枝,或者利用稀疏性,你可能會得到一個雙峰分布。這實際上是我2015年那篇ICLR論文中的權重分布圖。如果你選擇線性量化,也就是基本上只使用整數表示,并且你有16個值,它們將會出現在X所在的位置。你可以看到我在這里有很多取樣點,而那里幾乎沒有什么。在整個分布的葉下,我只有像三個X這樣的點。因此,我將會得到非常高的誤差。然而,如果我訓練碼本,我得到的小紅點將會更加集中,我基本上會把所有的點都放在它們表現良好的地方。事實上,這樣做是最優的。你訓練碼本就是為了達到這樣的效果。雖然有一個k均值聚類步驟,但除此之外,你基本上是在使用隨機梯度下降來將這些碼本條目移動到最佳位置。這就是你想要達到的目標。
如果你不進行剪枝,你往往會得到這樣的分布。這里要理解的重要事情是,你大部分的值都接近零。因此,非常重要的是要很好地表示小值。因為小值的誤差往往比大值的誤差權重更大,因為小值的數量并不多。
接下來,我們談談對數表示法。
對于我們這一代人來說,上大學時,我們可能是在這樣的工具上進行數學計算的。這就是計算尺,它主要進行對數運算。上面刻的小線代表了對數間隔。例如,我要計算1.12乘以1.2,只需將1.12放在這里,移動到1.2的位置,然后讀出答案。實際上,我將乘法運算轉化為了加法運算。我計算的是線性距離,同時利用刻度線上編碼的對數表進行數學計算。與整數或浮點數表示法相比,對數表示法具有出色的特性。
如果我選擇對數表示法——這里,我正在使用我所說的8位對數4.3表示法。其中包含一個符號位,7個指數位,其中4位在二進制點的左側,3位在右側。這意味著,如果你將這些位串聯起來,你實際上是在計算2的某個冪次除以8。在二進制點的右側需要有一些數值,因為如果只考慮2的冪次,它們之間的間隔會過大。你的數字系統需要更細致的分級。通過移動二進制點,你可以在精度和動態范圍之間找到平衡。
與FP8相比,我選擇了E4M3,即4位指數,然后取相同的3位,但不是擴展的指數,而是尾數值。在這里,我們擁有相同的動態范圍,因為我基本上選擇了相同的指數。但我的最差情況準確性提高了50%。稍后我會給你一個圖表來展示這一點。基本上,我是按塊值來縮放誤差的。每個具有相同指數的塊具有相同的誤差,然后跳到一個更大的誤差,而對數表示法則是對每個值都進行了縮放。因此,最小數字的誤差非常小。
這里是對數表示與整數表示的比較。你可以清晰地看到,對數表示法的優勢在于表示較小的數字,而這恰恰是我們最為關心的部分,因為大多數權重都集中在這個范圍內,其誤差非常小。在1.5左右的最大誤差,無論是向上還是向下調整,都大約是9%。這是使用4位對數2.2(無符號位)時的情況。而使用4位整數表示時,這里的最大誤差高達33%,因為誤差的絕對值是一樣的。在任何位置,誤差都是0.5。所以,在1.5或15.5這樣的數值上,誤差同樣是0.5。這意味著,在我們真正關心的區域,整數表示法會帶來非常大的誤差,而且這種誤差是不成比例的。
浮點數在某種程度上可以被視為一種不那么理想的對數表示。這里我們比較了浮點數2.2與對數2.2的誤差。你可以看到,誤差增加了一半,從9增加到了13。這是因為,在使用浮點數時,你對前四個步驟使用了相同的步長,接著對接下來的四個步驟也是如此。而在使用對數表示時,你在每個元素中都增加了步長。因此,你最終得到的誤差更小,這在表示最小值時尤為重要。
對數數字系統有哪些特性呢?首先,乘法運算變得非常高效,因為只需進行加法運算。實際上,與在整數或浮點數系統中進行乘法相比,加法運算的成本要低得多。在整數或浮點數系統中,乘法是一種二次成本的操作,而加法則是一種線性成本的操作——與位數成比例。然而,加法在對數數字系統中并不容易實現,因為通常需要進行查找操作。所以,具體性能還取決于綠色區域(EI和EF)的轉換效率。
EI只是一個簡單的移位操作。你取得那個指數,它告訴你需要移位多遠。然而,EF則需要一個查找操作。你必須在八個值中查找一個,這些值都是2的冪——2的0次方很簡單,就是1。但接下來是2的1/8次方、2的1/4次方、2的3/8次方、2的1/2次方等等。你需要查找這些值的二進制表示,并用足夠的位數來表示它們以保持準確性。然后,根據EI的數量進行移位操作,再進行加法。如果每次加法都這樣做,那將是一個非常耗時的操作。但想象一下你在深度學習系統中做的事情。你通常在進行大量的乘法運算,并將所有結果相加來計算新的激活值——實際上,通常是成千上萬次的乘法,然后將它們全部相加。
這里有一個來自某個美國專利申請的圖。數字在下方,展示了如何以低成本進行這種操作。你需要做的是將這個表查找操作移到這10,000個元素的外部。假設我有10,000個元素要相加,每個元素都有EI和EF。我根據EF對它們進行排序,EF可能是2的1/8、2/8、3/8或1/4。我需要在最后乘以它們嗎?我取所有這些元素,并將它們的整數部分相加在一起,這很簡單。然后,如果我取余數部分,也就是EF部分,并在排序單元中選擇——假設它是三位——我將指向由商部分確定的八個輸出之一。在典型的應用中,不是每個周期處理一個元素,通常是每個周期處理8或16個元素。然后,我傳遞符號和EI,我取得符號位,并將其移位到商。接著,我將這些累加器相加。這是一個熱和求和的過程,你可以利用它,因為你只翻轉了一個位。如果你足夠聰明,你可以利用這一點來提高能效。我將所有這些元素相加,直到我完成整個張量的計算。
完成了10,000次加法運算——平均每個區間大約1,000次。然后,我進行一次查找操作。實際上,這不是真正的查找操作。它是硬連線的。我將那個常數硬連線到這里。我用這個硬連線的數字進行最后的乘法運算,取出部分總和,然后將它們相加。現在,我得到了整數形式的值。而且,有一種非常簡單的方法可以將其轉換回對數形式。這就是對數數字系統的運作原理。
接下來,我們將討論如何最優地裁剪你的數字。
這實際上是一個關于如何選擇適當的動態范圍的問題。不論你采用哪種表示方式,無論是整數、對數還是浮點數,關鍵的操作是如何確定一組數字的可表示范圍的居中位置。簡單來說,你必須表示分布。
讓我介紹兩種可能的做法。
首先是大多數人目前采用的方法。你基本上會掃描——假設我有一堆權重或激活值。我掃描我的權重或激活值,并且可以在不同的粒度上執行此操作。稍后我會談到這一點,通常是對每一層進行一次操作。所以,我會選擇網絡的一層,掃描所有權重,比如找到最小權重-0.8和最大權重0.8。然后,我會調整我可表示范圍的數字——在這種情況下,它是一個整數表示,因為它是均勻分布的——以便我可以精確地表示最大值和最小值。這樣,你就不會遇到任何剪輯噪聲。通過限制較大的數字,我不會產生任何噪聲。但我的量化噪聲會非常大。這些紅色條之間的間隔非常大。
另一方面,我可以選擇進行裁剪。我可以選擇說,與其表示0.8,我將我的最大可表示數字設為0.2。這意味著我必須將這里的任何數字都限制在0.2以下。這將引入剪輯噪聲,降低這些數字的值。但我的量化噪聲會小得多。
在某次會議上,我提出了一個有趣的問題,我認為這個問題很難回答,那就是是否存在一種方法可以找到設置這個剪輯因子的最佳位置,以便獲得最小的均方誤差。雖然這并不是你真正想要的,但它是一個很好的代理,也是一個可以明確表述的問題。你真正想要的是神經網絡中的最小誤差,但那是一項更具挑戰性的任務。
然而,我們團隊中最近加入的一位員工在一個小時內就解決了這個積分問題。他告訴我:“是的,你只需要解決這個積分。”我對此感到相當震驚。
聽眾問:GPT-4或? Bill Dally:不,這是在GPT-4之前。他實際上親手解決了這個數學問題。我必須說,這真的令人印象深刻。解決那個積分是相當困難的,你可能不會希望每次針對變化的激活函數都這樣做。
然而,有了這個迭代方程,我們可以近似這個積分,而他在大約一天后就給出了結果。如果你進行2或3次迭代,它可以為你提供一個非常接近真實積分的值。這個方程還給出了上下裁剪點。直觀地來說,讓我們看看這個例子。這是一個特定的層,我們正在查看的網絡的第13層。假設我使用四位數字來表示。如果我的裁剪比例尺在這里,那就意味著我沒有進行任何裁剪。我可以表示直到4.2或其它最大可表示的值。因此,當我開始裁剪時,我的噪聲會減少,因為我大大降低了量化噪聲。而且,我實際上沒有引入太多的裁剪噪聲,因為在這個范圍內幾乎沒有權重,直到我移動到大約這里的這一點。在這一點上,我達到了一個最小值。如果我再降低裁剪比例,裁剪噪聲開始變得足夠大,以至于實際上使整體的均方誤差增加。但這就是我想要的位置。如果我查看誤差的點,我這里沒有5位數線的具體數據,但實際上我最終得到的誤差遠低于5位數線的頂部。事實上,如果我沒有進行任何裁剪,我的誤差幾乎達到了6位數線。因此,在減少均方誤差方面,這樣做是非常值得的。所以,最重要的不是按照你認為的方式進行縮放,而是找到最優的縮放方式來最小化均方誤差。
聽眾:這個假設是基于一個預先訓練好的網絡,你進行裁剪。如果在訓練循環中,你實際上假設在訓練期間有一定數量的表示形式,那么這個答案會不會有很大的變化?
Bill Dally:這是一個很有深度的問題。實際上,我并不確定它是否會有很大的變化。如果能夠訓練裁剪因子,那將會是非常理想的情況。
聽眾:好吧,為了得到可能最簡單的結果,這里確實有很多需要權衡的地方。
Bill Dally:我很高興你這么認為,因為我自己之前也沒有深入考慮過這個問題。但我認為,理論上講,我們是可以訓練裁剪因子的,只需要將反向傳播應用到裁剪因子上。然后,其它的權重將會根據裁剪因子進行調整。目前,我們是在訓練完成后再進行這個操作的。實際上,我們并沒有用剪輯重新訓練網絡,盡管這樣做也是可能的,而且可能會得到更好的效果。
聽眾:我想更廣泛地探討一下,是否可以選擇最簡單的數字表示形式,以便在可能的任何合理動態范圍內,以及你所描述的分布中的任何極端特性下,都能得到理想的效果?我假設這是你目前唯一可用的數學方法,所以—— Bill Dally:我們仍然需要選擇一個scale factor。關鍵在于,你不僅僅是使用表示形式本身,而是結合一個scale factor來使用它。這個scale factor的選擇變得尤為關鍵。
因此,讓我再深入談談向量縮放。實際上,向量縮放可能是這次演講的核心信息。在通常的實踐中,我們都會進行縮放。當我們開始縮放時,需要兩個縮放因子,一個用于前向傳播,另一個用于反向傳播。這是因為兩者最終使用的值可能會有很大的差異,特別是在反向傳播中,你需要乘以一個學習率,這會使返回的數字變得更小。然后,我們會逐層進行縮放。如果你發現某種方法有效并改善了結果,你可能會想是否可以進一步優化?
于是,我們轉向了更細粒度的縮放。這進一步提升了效果。于是,我們提出了一個問題:如果我們不是按層進行縮放,而是按矢量進行縮放,效果會如何呢?這里的‘矢量’指的是包含16、32或64個元素的集合。由于每個矢量都有一個非常緊湊的分布,我們可以對其進行縮放,從而獲得非常出色的結果。這實際上相當于增加了額外的精度位數。
因此,我們的思考方式是,在常規操作中,你會按照這里展示的方式處理ConvNet。我們有一個維度為高度乘以寬度乘以通道數的張量,即 H、W 和 C。接著,我們通過 R 乘以 S 進行卷積,這里的 R 和 S 是卷積核的大小。但在通道維度上,我們會使用對應通道的權重進行點乘操作。
假設我選取一個在通道維度上長度為32的矢量元素,并與該元素進行點乘,我可以獨立地對這個32元素矢量進行縮放,而不影響張量的其它部分。為了實現這一點,我最終在我的 MAC 單元中添加了一個小單元。在輸出端,完成所有權重與激活函數的乘法運算以將其轉換回預縮放數字之后,我必須乘以兩個縮放因子——一個用于權重,一個用于激活函數,即 sw 和 sa。
從圖形化的角度來看,我們可以這樣想象:這個大藍色塊代表整個層的分布,而這條線的小范圍則代表我的矢量的范圍。因此,現在基本上我在對一個更小的矢量進行縮放。
如果我對這個更小的矢量進行最優裁剪,我可以獲得更好的效果。因此,這個方法在實際應用中表現非常出色。接下來,我將展示我們構建的一款加速器的一些實驗結果。
讓我先談談稀疏性。
這張圖來自我和宋于2015年在NeurIPS(當時稱為NIPS)上發表的一篇論文。在這篇論文中,我們展示了一個實驗:取一個神經網絡——這里展示的是一個多層感知器——刪除其中一部分權重,然后使用掩碼重新訓練它。這個掩碼的作用是保持被刪除的權重不變。最終,我們幾乎得到了與原始網絡相同的準確性。
實際上,對于多層感知器,我們可以刪除高達90%的權重而仍能保持相同的準確性。而對于卷積神經網絡(ConvNets),這個數字通常更接近30%。也就是說,你可以刪除60%到70%的權重,使網絡的密度保持在30%到40%,同時仍然保持相同的準確性。我們覺得這一發現非常有趣。
為了進一步驗證這一發現,我們實際上設計了一個小型測試條帶,名為“高效推斷引擎”。這個引擎的目的是展示我們如何在實際應用中實現稀疏計算,并且這種計算方式是高效的。與標量引擎相比,我們的高效推斷引擎具有更高的效率。為了實現這一點,我們使用了專用硬件來遍歷CSR結構,從而能夠在50%的密度下有效地進行稀疏計算。
我記得原始論文的一個審稿人曾經評論說,這只是學術上的好奇,因為大家都知道,如果使用稀疏矩陣包,那么矩陣的密集度必須非常低,比如不超過0.1%,否則直接運行它會更快。確實,如果全部在軟件中進行稀疏計算,那么審稿人的觀點是正確的。但我們的方法有所不同。我們基本上為CSR指針分配了單獨的內存數組。我們還設計了特殊的硬件來遍歷這些內存數組。因此,我們的稀疏計算幾乎沒有額外的開銷。
問題是,實際上沒有多少人愿意去做標量計算。為了進行比較,我們構建了一些最先進的加速器,它們配備了并行向量單元。這些加速器基本上可以同時執行16個長向量的運算,每個周期可以完成256次乘法。現在,我們面臨的挑戰是如何在稀疏情況下使它們高效工作。
自2015年以來,我一直在努力解決這個問題。我不斷嘗試提出新的想法,看起來都非常不錯,直到我們實際去合成邏輯。然后,我發現了一個問題:如果我想對兩個稀疏向量進行點積運算,并在最后一刻篩選出非零元素并將它們送入MAC單元,這會產生大量的閃爍。這是因為多路復用器在實時嘗試判斷哪些數字是0。它會不斷選擇這個數字,然后說:“不,這個數字在這里是非零的,但在另一邊它是0,所以讓我們把向量移到下一個位置。”最后,為了每個計算,它們會切換數學單元5次,這極大地消耗了我們的能源。
因此,我們一直在尋找消除閃爍的方法,因為這成為了許多稀疏運算的瓶頸。在Ampere和Hopper中,我們都找到了一個有效的方法,我們稱之為“結構化稀疏性”。原來,稀疏性之所以難以處理,是因為它是不規則的。當數據不規則時,我們需要花費大量精力去整理它們,使它們到達正確的位置。
我們的解決方案是避免不規則性。我們強制使稀疏性具有某種規律模式。具體的方法是,和所有與稀疏性相關的工作一樣,我們密集地訓練網絡。即使對于所有的稀疏性,大部分的訓練也是在稠密的情況下進行的推理。但是,在訓練完網絡之后,我們會找到最低的權重并將它們刪除。但在這里,我們會以結構化的方式進行刪除,即我們堅持要求每四個中最多只有兩個是非零的。如果你做不到這一點,那么你可能只能進行密集計算。但是,如果你能剔除四分之二的權重,這通常是可以做到的,特別是當處理MLP時,你可以剔除10個中的9個。那么,剔除四分之二應該就很容易了。
我們將這些權重刪除,然后使用掩碼重新訓練網絡,使其它部分在某種程度上補償消失的部分。接著,我們通過僅存儲非零權重和一些元數據來壓縮模型,這些元數據告訴我們哪些權重被保留了。由于元數據是靜態的,不會頻繁變動,我們將其輸入多路復用器,用于選擇輸入激活。具體來說,如果我們有八個輸入激活,而元數據告訴我們其中四個是非零的,我們就選擇這四個并將其饋送到乘法器中。這樣,我們得到了一種規則性很強的計算方式,效率幾乎翻倍。目前,我們正在研究如何將這種方法擴展到激活函數上,以及如何結合兩種稀疏模式,同時保持計算的可預測性。
接下來,我簡要談談加速器和加速器與GPU之間的關系。
我們在NVIDIA開發了一系列加速器,其中EIE是與斯坦福大學合作完成的,而Joe Lemar則在NVIDIA與麻省理工學院合作完成了另一項工作。我們還開發了用于稀疏卷積神經網絡的SCNN加速器,以及多芯片模塊等。
這些加速器之所以能獲得出色的性能,主要有五種原因。
首先,它們采用了特殊的數據類型和操作符。這與我們從GPU中借鑒的經驗有關。我們針對數據類型進行了專門化設計。以Hopper為例,它采用了FP8數據類型,并使用QMMA專門處理FP8的8x8矩陣乘法。通過這種方式,我們基本上用一個周期完成了原本需要數十或數百個周期才能完成的工作。因此,QMMA和IMMA都能在單個指令周期內完成1024次操作。
其次,這些加速器具備大規模的并行性。我們追求的是1000倍的性能提升,因此希望大量的計算單元能夠并行工作。在構建加速器時,優化存儲器是非常重要的。主存儲器訪問成本高昂,如果頻繁地從主存儲器中讀取數據,性能將會受到限制。由于深度學習涉及多個層次的讀取,我們可以通過使用小的暫存區來實現良好的數據重用。
當我們為生物信息學設計了一個加速器,并在Hopper中實現了動態規劃指令時,我們首先考慮了生物信息學算法——Minimap,這是廣泛使用的算法。我們提出了一個問題:如果只為這個算法設計專用硬件,我們能獲得多少加速效果?答案大約是4倍。就在我們準備放棄并轉向其它項目時,我們想到,如果重新設計算法呢?這引出了算法、架構和代碼協同設計的挑戰。
事實證明,生物信息學家認為動態規劃計算成本高昂,因此他們花費大量時間在種子階段,試圖找到好的候選項以進行對準。而我們采取了不同的策略:我們使對準階段變得非常高效,因為我們的對準引擎比CPU上的對準操作快150,000倍。而種子階段相對昂貴,因為它需要主存儲器訪問。因此,我們顛倒了這一策略,設計了一個非常經濟的種子階段,其中可能產生大量誤報輸入到對準階段。但由于對準速度極快,它能夠自我過濾,最終我們實現了大約4000倍的總體加速。
然而,關鍵在于優化內存訪問。你不能一直依賴主存儲器進行引用并期望獲得良好的性能。此外,減少操作的平均開銷也很重要。對于簡單的操作,與CPU相比,我們的加速器可以實現10000倍的加速。
我一直在從事這方面的研究,從1985年開始的快速加速器設計。我最初是從事仿真加速器的設計,之后涉及信號處理,最近則是神經網絡和SAT求解器。
我想強調操作開銷的重要性。這是一篇關于簡單ARM亂序核的論文中的數據,盡管它是相對簡單的核之一。我忘記了具體是哪個型號——可能是某種A型號,我以為我在這里寫下來了。然而,與我們今天擁有的更先進的核心相比,例如Grace芯片中的Neoverse核心,這是一個非常高效的CPU。但即使如此,執行一個CPU指令的成本仍然很高。即使那個指令是一個空操作,獲取指令、解碼、進行分支表查找以及在寄存器文件中進行亂序操作的成本是250皮秒焦耳。而執行一個16位整數加法的成本是32飛秒焦耳。所以,大部分開銷都來自于指令執行的輔助操作。因此,我認為在設計和優化硬件時,需要密切關注這些開銷,并努力減少它們。
在乘法運算方面,存在二次擴展現象。一個32位乘法的成本并不僅僅是8位乘法的4倍,而是比8倍還要貴,實際上是貴了16倍。浮點數的情況稍微復雜一些,但大致相同。其中還涉及到一個特殊的歸一化階段。你會發現,從內存中讀取數據的成本比所有這些操作都要昂貴,甚至比32位乘法還要貴。讀取一個相對較小的8k字節內存的成本更高。讀取內存的距離越遠,情況就會變得更糟。
我喜歡使用這種數量級的方式來描述,例如,如果我讀取一個本地的8k字節內存,每個字的成本是5皮焦耳。如果我必須穿過芯片并讀取,基本上是數百兆字節的內存,每個字的成本是50皮焦耳,但其中的內存部分仍然是5。你使用小內存陣列來構建大內存。因此,我們基本上有一個內存陣列大小,我們傾向于用于所有東西,因為在一個位線上,你只能有那么多位單元,在一個字線上,你只能有那么多單元。所以這是你的基本陣列大小。超過這個大小的任何東西都要使用多個陣列。所以另外的45皮焦耳是通信能量。這是將地址傳送到內存陣列并將數據傳送回來的成本。然后,如果你離開芯片,情況就會糟糕得多。LPR,這是你能得到的最節能的DRAM——實際上與HBM相當。現在,它大約是——我在試著回憶——大約是每比特5皮焦耳。讀取32位字,這就是為什么這樣,是640皮焦耳。
接下來,讓我來談談我們最近的一個最新加速器項目。我們從一個程序開始,實際上,它搜索加速器的設計空間。我們基本上給它我們的目標神經網絡,然后我們說,對于加速這個神經網絡,最好的加速器是什么?它搜索一堆參數——有多少處理單元。我們有這個向量MAC。我們有一堆向量MAC的通道。所以這是一個二維的東西,有很多向量和很多向量元素和很多通道——不同緩沖區的大小將會是多少。因此,它在搜索有限的設計空間。我們有一個有點風格化的東西,但它在變化所有的參數。它實際上可以將多個級別放入我們通過的scratchpad層次結構中。
在ICCAD的論文中,我們實現了大約每瓦特20萬億次的8位操作,你會意識到——這在技術上比Hopper落后一代。我認為是在12納米工藝,而Hopper是在5納米工藝——實際上,所以它是兩代技術之后。但我們仍然做得比較好,因為我們優化了很多東西,并且我們可以將這些應用到Hopper上。
更進一步的是,我們今年在JSSC上發表了一篇論文,而去年則是在VLSI電路研討會上發表了關于Magnetic BERT的研究成果。因此,我們完成了兩項工作。我們計劃將其應用于LLM,因為它正成為當下的熱門話題,而非ConvNets,MAGNe真正優化了這一點。另一方面,我們也想應用我們所有關于最佳裁剪和向量級別縮放的學習成果。因此,它支持向量級別的縮放。我們增加了額外的兩組乘法器,用于乘以激活和權重,以及縮放因子,使其能夠在基于32個元素的向量上運行。這使得我們能夠運行一種特殊的量化方法,我們稱之為VS-Quant INT4,而且可以在不損失精度的情況下運行BERT和BERT Large。因此,我們能夠通過最佳縮放實現4位量化的推理。
在這個圖表中,真正重要的數字——雖然我不會詳細解釋——是每特拉操作95.6瓦的能耗。因此,我們幾乎每瓦能夠達到100萬億次操作,比Hopper的效率提高了約10倍。而且這是在相同的工藝下實現的。順便提一下,我們在NVIDIA進行原型制作的方式是,等待有人發送這些大型800平方毫米芯片之一,然后我們會說:“好吧,你有800平方毫米的空間。顯然,我們可以從你那里借用一個毫米的角落。”這有點像坐在那里向別人借你的杯子用一下。我們會問:“我可以要一個毫米的空間嗎?”他們通常都會同意。因此,我們最終在一個大型GPU上啟動了這種實驗之一,我相信這是Hopper交換芯片,并回來——這些是實驗室的數據——效果非常好。我們能夠在上面運行BERT并取得出色的結果。因此,我認為這是我們希望在未來一些GPU中投入的原型,并顯示出我們有另一個比Hopper高10倍的因素要追求。
好的,讓我總結一下,并回答一些問題。
深度學習是通過硬件實現的,并且受到硬件的制約。算法和數據在之前的幾年里已經存在,它們就像是GPU的火花所需的燃料-空氣混合物。它擁有足夠的能量和馬力,在足夠大的數據集上以合理的時間訓練出足夠大的模型。
從那時起,我們的訓練需求增長了10的8次方倍,在petaFLOP天數方面,從AlexNet的10的負2次方增長到了GPT-4的10的6次方。為了應對這一挑戰,我們不得不提高GPU的性能。在過去的10年里,GPU性能提升了1000倍,而剩下的10的6次方倍的增長則來自于時間和GPU數量的增加。現在,人們使用近10萬個GPU的集群來訓練這些大型模型,并花費了幾個月的時間。這確實是一個巨大的投資,但人們正在獲得證明其價值的結果。
那么,我們將從哪里繼續前進呢?我之前已經提到了一些內容,盡管我沒有過多地討論稀疏性,因為我們對稀疏性還沒有一個明確的答案。然而,我仍然認為,未來最大的收益將來自于找到如何比我們現在從稀疏性中獲得的2比1更好的方法。當然,在數字方面還有很多工作要做。我談到了對數數字,它們在本質上比整數或浮點數更具優勢。雖然浮點數很接近,但對數數字通常具有最壞情況誤差,這種誤差比FP的最壞情況誤差要小約33%,因為每一步都經過了縮放。
最佳剪裁是一個巨大的收益。在選擇scale factor時,需要非常謹慎。我不知道最小均方誤差是否真的是最佳的度量標準,但它是一種容易量化和應用的度量標準,并且我們在此基礎上取得了良好的結果。當進行縮放時,需要選擇縮放的粒度。為每32或64個元素分配一個scale factor并不會帶來太大的成本。然后,可以縮放更小的數字組,使范圍更加緊湊,從而減少誤差。
接下來,我們構建了一系列加速器來驗證這些想法。我分享了其中的兩個:MAGNe和Magnetic BERT。Magnetic BERT的表現非常出色。它在BERT和BERT Large上實現了每瓦近100萬億次的操作,而且準確度幾乎可以忽略不計。這對我們來說實際上是一個驗證場,充分展示了向量縮放和最佳剪裁技術的優勢。在進行這種算法硬件協同設計時,這種驗證過程非常有益。我們正在努力探索如何——這總是需要一些時間和努力的。你設計了一個加速器,它只能完成一項任務。現在,我面臨的問題是,如何將這個設計轉化為未來一代GPU的指令?
----- 聽眾:你提到了稀疏性,我對目前正在使用哪些技術來優化網絡大小很感興趣。
Bill Dally:對,這實際上是一個不同的問題。對于網絡大小的優化,我們有一個團隊專門負責進行神經架構搜索。他們會在各種參數上進行搜索,例如層數、每層的通道數、層的大小以及它們之間的連接等。他們試圖找到一個在某種優化定義下最優的模型。當然,模型越大,通常準確性就越高。但如果受到執行時間或功耗的限制,他們通常會嘗試找到最小的模型以達到一定的準確度。這就是他們進行神經架構搜索的目的。
與此同時,他們還會進行網絡修剪,這是另一個軟件部分。我們實際上使用了幾種不同的技術。最簡單且被廣泛使用的方法是掃描一層中的權重,并根據權重的大小進行修剪。如果你希望達到某個層的密度,它會進行直方圖統計,找到那個點,并將所有低于該點的權重設為0。
我們還嘗試了一種更復雜但效果更好的方法,盡管它更昂貴。這種方法試圖計算每個權重的敏感度。它不僅關注權重的值,還關注與該權重連接的其它值對輸出的影響。通過查看敏感度,它能夠找到最不敏感的權重進行修剪。
這就是目前我們廣泛使用的兩種技術。
聽眾:我對于復雜的指令很感興趣。你提到了節省了很多能量,這包括了提取和解碼能量的節省,以及操作數加載的節省。我想知道你對這兩者之間的能量分配有什么看法,以及。..
Bill Dally:我目前沒有具體的分配數字。但我認為,在大多數情況下,提取和解碼的能量節省可能會占據主導地位。不過,我需要進一步查找和確認這些數字。
聽眾:關于縱橫交錯的體系結構,Google的TPU與NVIDIA之間在這方面的設計確實存在許多人工差異。
聽眾:NVIDIA沒有采用系統陣列來進行矩陣運算,是嗎?
Bill Dally: 我們進行的是規模較小的矩陣乘法。當我們使用FP16或BF16時,我們的核心元素是一個4乘4的矩陣,而Google的TPU則傾向于進行規模較大的矩陣乘法。我不記得具體的尺寸了,但其中一個尺寸是128乘128。我們沒有選擇這種做法的原因之一是,它會導致碎片化問題。如果你選擇了一個非常大的矩陣乘法作為基本元素,那么自然大小的矩陣可能并不是一個2的冪的整數倍。這可能會導致一些奇怪的情況。例如,如果你有一個4乘4的矩陣,你可能需要在某個地方四舍五入到3來適應它。但如果你有一個128乘128的矩陣,你可能會最終四舍五入到127,這將會非常耗費資源。然而,就矩陣乘法操作的效率而言,我認為我們做得更好一些。盡管我們沒有使用系統陣列,但這并不重要。因為我們在進行矩陣乘法時,幾乎所有的能量都消耗在數學單元中。實際上,只有一小部分,大約幾個百分點,不在數學單元中。所以,采用系統陣列的方式并不會帶來任何好處。問題在于,向矩陣乘法輸入數據的能量成本是多少?我們可能會因為進行較小的矩陣乘法而有一些額外的成本。我們從寄存器文件中為矩陣乘法器提供輸入。每次進行4乘4的運算時,我們都會進行一個264的寄存器提取——兩個4乘4的矩陣。然后得到結果,再進行下一個4乘4的運算,依此類推。我們在進行更大的矩陣運算時,可能會有一些額外的洗牌開銷,因為我們是以較小的顆粒度進行的。但即使這樣,我認為這只是噪聲,對總體性能的影響在10%左右。而Google仍然需要——他們仍然需要移動數據。他們必須將數據從任何地方移動到系統陣列的輸入端。如果他們的成本低于10%,我會感到非常驚訝。他們還有控制開銷。他們有一些小微控制器來告訴它,現在進行矩陣乘法運算,這也不是零成本。
聽眾:我想快速回到你之前提到的訓練模型部分,你提到了查看數字和權重的分布,并對這些數字進行剪裁。我可能錯過了一些細節,但我不太確定是因為硬件的改進使你能進行剪裁,還是因為軟件或者像FPGA這樣的可編程硬件。所以,在整個技術堆棧中。..
Bill Dally: 不,這幾乎完全是軟件實現的。我們已經有了可以使用的scale factor。這些scale factor讓我們能夠將數字縮放到適應我們數字系統表示的動態范圍。傳統的方法是選擇一個scale factor,以便能夠表示最大和最小的數字。通過剪裁,你只需要選擇一個更大的scale factor。基本上,你將每個數字乘以一個較大的量。然后,當你將其轉換為較低精度時,一些數字會被剪裁。我們使用飽和算術,所以這些數字會被限制在最大可表示的值。這主要是一種軟件技術。唯一涉及到硬件的部分——而我們無論如何都需要它,因為我們在進行——如果你進行縮放,你必須要有——在右上角的那個小乘法器,表示sw乘以sa,將兩個scale factor相乘,四舍五入,然后第二個乘法器——所以這兩個乘法器必須被添加進去,每當你進行縮放時。但一旦你進行了縮放,你可以選擇是否進行剪裁,以及任何你想要的粒度。你只需要為額外的scale factor的表示付費,如果你以更小的粒度進行縮放的話。
-
DRAM
+關注
關注
40文章
2311瀏覽量
183446 -
寄存器
+關注
關注
31文章
5336瀏覽量
120231 -
深度學習
+關注
關注
73文章
5500瀏覽量
121112
原文標題:NVIDIA首席科學家Bill Dally:深度學習硬件趨勢
文章出處:【微信號:算力基建,微信公眾號:算力基建】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論