過去十年機器學習軟體開發行業概覽

infoq 發佈 2024-04-29T06:33:47.638188+00:00

過去十年機器學習軟體開發行業概覽:英偉達 CUDA 壟斷地位下降,PyTorch 超越谷歌 TensorFlow作者 | Dylan Patel譯者 | 馬可薇策劃 | Tina在過去的十年間,機器學習軟體開發的格局翻天覆地。

過去十年機器學習軟體開發行業概覽:英偉達 CUDA 壟斷地位下降,PyTorch 超越谷歌 Tensorflow

作者 | Dylan Patel

譯者 | 馬可薇

策劃 | Tina

在過去的十年間,機器學習軟體開發的格局翻天覆地。流水的框架鐵打的英偉達,這些框架大多都極度依賴英偉達的 CUDA(統一計算架構),且在英偉達 GPU 上性能最好。不過,隨著 PyTorch 2.0 和 OpenAI 的 Triton 的到來,英偉達因其軟體護城河而在這一領域的制霸地位恐將不保。


本篇報告中將涵蓋以下主題:為何谷歌的 TensorFlow 輸給了 PyTorch,谷歌為何沒能利用其在人工智慧領域的早期領導地位,機器學習模型訓練時間的主要構成成分,內存容量、帶寬、成本牆,模型優化,為何其他人工智慧硬體公司至今無法撼動英偉達的統治地位,為何硬體地位逐漸重要,英偉達在 CUDA 上的競爭優勢是如何消失的,以及英偉達的競爭對手在大型雲的晶片訓練上所取得的重大勝利。


問題簡述是,英偉達閉源 CUDA 將不再涵蓋機器學習模型的默認軟體棧。英偉達雖然搶占先機,但卻讓 OpenAI 和 Meta 後來居上掌控了軟體棧,英偉達專有工具的失敗致使後者在生態系統中建立了自己的工具,英偉達的護城河也遭到了永久地削弱。

TensorFlow vs. PyTorch

僅僅幾年前,在相當分散的框架生態系統中,掌握最常用框架 TensorFlow 的谷歌作為領跑者,設計並部署了唯一成功的人工智慧指定應用加速器 TPU,他們看似已經搶占先機、準備好制霸機器學習行業了。



2019 年機器學習框架狀態,PyTorch 掌控研究領域,Tensorflow 掌控行業領域


可事實卻是 PyTorch 贏了,而谷歌沒能將先手優勢轉換為對新生機器學習行業的主導權。如今的谷歌使用自研軟硬體棧而非 PyTorch 和對應 GPU,導致其在機器學習社區的地位頗為尷尬,谷歌甚至還有另一套名為 Jax 的框架,直接和 TensorFlow 相競爭。


不僅如此,關於谷歌在搜索及自然語言處理方面的主導地位會因大型語言模型而衰退之類的言論也是甚囂塵上,尤其是來自那些 OpenAI 及各種利用 OpenAI 的 API 的、或基於類似基礎模型的初創公司。雖說可能是有些杞人憂天,但我們今天不談這些。目前來說,雖然挑戰不斷,但谷歌仍是處於機器學習模型的最前沿。谷歌所發明的 Transformer 在 PaLM、LaMBDA、Chinchilla、MUM,以及 TPU 等諸多領域依舊是最先進的。


讓我們回到 PyTorch 贏得一籌的話題中去。雖然也有從谷歌手中奪取掌控權的成分在,但 PyTorch 主要還是贏在了其相對 TensorFlow 而言更高的靈活性和可用性,從原則為先的角度來看,PyTorch 與 TensorFlow 的不同在於前者使用的是「動態圖模式(Eager Mode)」而非「圖模式(Graph Mode)」。

動態圖模式可被看作是一種標準的腳本執行方式。深度學習框架會隨調用立即逐行執行所有操作,這點和任何的 Python 代碼執行都一樣。因此,代碼的調試和理解也都更加容易,操作間的結果和模型表現也更直觀。


