作為一家由多位前Google TPU開發(fā)者組建的芯片公司,Groq一經(jīng)成立便備受關(guān)注。2016年底,曾領(lǐng)導(dǎo)研發(fā)Google張量處理單元(TPU,用于加速機(jī)器學(xué)習(xí)而定制的芯片)的Jonathon Ross離職創(chuàng)辦了Groq,他們希望能為AI和HPC工作負(fù)載提供毫不妥協(xié)的低延遲和高性能。
不同于傳統(tǒng)的CPU和GPU架構(gòu),Groq從頭設(shè)計(jì)了一個張量流處理器 (TSP) 架構(gòu),?以加速人工智能、機(jī)器學(xué)習(xí)和高性能計(jì)算中的復(fù)雜工作負(fù)載。這個架構(gòu)不是開發(fā)小型可編程內(nèi)核并對其進(jìn)行數(shù)百次復(fù)制,而是容納一個具有數(shù)百個功能單元的單個處理器。?
Groq的軟件將深度學(xué)習(xí)模型編譯成指令流,所有這些都是預(yù)編排的。他們用“軟件定義硬件”的思路,將芯片中的控制和調(diào)度操作都交給軟件完成,從而減少相應(yīng)的硬件開銷,壓榨更多的性能。
目前,Groq主要面向云端推理領(lǐng)域。2021年4月,Groq宣布獲得3億美元新融資,用于開拓自動駕駛和數(shù)據(jù)中心行業(yè)市場。
近期,Groq首席架構(gòu)師Dennis Abts完整介紹了Grop公司研發(fā)的軟件定義橫向擴(kuò)展的張量流式多處理器(Tensor Streaming Processor,簡稱TSP)架構(gòu),主要包括搭建TSP架構(gòu)的背景及構(gòu)成,并說明了TSP的工作負(fù)載性能。
01?TSP的設(shè)計(jì)理念
Groq將軟件定義(software-defined)的方法引入到多處理器中軟硬件接口的設(shè)置問題。具體來說,靜態(tài)和動態(tài)(static-dynamic)界面來區(qū)分什么應(yīng)該在編譯時(shí)做,什么應(yīng)該在運(yùn)行時(shí)執(zhí)行;軟硬件接口由通過指令集架構(gòu)(ISA, instruction set architecture )來實(shí)現(xiàn),僅僅向編譯器暴露必要的體系結(jié)構(gòu)內(nèi)部狀態(tài)。?
我們將更多的控制權(quán)交給軟件,并將那些應(yīng)該硬件做的事交給芯片,而對于能在軟件中完成的事情,則更多的放在軟件堆棧中去做(在軟件堆棧中這些任務(wù)也能完成得更好)。?
面向確定性的設(shè)計(jì)(designing for determinism )要求我們在設(shè)計(jì)時(shí)作出選擇,并對該設(shè)計(jì)理念一以貫之。我們必須確保硬件可以完全由編譯器來控制,這不是要抽象掉硬件的細(xì)節(jié),而是要顯式地控制底層硬件。并且編譯器能夠清楚地了解硬件在任何給定周期內(nèi)的工作情況。
傳統(tǒng)的系統(tǒng)和CPU通常采用亂序執(zhí)行(out-of-order execution)和推測執(zhí)行(speculative execution)等技術(shù)在內(nèi)存層次結(jié)構(gòu)中暴露出附加的指令級并行(instruction level parallelism)和內(nèi)存并發(fā)性(memory concurrency)。
而Groq則采取了不同方式,只在一個220兆字節(jié)的scratchpad內(nèi)存中顯式分配tensor,以便編譯器知道tensor的位置以及它們?nèi)绾卧谛酒弦苿?。編譯器還可以利用大量的內(nèi)存并發(fā)性,我們通過分區(qū)的全局地址空間來對此進(jìn)行描述,并使其可以在整個系統(tǒng)中訪問。
由于系統(tǒng)中的處理單元會達(dá)到數(shù)以萬計(jì)(這些元素通常由異構(gòu)組件組成,例如CPU、GPU、SmartNICs、FPGAs,所有這些組件都具有不同的故障特征和性能概況),系統(tǒng)層面的復(fù)雜性通常也會不斷增加。
結(jié)果,系統(tǒng)的性能會發(fā)生變化,同時(shí)響應(yīng)時(shí)間也會延長,這些變化也會相應(yīng)地降低其他互聯(lián)網(wǎng)應(yīng)用程序的運(yùn)行速度,所有需要機(jī)器各部分協(xié)作完成的事情最終都會受到這種延時(shí)的影響。
因此,我們盡量避免在系統(tǒng)層面出現(xiàn)這種資源浪費(fèi)和濫用行為,同時(shí)引入新技術(shù)來幫助平衡系統(tǒng)負(fù)載,而無需在網(wǎng)絡(luò)層面使用自適應(yīng)路由和其他激進(jìn)技術(shù)。
02?TSP微架構(gòu):
軟件定義硬件意味著什么
接下來讓我們介紹微架構(gòu)。首先是從傳統(tǒng)的同構(gòu)眾核開始,每個核心都包含計(jì)算單元、整數(shù)單元、浮點(diǎn)單元、加載存儲單元和網(wǎng)絡(luò)接口。我們將這些功能單元分解并重新組織成SIMD功能單元,并將它們彼此相鄰放置,便于控制并利用其空間局部性。這看起來與傳統(tǒng)CPU有點(diǎn)不同,但執(zhí)行方式卻與傳統(tǒng)CPU一樣將較大的指令分解為微指令。同樣,我們將深度學(xué)習(xí)操作分解為更小的微操作,并將它們作為一個整體執(zhí)行,共同實(shí)現(xiàn)更大的目標(biāo)。
因此,如果我們只看芯片架構(gòu),會發(fā)現(xiàn)芯片是按照空間方向(spatial orientation)排列的,功能單元彼此相鄰布置。它們通過在彼此之間傳遞操作數(shù)和結(jié)果來相互協(xié)作,這種有效運(yùn)作方式稱作“鏈條化(chaining)”,可以將一個功能單元的輸出鏈接到相鄰下游功能單元的輸入。
在芯片上的大型MXM模塊是TSP架構(gòu)的主力,該模塊是矩陣單元,包含409,600個乘加器。換言之,我們可以通過芯片上的數(shù)據(jù)并行來利用大量權(quán)重參數(shù),這使得我們能提供巨大的計(jì)算密度,每平方毫米硅面積超過1 TeraOps。?
現(xiàn)在往回看,來看看GroqChip的抽象構(gòu)造。芯片上有多個不同的功能單元,這些單元組成了簡單的構(gòu)建塊,長度為320個元素(本處所指的是SIMD單元),每個SIMD單元由指令調(diào)度單元(位于芯片底部)控制。
這些功能單元彼此相鄰,正如軟件的不同分類一樣,這些不同的功能單元都有各自的用途,包括矩陣單元MXM,用于逐點(diǎn)運(yùn)算的vector單元,用于數(shù)據(jù)重塑的SXM單元(開關(guān)執(zhí)行模塊),以及一個用于處理片上存儲的存儲器單元。
它們在布局上彼此相鄰,以此來利用空間定向的優(yōu)勢。所以我們可以在芯片上采取東西向流式傳輸數(shù)據(jù),充分利用其空間局部性。從某種意義上說,它正在捕獲數(shù)據(jù)流的局部性,這在機(jī)器學(xué)習(xí)模型中很常見。
這種架構(gòu)使得ISA能夠賦能我們的軟件堆棧。我們顯式地將控制權(quán)移交給軟件,特別是編譯器,以便它可以從第一性原理的角度推斷硬件上的正確性和調(diào)度指令。?
具體來說,我們有144個片上指令控制單元,每個指令控制單元控制著與其相關(guān)聯(lián)的功能單元的調(diào)度。這使我們能夠?qū)⒄{(diào)度的硬件開銷保持在非常低的水平,僅僅不到3%的區(qū)域用于指令解碼和調(diào)度,同時(shí)將大部分芯片區(qū)域用于執(zhí)行功能模型。?
這使得編譯器能非常簡單地進(jìn)行提取,即每個功能單元與一組流寄存器文件(SRF,stream register files)交互。通過SRF提供的管道(conduit),數(shù)據(jù)輸入和數(shù)據(jù)結(jié)果被傳送到其他功能單元。
可以把SRF看作是連接不同功能單元的tensor裝配線,這些流寄存器是非常簡單的模型,編譯器可以推斷每個流寄存器之間只有單周期跳(one-cycle hop)。在加載存儲或網(wǎng)絡(luò)引用中沒有仲裁節(jié)點(diǎn),沒有提示,也沒有重新排序。因此,編譯器確實(shí)擁有預(yù)言性信息,以此推斷其生成的每個程序的正確性。?
該功能的核心是指令集,它是用于在機(jī)器學(xué)習(xí)模型上運(yùn)行的特定領(lǐng)域指令集。具體來說,我們采用conv.2d之類的機(jī)器學(xué)習(xí)操作,并將它們分解為一組微指令,這些指令在每個不同功能單元的芯片上執(zhí)行。它們協(xié)作產(chǎn)生更高級別的指令,如conv.2d或max pooling操作,并且根據(jù)每個功能單元將指令分解為不同的指令集。?
硬件本身支持的數(shù)據(jù)類型是INT8、UINT8以及FLOAT16,處理逐點(diǎn)元素的向量處理器支持包括FP32在內(nèi)的超集。
所以如果只看TSP的功能單元,每個功能單元都有一定數(shù)量必備指令,即取指、無操作(No-Op)和同步。這些是協(xié)調(diào)執(zhí)行所必需的基本指令。?
芯片的核心是矩陣乘法單元。矩陣引擎通過具有320個元素的向量進(jìn)行操作,每個矩陣中有320個特征,提供320x320整數(shù)運(yùn)算。對于浮點(diǎn)運(yùn)算,我們可以做320x160,可以同時(shí)處理整數(shù)和浮點(diǎn)數(shù)。浮點(diǎn)有點(diǎn)獨(dú)特,因?yàn)橐粚ψ止?jié)平面(byte planes)協(xié)作產(chǎn)生一個FP16的輸出。?
芯片的中間是矢量執(zhí)行模塊(VXM,vector execution module),它是機(jī)器學(xué)習(xí)模型中常見的向量逐點(diǎn)運(yùn)算,例如GELU或ReLU,并且向量單元中存在其他超越函數(shù)(transcendental functions)以利用逐點(diǎn)操作。
每個矢量通道支持16個ALU(網(wǎng)絡(luò)算術(shù)邏輯單元,Arithmetic Logic Unit),并且通過內(nèi)存功能單元(memory functional unit)連接到在SRAM(靜態(tài)隨機(jī)存取存儲器,Static Random-Access Memory)中的片上內(nèi)存。內(nèi)存功能單元在芯片上有88個切片,每個切片每次可讀取一次。所以原則上內(nèi)存系統(tǒng)最多支持176路并發(fā)執(zhí)行,這是大量可利用的內(nèi)存并發(fā)。?
最后,SXM(switch execution module)是一個開關(guān)執(zhí)行模塊。SXM就像是一把瑞士軍刀,來處理數(shù)據(jù)操作、數(shù)據(jù)重塑、片上數(shù)據(jù)搬運(yùn)和片外數(shù)據(jù)搬運(yùn)。如上圖所示,C2C IO、PCIE也由這個SXM單元處理。
03?系統(tǒng)概覽:
封裝、拓?fù)洹⒙酚珊土骺?/strong>
接下來如何將這些組件封裝,進(jìn)而組建成一個系統(tǒng)?首先是將GroqChip與散熱器封裝在一張卡上,然后將八張這種卡集合成一個GroqNode,最后再將八個GroqNode加一個備用包打包到一個GroqRack中,并使其在云端也可訪問。
這種橫向擴(kuò)展排列方式非常獨(dú)特。第一,它利用封裝層次來制作低直徑網(wǎng)絡(luò),這利用了蜻蜓拓?fù)洌╠ragonfly topology),而蜻蜓拓?fù)溆掷昧朔庋b局部性(packaging locality)。它創(chuàng)建了所謂的軟件調(diào)度的直連網(wǎng)絡(luò)(software-scheduled direct network),支持每個TSP上的16個直接相連的芯片到芯片鏈路進(jìn)行通信。?
橫向擴(kuò)展組織利用較小的網(wǎng)絡(luò)直徑將多達(dá)8個芯片打包到一個節(jié)點(diǎn)中,這8個芯片使用28根電線連接到它們的7個中轉(zhuǎn)點(diǎn),這些電線被放置在每個節(jié)點(diǎn)底層,使我們能夠豐富地連接單個節(jié)點(diǎn)內(nèi)的8個TSP,以再次利用封裝的局部性。這些節(jié)點(diǎn)使用電線連接,較長的電線將在機(jī)架到機(jī)架網(wǎng)絡(luò)(rack-to-rack network)之間使用光纜。?
蜻蜓拓?fù)涫欠謱油負(fù)?。它首先通過識別這8個TSP構(gòu)建成一個組,每個TSP都公開四個全局端口,所以8×4是32個端口。這32個虛擬端口用于連接全局系統(tǒng),使能夠連接多達(dá)30到32個單個系統(tǒng)中共計(jì)264個TSP的對等節(jié)點(diǎn)。
我們可以實(shí)現(xiàn)這個想法,并將這個機(jī)架作為本地組,如此一來,我們將能夠在系統(tǒng)中連接多達(dá)145個機(jī)架,從而實(shí)現(xiàn)超過10000 TSP的總可擴(kuò)展性。?
Groq的橫向擴(kuò)展拓?fù)涫褂抿唑淹負(fù)鋪硗耆B接機(jī)架內(nèi)的八個全局節(jié)點(diǎn)集,如下圖所示。
該結(jié)構(gòu)提供了一個備用節(jié)點(diǎn)作為熱備用(hot spare),并利用網(wǎng)絡(luò)的邊緣和節(jié)點(diǎn)對稱性來提供n+1冗余,由此提高系統(tǒng)彈性。
04?全局同步網(wǎng)絡(luò)
這個系統(tǒng)組織的核心是全局同步網(wǎng)絡(luò)。當(dāng)然,目前這個網(wǎng)絡(luò)并不是真正同步的,因?yàn)橄到y(tǒng)中的每個節(jié)點(diǎn)都還沒有統(tǒng)一的全局時(shí)鐘。我們提供了同步行為的假象,還特別使用了一系列硬件和軟件技術(shù)、硬件對齊計(jì)數(shù)器和軟件對齊計(jì)數(shù)器,幫助檢測何時(shí)發(fā)生漂移并補(bǔ)償漂移。
全局同步網(wǎng)絡(luò)由多同步鏈路組成,這意味著它們大部分是同步的,在驅(qū)動每個鏈接的時(shí)鐘晶體的容差范圍內(nèi)是同步的。正是對于這一點(diǎn)的利用,使得我們能夠檢測到漂移何時(shí)發(fā)生,并通過硬件和軟件技術(shù)對其進(jìn)行補(bǔ)償。
再次強(qiáng)調(diào),在這個部分必須啟用ISA支持,以便能夠?qū)@些芯片間的鏈接進(jìn)行糾偏(我們有特定的指令支持糾偏)。
此外,這些鏈接不是硬件流控制,而是軟件流控制。軟件控制鏈接的運(yùn)行節(jié)奏,以確保它們永遠(yuǎn)不會溢出或下溢。該鏈接的核心是前向糾錯,這樣就可以在每個網(wǎng)絡(luò)鏈路上都有一個固定的延遲,讓編譯器能夠推斷出需要消息傳遞的時(shí)間。
從概念上講,這些計(jì)數(shù)器在機(jī)器剛復(fù)位時(shí)相互獨(dú)立,然后將它們放入鎖步(lock step),可能會隨著時(shí)間的推移略有漂移,但我們會消除偏移并將它們重新放入鎖步。這就是我們?nèi)绾卧诜植际较到y(tǒng)中保持同步行為的方法。
不同于傳統(tǒng)網(wǎng)絡(luò)依賴硬件判優(yōu)機(jī)制來動態(tài)競爭一組輸出端口,我們讓編譯器可以調(diào)度所有物理網(wǎng)絡(luò)端口,使它可以像調(diào)度ALU或矩陣一樣調(diào)度網(wǎng)絡(luò)鏈接。傳統(tǒng)方法只會對網(wǎng)絡(luò)中的擁塞做出反應(yīng),而不是對擁塞做出反應(yīng)后進(jìn)行自適應(yīng)路由,以試圖改善因競爭而導(dǎo)致的熱點(diǎn)(hot spots)問題。?
相反,我們的首要原則是完全避免競爭,并將流量模式分散到網(wǎng)絡(luò)上的可用路徑多樣性中,以顯現(xiàn)和利用額外的對分帶寬。
我們將tensor視為消息,換句話說,我們將tensor作為數(shù)據(jù)包進(jìn)行路由,這些連續(xù)的向量流在時(shí)間上背對背出現(xiàn),形成一個tensor。這使我們能將消息構(gòu)建為向量序列,能夠非常有效地在網(wǎng)絡(luò)上對消息進(jìn)行編碼,而編碼開銷僅為2.5%。
05?確定性的負(fù)載平衡
同時(shí),利用最小和非最小路由是我們這個想法的核心。系統(tǒng)中的每個TSP在每個源目標(biāo)對之間都有一個最小路徑,但是也有很多非最小路徑。在這種情況下,編譯器可以查看張量的大小,并決定在其上傳播多少條路徑,以最大限度地減少在網(wǎng)絡(luò)傳輸時(shí)的序列化延遲。
這使我們能夠進(jìn)行所謂的確定性負(fù)載平衡,而不必使用更傳統(tǒng)的自適應(yīng)路由方法去適應(yīng)或響應(yīng)網(wǎng)絡(luò)中的擁塞。傳統(tǒng)的方法有其自身的問題,因?yàn)橹荒芸吹揭恍〔糠志W(wǎng)絡(luò),只能查看輸出端口的擁塞狀態(tài),這可能導(dǎo)致做出錯誤的決定,選擇一條可能比目前路徑更擁擠的糟糕路徑。
我們的方法做出了更好的權(quán)衡,它允許編譯器對所有物理鏈路進(jìn)行負(fù)載平衡,就像我們對芯片上的任何其他功能單元進(jìn)行負(fù)載平衡一樣。
Groq芯片間鏈路的核心是簡化的通信協(xié)議和流量控制。流量控制是由軟件明確驅(qū)動的,沒有硬件流量控制,所以軟件必須確保它們不會溢出或下溢,我們設(shè)計(jì)的就是保證確定性成為首要原則,這也是設(shè)計(jì)的基石。
如果看一下傳統(tǒng)的RDMA類型的請求,我們向目標(biāo)發(fā)出讀取請求,并且該讀取將造成內(nèi)存事務(wù)(memory transaction),然后將這個回復(fù)回流到網(wǎng)絡(luò),以便以后使用。?
更簡單的方法是讓編譯器知道正在讀取的地址,并且數(shù)據(jù)只在需要時(shí)通過網(wǎng)絡(luò)推送,以便在源頭使用。這使得我們能夠以更少的網(wǎng)絡(luò)消息和更少的開銷來實(shí)現(xiàn)更高效的網(wǎng)絡(luò)傳輸。
06?可靠性
我們在整個系統(tǒng)中利用了TSP和網(wǎng)絡(luò)內(nèi)的冗余。例如制造良率的問題,芯片實(shí)際上是由21條超級通道構(gòu)成的,而我們只使用了20條,因此可以允許出現(xiàn)一條無效的超級通道。這意味著我們可以在編譯器中隱藏備用的超級鏈接,實(shí)際上也確實(shí)將硬件細(xì)節(jié)隱藏在其中。
這使我們能夠使用一個全優(yōu)的芯片,其能夠包容目前領(lǐng)域可能存在的一些缺陷。
此外,每個架構(gòu)內(nèi)的冗余電源和冗余節(jié)點(diǎn)提供了額外的冗余。不僅如此,確定性還簡化和改進(jìn)了ASIC的設(shè)計(jì)過程,設(shè)計(jì)和驗(yàn)證可以通過硬件和軟件需要確保的一些假設(shè)來表達(dá),并保證硬件和軟件需要確保彼此進(jìn)行驗(yàn)證。例如,硬件制造的任何保證需要作為軟件假設(shè)進(jìn)行驗(yàn)證。
軟件堆棧對可靠性和冗余性起著重要作用,特別是在運(yùn)行時(shí)層面處理異常處理時(shí)。這就是為什么所有鏈路都需要前向糾錯,如果遇到錯誤,則需要軟件重演(software replay),并且通過運(yùn)行時(shí)處理。
為了保護(hù)所有片上數(shù)據(jù)結(jié)構(gòu),我們使用單糾錯和雙檢測(SECDED)來保護(hù)所有數(shù)據(jù)路徑、所有流寄存器、所有指令緩沖區(qū)和芯片上的指令提示。我們稱這種方法為無處不在的ECC。
既然開銷很容易計(jì)算,那么我們可以利用這一點(diǎn)。在這個問題上偏執(zhí)一點(diǎn)是值得的,因?yàn)榇_實(shí)有過無記載數(shù)據(jù)損壞,我的谷歌前同事在他們的論文《cores that don't count(不算數(shù)的內(nèi)核)》中聲明了這一點(diǎn)。重要的是,我們要成為客戶數(shù)據(jù)的好管家。
因此,我們需要保護(hù)所有關(guān)鍵的硬件結(jié)構(gòu),在這個圖中,每一個被編號的灰色框都是流寄存器,SECDED保護(hù)著它們的安全,當(dāng)張量在芯片流動時(shí),我們可以對它再次保護(hù)。
此外,我們希望提供異常處理來避免常見問題,例如算術(shù)異常,算術(shù)溢出或下溢,可以通過提前決定異常語義來處理先驗(yàn),例如編譯器可以通過使用飽和指令來避免任何算術(shù)溢出,比如加減飽和或乘以飽和。這讓我們可以避免值溢出,并將溢出位精度精確到一個很小的值。
07?負(fù)載評估
因此,如果查看我們獨(dú)特的工作負(fù)載,會發(fā)現(xiàn)它們往往都與線性代數(shù)有關(guān),因?yàn)檫@是機(jī)器學(xué)習(xí)以及許多HPC代碼的主力。舉個例子,看一下喬里斯基分解(Cholesky Factorization),它使用塊循環(huán)將這個三角形元素?cái)U(kuò)展到多個芯片。
我們在TSP上實(shí)現(xiàn)了BERT和BERT Large的最先進(jìn)的結(jié)果,并展示了如何真正有效地完成一般矩陣乘法。最后,當(dāng)我們準(zhǔn)備進(jìn)行通信時(shí),就能體會到所有上述優(yōu)點(diǎn),即使我們的引腳帶寬比競品芯片少,也能夠更好地利用該引腳帶寬,并采取細(xì)粒度通信的優(yōu)勢,換句話說,小張量在這個網(wǎng)絡(luò)上可以非常有效。
08?總結(jié)
簡單總結(jié)一下。首先,所有這些內(nèi)容都是為了使編譯器更高效且更輕量級,從編譯器取得的快速進(jìn)展就可以看出,我們已經(jīng)能夠更廣泛地編譯各種不同類型操作的模型。因此,從更廣泛的角度來看,我們試圖實(shí)現(xiàn)的是可預(yù)測和可重復(fù)性的性能,以在整個系統(tǒng)中提供低延遲和高吞吐量,以及支持軟件定義的硬件方法。
我們不是要通過抽象去掉細(xì)節(jié),而是要控制底層的硬件。我們希望公開一組正確的架構(gòu)可見狀態(tài),將其交給編譯器,它可以從第一性原理推斷正確性,使軟件和異常處理分別在編譯時(shí)和運(yùn)行時(shí)處理。
最后,我們啟用了同步通信模型,該模型使得在非常大的系統(tǒng)中進(jìn)行無鎖通信,這是我們希望能夠幫助到你的超級力量。
審核編輯:劉清
評論
查看更多