相較之下,圖模式則有兩個階段,第一階段定義需要執行操作的計算圖,其中計算圖是一系列代表操作、變量的相交節點,節點相連的邊則代表其間的數據流。第二階段定義延遲執行計算圖的優化版本。因為圖的執行過程中我們無從得知到底發生著什麼,所以這種分階段的方式讓代碼調試更具挑戰,也更難理解。這與「解釋性」和「編譯性」程式語言類似,可解釋的 Python 調試要比 C++更容易。


儘管現在 TensorFlow 也默認擁有了動態圖模式,但研究社區和多數大型技術公司都已經習慣了 PyTorch 的解決方案。至於 PyTorch 更勝一籌的深層解釋,請見這裡。總之,主流 AI 大會 NeurIPS 上最優秀的那些非谷歌的生成性人工智慧都是用的 PyTorch。

機器學習訓練組件

追根究底,影響機器學習的模型訓練耗時主要有兩個因素:1. 計算(FLOPS),即每層內運行密集的矩陣乘法 2. 內存(帶寬),即等待數據或層權重獲取計算資源。常見受帶寬限制的操作有歸一化、點式操作、SoftMax、ReLU。


曾經主要影響機器學習訓練時長的計算時間、等待矩陣乘法等因素,隨著英偉達 GPU 的不斷發展都已不再重要。英偉達的 FLOPS 在摩爾定律下英偉達的 FLOPS 在摩爾定律下提升了多個數量級,但主要架構變化還是集中在張量核心及低精度浮點格式上,內存方面則沒有太多變化。



英偉達 GPU 增長趨勢


2018 年的 BERT 模型和英偉達的 GPU V100 均是時代頂尖產品,我們不難發現,矩陣乘法已經不再是提高模型性能的主要因素。自此之後,最為先進的模型在參數數量上有了 3 至四個數量級的增長,而最快的 GPU 也有了一個數量級的增長。



PyTorch中操作類占比


即使是在 2018 年,純粹的計算性質工作負載在占據 99.8%的 FLOPS 同時,僅占用了 61%的運行時間。歸一化和逐點操作相較矩陣乘法而言,分別擁有 250 倍和 700 倍 FLOPS 的減少,但同時也消耗了模型近 40%的運行時間。

內存牆

隨著模型規模的不斷擴張,大型語言模型的權重本身便占據了千億、乃至太字節。百度和 Meta 所部署的生產型推薦網絡其中的大規模嵌入表就可占用幾十兆字節內存,大型模型訓練或推理中的大部分時間並沒有花在矩陣乘法的計算,而是在等待數據到達計算資源。或許你會問,為什麼架構師不把更多內存放在靠近計算模塊的地方?答案只有一個字,貴。



存儲層級


存儲層級所遵循的規律是從近且快,到慢但廉價的。共享內存池最近可以在同一塊晶片上,通常這種情況是由 SRAM(靜態隨機存取存儲器)組成。有的機器學習 ASIC 嘗試利用大型 SRAM 池保存模型權重,但即使是Cerebras價值約5百萬美元的晶圓規模晶片上也只有 40G 的 SRAM。我們沒有足夠的內存來容納 100B 以上的參數模型權重。


英偉達的架構常常會在晶片上使用更為少量的內存,當前一代 A100 包括了 40MB 內存,而下一代的 H100 上也只有 50MB。台積電 5 納米工藝節點上 1GB 的 SRAM 需要大約 200 平方毫米的矽,加上相關的控制邏輯和結構的實現後就需要超過 400 平方毫米的矽,或使用英偉達數據中心 GPU 總邏輯面積的 50%左右。考慮到 A100 GPU 超過 1 萬美元的價格,H100 的價格很可能也會兩萬美元起步,經濟層面上這條路行不通。就算我們忽略英偉達數據中心 GPU 的 75%毛利率(約為四倍加價),實現產品的完全產出所需要每 GB 的 SRAM 內存,成本仍在一百美元上下。


此外,晶片上 SRAM 內存的花銷並不會隨著傳統摩爾定律所帶來的工藝技術縮減而下降太多,在下一代台積電 3 納米工藝技術下,同樣 1GB 的內存成本實際是在增長的。3D SRAM 雖然會在一定程度上降低 SRAM 成本,但這也只是價格曲線的暫時下跌。


存儲層次中的下一層是緊密耦合的片外內存 DRAM。DRAM 相較於 SRAM,延遲要高上一個數量級(約 100 納秒和 10 納秒的區別),但 DRAM 也要便宜許多(DRAM 每 GB 一美元,SRAM 每 GB 一百美元)

數十年來 DRAM 一直遵循摩爾定律,事實上,在戈登·摩爾創造「摩爾定律」這個詞時,英特爾的主要業務就是 DRAM。摩爾關於電晶體密度與成本的經濟預測對 2009 年之前的 DRAM 通常都是準確的,但自 2012 年來,DRAM 的成本幾乎沒有提升。



DRAM 每 GB 價格


我們對內存的需求只增不減,目前 DRAM 已經占據了伺服器總成本的50%。內存牆的存在已經開始在產品中顯露出來了。相比英偉達 2016 年的 GPU P100,2022 年剛剛發售的 GPU H100 在內存容量上提升了五倍(16GB 到 80GB 的提升),而 FP16 性能卻提升了足足 46 倍(21.1 TFLOPS 至 989.5 TFLOPS)。


容量瓶頸與另一同樣重要的帶寬瓶頸息息相關。並行化是增加內存帶寬的主要手段,如今的 DRAM 每 GB 價格區區幾美元,而英偉達為了達到機器學習所需要的巨大帶寬而用上了 HBM 內存,這是一種由3D堆疊的DRAM層所組成的設備,且需要更為昂貴的包裝。HBM 的價格區間為 10 至 20 美元每 GB,其中包含有包裝與產量成本。


內存帶寬與容量限制在英偉達 A100 GPU 中被反覆提及。沒有大量優化過的 A100 常常會有極低的 FLOPS 利用率,FLOPS 利用率是通過計算(模型訓練時總計算 FLOPS)/(GPU 在模型訓練時間內理論可計算 FLOPS)而得出。


即使是在頂尖研究者所做的大量優化下,60%的 FLOPS 利用率對於大型語言模型訓練而言也算是非常高的了。剩下的時間都是開銷,包括等待其他計算或內存數據的空閒期,或為減少內存瓶頸而進行即時重新計算結果。


FLOPS 在 A100 至 H100 兩代間增長了 6 倍有餘,但內存帶寬卻只有 1.65 倍的增長,從而導致了許多對 H100 低利用率問題的擔憂。人們為讓 A100 繞過內存牆搞出了許多變通方案,而這種努力在 H100 上恐怕會只多不少。


H100為Hopper架構帶來了分布式共享內存和二級組播,其中不同 SM(可看作內核)可直接寫入其他 SM 的 SRAM(共享內存/L1 緩存)。此舉在有效增加緩存大小的同時,縮減了DRAM讀寫所需的帶寬。後續架構也將通過減少向內存傳輸的操作緩解內存牆的影響。值得注意的是,因為對 FLOPS 的需求會隨參數數量增加而立方擴展,對內存帶寬及容量的需求則常呈二次曲線發展,所以較大型的模型也更傾向於實現更高的利用率。

算子融合 - 治標不治本

同機器學習模型訓練一樣,明白自己所處狀態才能更精確地進行重要的優化。舉例來說,如果我們處於內存帶寬約束的狀態,時間全花在了內存傳輸上,那麼增加 GPU 的 FLOPS 並不能解決問題。而如果是處於計算約束的狀態,笨重的矩陣乘法非常耗時的話,那麼試圖通過將模型邏輯改寫成 C++來削減開銷也是沒效果的。


雖然 PyTorch 是通過動態圖模式增加了靈活性和可用性而贏得的比賽,但動態圖模式也不是完美的。在動態圖模式中執行的每個操作都需要從內存中讀取、計算,再發送到內存之後,才能處理下一個操作。在缺乏大量優化的情況下,這種模式將大大增加對內存帶寬的需求。


因此,動態圖模式中執行模型的主要優化手段之一是算子融合。用融合操作符的方式取代將每次的中間結果寫入內存,在一次計算中計算多個函數,從而儘可能減少對內存的讀寫。算子融合改善了操作符的調度,也削減了內存帶寬和容量的成本。



算子融合簡圖


這種優化方式常常需要編寫自定義 CUDA 內核,這可比簡單使用 Python 腳本要難多了。PyTorch 的內置變通方案長期以來在 PyTorch 內部實現了越來越多的操作符,這其中的許多操作符都只是將多個常用操作融合到一個更為複雜的函數中。


操作符的增加讓 PyTorch 中的模型創建更加輕鬆,隨著內存讀寫次數的減少,動態圖模式的性能也更快。但隨之而來的代價是 PyTorch 中運算符在短短几年內就膨脹至兩千有餘。



人們常說軟體開發者是懶人,但老實說又有誰不是呢。在熟悉了 PyTorch 中某個新增的操作符後,開發者們通常只會覺得這個新操作符能讓自己少些點代碼,而完全沒有意識到其中的性能提高。


此外,並不是所有的操作都能融合。大部分時間我們都在決定要融合哪些操作,又要將哪些操作分配給晶片和集群層面特定的計算資源。雖然一般來說算子融合的策略都多少有些類似,但根據架構的不同也會有所區別。

英偉達稱王

操作符數量的發展和其默認的首選地位讓英偉達受益很多,每個被迅速優化的操作符都是針對英偉達架構的,且對其他硬體並不適用。任何想要完整實現 PyTorch 的人工智慧硬體初創公司,都得靠高性能才能原生支持兩千多個且還在不斷增長的操作符。


在 GPU 上訓練高 FLOPS 利用率的大型模型所需的技術水平越來越高,為達到最佳性能所需花樣也越發繁多。動態圖模式的執行和算子融合,意味著軟體、技術、模型的開發都要被迫適應最新一代 GPU 的計算和內存比例範圍。


內存牆是任何機器學習晶片的開發者都逃不開的命運。ASIC 必須要能支持常用框架的同時,也要能支持混合使用英偉達及外部庫的、基於 GPU 優化的 PyTorch 代碼這一默認開發策略。因此,為圖更高 FLOPS 及更嚴格的編程模型,而主動放棄 GPU 的各種非計算包袱這種行為是非常沒有意義的。


易用性是王道。


要打破這種惡性循環的唯一方式是將英偉達 GPU 上運行模型的軟體,儘可能地無縫轉移至其他硬體上。隨著 PyTorch 2.0、OpenAI Triton,以及諸如MosaicML的MLOps公司所提供的模型架構穩定性和抽象逐漸得到主流承認,晶片解決方案的架構和性價比逐漸取代了英偉達卓越的軟體所帶來的易用性,成為驅動購買力的主要因素。

PyTorch 2.0

數月之前剛剛成立的PyTorch基金會正式脫離了Meta的掌握。在向開放式開發和管理模式轉變的同時,2.0 的早期測試版本已經發布,並預計於 2023 年三月全年上市。PyTorch 2.0 與前代最主要的區別在於,新增的一個支持圖執行模型的編譯解決方案,讓各種硬體資源的利用更加輕鬆。


PyTorch 2.0 在英偉達 A100 上的訓練性能有了86%的提升,CPU上的推理則有26%的提升,極大地縮減了模型訓練所需的計算時間和成本。而這種性能提升也可以類推至包括AMD、英特爾、Tenstorrent、Luminous Computing、特斯拉、谷歌、亞馬遜、微軟、Marvell、Meta、Graphcore、Cerebras、SambaNova 在內的多個 GPU 和加速器上。


PyTorch 2.0 的性能提升在未經優化的硬體上更為明顯。Meta 及其他公司對 PyTorch 的大量貢獻背後,是希望能在他們數十億美元的訓練集群上,以最小的努力實現更高的 FLOPS 利用率,讓他們的軟體棧更易於移植到其他硬體上,從而為機器學習領域引入新的競爭力。


分布式訓練也受益於 PyTorch 2.0,數據並行、分片、管道並行及張量並行均得到了更優秀的 API 支持。除此之外,PyTorch 2.0 也通過全棧提供了對動態圖形的原生支持,讓LLM不同序列長度等更易於支持。這也是主流編譯器第一次支持從訓練到推理的動態形狀。



PrimTorch

對任何非英偉達 GPU 之外的任何機器學習 ASIC 來說,想要編寫一個完整支持全部兩千餘個操作符的高性能後端是非常具有挑戰性的。而 PrimTorch 卻可以在保障 PyTorch 終端用戶可用性不變的前提下,將操作符數量減少至約 250 個原始操作符,讓非英偉達的 PyTorch 後端實現更簡單容易,定製硬體和作業系統的供應商也更容易提出自己的軟體棧。

TorchDynamo

穩健的圖定義是向圖模式轉變的必需品,而過去五年間 Meta 和 PyTorch 在這方面解決方案的嘗試都有著明顯的缺陷,直到 TorchDynamo 的出現。TorchDynamo 可接收任何 PyTorch 用戶腳本並生成FX圖,甚至是調用三方外部庫的腳本也可以。


Dynamo 將所有複雜操作都壓縮為 PrimTorch 中約 250 個原始操作符。圖成型後所有未使用的操作會被棄置,成型的圖決定了有哪些中間操作需要被存儲或寫入內存,有哪些可以被融合。這種方式極大地削減了模型內開銷,對用戶而言也是無感的。


目前在不修改任何源碼的前提下,TorchDynamo已在超過七千個PyTorch模型上通過了可行性測試,其中不乏來自 OpenAI、HuggingFace、Meta、英偉達、Stability.AI 的模型。這七千多個模型是從 GitHub 上熱度最高的 PyTorch 項目中直接選取的。



谷歌的 TensorFlow、Jax 及其他圖模式的執行管道,通常需要用戶自行保障模型對編譯器架構的兼容性,才能確保圖可以被捕獲。而 Dynamo 通過啟用部分圖捕獲、受保護的圖捕獲及即時重新捕獲進行改善。

  • 部分圖捕獲允許模型包括不支持或非 Python 的結構。在無法生成圖的模型構造部分插入圖斷點,並在部分圖之間以動態圖模式執行。
  • 受保護圖捕獲校驗被捕獲的圖是否可有效執行。保護是指需要重新編譯的代碼變更,畢竟多次重複執行的同一段代碼並不會重新編譯。
  • 即時重新捕獲允許無效執行的圖重新被捕獲。



PyTorch 意圖創建一個依賴 Dynamo 圖生成的、統一且流暢的 UX。這項解決方案在不改變用戶體驗的同時顯著提高性能,而圖捕獲意味著在大型計算資源的基礎上執行可以更高效地並行進行。


Dynamo 及AOT自動求導會在之後將優化後的 FX 圖傳入 PyTorch 本地編譯器層,即 TorchInductor。其他硬體企業也可直接取用此時的圖並輸入至他們自己的後端編譯器中。

TorchInductor

作為原生的 Python 深度學習編譯器,TorchInductor 可為多個加速器和後端生成快速代碼。Inductor(電感器)可接收包含約 250 個操作符的 FX 圖,並進一步將其操作符數量削減至 50 左右。在這之後,Inductor 會進入調度階段,融合算子並確定內存規劃。


之後,Inductor 會進入「代碼封裝」階段,生成可在 CPU、GPU 及其他人工智慧加速器上運行的代碼。封裝後的代碼可調用內核並分配內存,取代了編譯器堆棧中解釋器的部分。其中,後端代碼的生成部分藉助 OpenAI 的 GPU 語言 Triton,輸出 PTX 代碼。對 CPU 而言,英特爾編譯器所生成的 C++代碼也可以在非英特爾的 CPU 上運行。


後續還會新增更多對硬體的支持,但 Inductor 確實顯著降低了在編寫 AI 硬體加速器的編譯器時所需的工作量。此外,代碼性能也得到了優化,對內存帶寬和容量的要求也大大地降低了。

我們寫的編譯器不能只支持 GPU,而要能擴展到對各類硬體後端的支持。C++及(OpenAI)Triton 迫使著我們一定要具備這種通用性。——Jason Ansel – Meta AI

OpenAI Triton

OpenAI 的 Triton 語言對英偉達機器學習閉源軟體的護城河有著毀滅性的打擊。Triton 可直接接收 Python 腳本,或者更常見地接收通過PyTorch的Inductor堆棧的信息流。隨後 Triton 會將輸入轉換為 LLVM 中間表示並生成代碼,使用 cutlass 等開源庫取代英偉達的閉源 CUDA 庫(如 cuBLAS)。


CUDA 在專職於加速計算的開發者中更為常用,在機器學習研究者或數據科學家之間則沒什麼知名度。高效地使用 CUDA 並不容易,需要使用者對硬體架構有深入理解,並可能會拖慢開發過程。因此,機器學習專家們常常會依賴 CUDA 專家對他們的代碼進行修改、優化,以及並行化。


而 Triton 則彌補了這一差距,讓高層語言達到與底層語言相媲美的性能水平。Triton 的內核本身對一般的機器學習研究者而言具備可讀性,這一點對語言可用性非常重用。Triton 將內存凝聚、共享內存管理,以及 SM 內部的調度全部自動化,但對元素層面的矩陣乘法沒什麼太大幫助,後者本身已經足夠高效了。此外,Triton 在昂貴的逐點操作方面很有效,對涉及矩陣乘法的大型算子融合而言,也可明顯削減複雜如Flash注意力等操作的開銷。


時至今日,OpenAI 的 Triton 才正式支持英偉達的 GPU,不過很快就要不同了。數個其他硬體供應商都會在後續對其提供支持,這項開源項目的前途一片光明。其他硬體加速器能夠直接集成至 Triton 中 LLVM IR,意味著在新硬體上建立人工智慧編譯器堆棧的時間將大幅縮短。


英偉達龐大的軟體組織缺乏遠見,沒能利用自己在機器學習軟硬體方面的巨大優勢,一舉成為機器學習的默認編譯器。英偉達對可用性關注的缺失讓外界中 OpenAI 及 Meta 得以開發出向其他硬體方向移植的軟體棧。他們為什麼沒能為機器學習研究者們開發出一個像是 Triton 之類的*簡化版*CUDA?為什麼像是Flash注意力一類的技術是出自一個博士生而不是英偉達本身?


本篇報告中的剩餘部分將會列出能讓微軟拿下一城的具體硬體加速器,以及目前正被快速集成至 PyTorch 2.0 或 OpenAI Trion 軟體棧中多家公司的硬體產品。此外,報告中也將列出相反觀點,為英偉達在人工智慧培訓領域的護城河或實力提供辯護。


查看英文原文:How Nvidia’s CUDA Monopoly In Machine Learning Is Breaking - OpenAI Triton And PyTorch 2.0


本文轉載來源:

https://www.infoq.cn/article/9TFWk1rM2h8hLJUvbUG0

關鍵字: