NPU,何許人也?
說起近年來數(shù)字電路設(shè)計領(lǐng)域的弄潮兒,非“神經(jīng)網(wǎng)絡(luò)處理器 NPU”莫屬。它更廣為人知的花名,就是:AI芯片。
NPU與CPU、GPU等通用處理器之間最大的不同,就在于高度的專用性。作為一種典型的領(lǐng)域?qū)S眉軜?gòu)(Domain Specific Architecture, DSA),NPU是專門用于處理神經(jīng)網(wǎng)絡(luò)算法的。
神經(jīng)網(wǎng)絡(luò)算法良好表現(xiàn)的背后,是密集的運算。如果我們能夠為神經(jīng)網(wǎng)絡(luò)的處理這一任務(wù)定制一款架構(gòu),那么我們便能享受到更高的處理性能、更低的功耗。
舉個例子,同樣是進(jìn)行一次人臉識別,比起通用處理器,NPU不僅能更快地完成任務(wù),耗電還更少。反映到市場上,這些優(yōu)勢可就是真金白銀。
在這樣的需求下,大量的人力物力被投入于NPU的設(shè)計,使得這一概念早已走出了紙上談兵的階段。
而如今,擺在我們眼前的局面似乎是矛盾的。
一方面,在自研芯片的熱潮下,不少企業(yè)紛紛選擇了拿NPU來小試牛刀,讓人覺得NPU似乎已經(jīng)開始走向大規(guī)模的市場化。
但另一方面,NPU的研究熱仍然持續(xù)席卷著各大學(xué)術(shù)會議,宣告著:“理想的、終極形態(tài)的NPU還在路上。”
那么,有關(guān)NPU的研究到底進(jìn)入怎樣的技術(shù)階段了呢?亟待解決的問題和有潛力、前景的技術(shù)方向又有哪些呢?
處理神經(jīng)網(wǎng)絡(luò)模型,跟生產(chǎn)湯圓差不多?
既然是要設(shè)計專用的處理器,那么架構(gòu)自然得跟著目標(biāo)算法走。
(圖片來自Eyeriss Tutorial)
一個典型的神經(jīng)網(wǎng)絡(luò)模型常常由多個不同類型的層構(gòu)成。不了解每一層對于整個模型的表現(xiàn)有什么貢獻(xiàn)?沒關(guān)系!我們只需要憑著“不畏浮云遮望眼”的魄力,猛抓主要矛盾——算法中計算量最大的部分。
在典型的神經(jīng)網(wǎng)絡(luò)模型中,計算最密集的要屬卷積層和全連接層,而兩者對應(yīng)的運算都可以用矩陣乘法的形式來交給硬件處理。
打個比方,這是一個小規(guī)模的矩陣乘法運算,其中輸入矩陣x,權(quán)重矩陣w和輸出矩陣y的大小均為2×2。今天是元宵節(jié),咱們就用生產(chǎn)湯圓打個比方~
假設(shè)輸入矩陣中的四個元素分別代表著四種餡料:芝麻、紅豆、花生和草莓,而權(quán)重矩陣中的四個元素則對應(yīng)著原味、紫米、抹茶和芋頭這四種外皮,那么輸出矩陣的計算便可以看作是生產(chǎn)四袋湯圓,每一袋里有兩顆湯圓:比如y0這一袋里的兩顆湯圓分別是原味芝麻(x0·w0)和抹茶紅豆(x1·w2)口味的。也就是說,每一袋湯圓的生產(chǎn)離不開兩種操作:把外皮、內(nèi)餡揉在一塊兒(乘法)和把揉出來的湯圓按計劃裝袋(加法)。
脈動陣列結(jié)構(gòu),走向最強(qiáng)湯圓生產(chǎn)商的不二選擇?
一說到矩陣乘法,大家是不是突然明白了為什么那些研究深度學(xué)習(xí)的小伙伴跑實驗總是離不開GPU?因為GPU最擅長的,就是靠里面的大量運算單元,處理高并行度的運算任務(wù)。
那么在處理神經(jīng)網(wǎng)絡(luò)模型中的矩陣乘法運算時,GPU的不足之處在哪?
讓我們再次把目光投向湯圓的生產(chǎn)上來。
GPU所對應(yīng)的生產(chǎn)模式,就像是在工廠里雇傭了大量的師傅,他們各自知道自己當(dāng)前的任務(wù)是什么,但缺少對于整體的生產(chǎn)計劃的認(rèn)知。
于是,在這樣一家湯圓生產(chǎn)廠里,我們可以看到這樣的現(xiàn)象:師傅張三和李四分別被分配到了“揉一顆原味芝麻湯圓”和“揉一顆抹茶紅豆湯圓”的任務(wù),于是他們各自跑到倉庫去取原材料、跑回工位上揉湯圓、再把湯圓送回倉庫里;之后,師傅王五被分配到了“打包這兩顆湯圓”的任務(wù),于是他同樣地經(jīng)歷了“跑去倉庫取湯圓-跑回工位打包-把包好的湯圓送回倉庫”的三段式工作流程。
由于人手多,完成整個生產(chǎn)任務(wù)所需要時間仍然能讓人滿意,但是這樣的生產(chǎn)模式意味著極高的人力成本。同時,整體的生產(chǎn)效率更是比理想狀態(tài)要低得多:由于每位師傅都需要頻繁地往來于倉庫和工位,因此即使把生產(chǎn)室和倉庫間的通道建得再寬敞,他們的大部分工作時間都得花在倉庫里和去倉庫的路上。這就是“馮·諾依曼瓶頸”——頻繁的數(shù)據(jù)存取拖了處理性能的后腿。
問題就來了,怎樣才能建立起一套更合理的生產(chǎn)模式呢?
答案很簡單,需要管理者充分地利用自己對于目標(biāo)生產(chǎn)任務(wù)的了解,定制化地指揮各位湯圓師傅們相互配合、而不是各自為戰(zhàn)。
對于專用芯片架構(gòu)設(shè)計,這件事帶來的啟發(fā)是,應(yīng)當(dāng)把握、利用目標(biāo)算法的特征,盡可能避免不必要的遠(yuǎn)距離數(shù)據(jù)傳輸——谷歌TPU中采用的脈動陣列(Systolic Array)結(jié)構(gòu)便是一次成功的嘗試。
在脈動陣列結(jié)構(gòu)中,相鄰的處理單元(Processing Element, PE)之間是允許進(jìn)行數(shù)據(jù)傳遞的,且各PE有著自己的存儲資源來暫存數(shù)據(jù),這就為數(shù)據(jù)的復(fù)用提供了可能性。
整個運算過程是這樣的:權(quán)重值首先被載入脈動陣列并保持靜止;輸入值按照特定的排序方式自左向右地“流”過陣列,并在途經(jīng)的PE中參與運算;輸出值,也就是運算結(jié)果,將從陣列的底部“流”出。
通過這樣的方式完成運算的好處何在?回到老石湯圓廠:在整個生產(chǎn)過程中,每一種餡料和外皮盡管被使用到了兩次,但它們從倉庫中被取出的次數(shù)卻被成功地限制在了最低限度一次。
這是因為:每位師傅都被指定負(fù)責(zé)一種特定外皮的湯圓的制作,比如張三師傅(PE0)負(fù)責(zé)所有原味外皮(w0)的湯圓的制作任務(wù),李四師傅(PE1)則負(fù)責(zé)制作紫米外皮(w1)的湯圓,于是,每位師傅便可以反復(fù)地使用自己已經(jīng)取出的外皮。
另一方面,餡料也被允許在相鄰的師傅間傳遞。當(dāng)李四師傅需要芝麻餡(x0)的時候,他可以從左側(cè)的張三師傅那里得到,而不需要自己再跑一趟倉庫。
成也專用性,敗也專用性?
但是,這樣的脈動陣列結(jié)構(gòu)還稱不上是終極的解決方案。
盡管上面給出了一個理想的運算過程,但是需要注意的是,這是建立在目標(biāo)運算的規(guī)模與陣列的大小完美契合的前提條件下的,而這一點在應(yīng)用場景中其實是難以滿足的。
在實際的設(shè)計中,出于對峰值算力的追求,脈動陣列的尺寸不宜選擇得過小,比如谷歌的Cloud TPU v2配備了兩個128×128大小的PE陣列。
而目標(biāo)運算的規(guī)模卻是變化的:一方面,同一個神經(jīng)網(wǎng)絡(luò)模型中的不同層所對應(yīng)的運算規(guī)模是不同的;另一方面,在很多應(yīng)用場景下,待處理的神經(jīng)網(wǎng)絡(luò)模型也不是單一的。
用固化的硬件去應(yīng)對變化的運算需求,結(jié)果注定是“悲劇”。
這就好比咱們的湯圓廠里雇了大量的湯圓師傅來保證高生產(chǎn)力,而今天接到的生產(chǎn)訂單很小,但師傅完成訂單的時間并沒有變少:因為他們認(rèn)準(zhǔn)了只有位置最靠邊的師傅(陣列中最底側(cè)的PE)才能把湯圓送回倉庫,于是便執(zhí)著于無意義的傳遞行為。
換言之,專用的架構(gòu)大大簡化了對于控制邏輯的需求,但也使得處理器喪失了靈活處理問題的能力。
有人可能會有異議:通過更深入的定制化,可以把同一個算法模型中不同層的運算交給不同大小的脈動陣列,讓多個陣列以流水線的方式協(xié)同工作,實現(xiàn)運算規(guī)模與硬件資源的匹配。這其實是NPU設(shè)計中一種常見的理念,但簡單地倒向定制化會導(dǎo)致NPU在處理不同神經(jīng)網(wǎng)絡(luò)模型時的“徹底躺平”。
為什么完全的專用性并不適用于NPU?這似乎與我們對于“定制化”的一貫理解不太相符。
一切仍然得追溯到需求上。
由于神經(jīng)網(wǎng)絡(luò)算法仍在高速發(fā)展,關(guān)于“最優(yōu)的神經(jīng)網(wǎng)絡(luò)模型”之爭還遠(yuǎn)沒有蓋棺定論,這就注定了當(dāng)下的NPU仍然需要具備一定的通用性——假設(shè)企業(yè)花重金買了NPU,幾個月后卻發(fā)覺它們無法兼容更新、更有效的算法,那么顯然沒有人愿意為這樣的一錘子買賣買單。
這使得NPU始終無法在競爭中甩開GPU,證明自己才是加速神經(jīng)網(wǎng)絡(luò)模型處理的最佳選擇。
路在何方?
考慮到神經(jīng)網(wǎng)絡(luò)算法持續(xù)高速發(fā)展的大背景,NPU若想與GPU掰手腕、搶占市場份額,哪些技術(shù)方向可能成為突破口?
我認(rèn)為,思路大體上可以分為兩種:
1. 適度犧牲專用性,換取通用性;
2. 無視通用性,選擇徹底的定制化。
前者意味著在架構(gòu)中額外引入少量的控制邏輯和數(shù)據(jù)通路,用輕量級的硬件開銷去折中專用性與通用性。
對于這一思路,引入多少通用性、如何低成本地引入通用性等等都是需要重點考量的因素,也需要更便捷的生態(tài)作為支持。
硬件若是骨架,那么軟件便是靈魂。
換句話說,當(dāng)GPU能夠流暢地處理PyTorch、TensorFlow等主流深度學(xué)習(xí)框架構(gòu)建的網(wǎng)絡(luò)模型、而NPU卻不能的時候,市場很難更青睞后者。
第二種思路則更接近于設(shè)計專用處理器的初心——既然選擇了定制化,豈有被通用性局限住的道理?
考慮到通用性來自于“用相同的硬件運行不同的算法”的需求,如果能為每一個神經(jīng)網(wǎng)絡(luò)都定制相應(yīng)的處理器,無視通用性這一想法便站得住腳了。
因此,NPU設(shè)計自動化這一方向被寄予了厚望:當(dāng)用戶輸入自己搭建的神經(jīng)網(wǎng)絡(luò)模型的特征,工具便能自動地生成出對應(yīng)的、RTL級別的NPU設(shè)計。基于FPGA等可編程的器件,該設(shè)計能夠以較低的成本迅速走向物理實現(xiàn)。由此看來,追求極致的專用性也并不是空中樓閣。
結(jié)語
理論上,高度定制化的專用處理器能比通用處理器更高效地完成特定的目標(biāo)任務(wù)。
然而,由于神經(jīng)網(wǎng)絡(luò)算法領(lǐng)域自身仍然在高速地發(fā)展,NPU的DSA設(shè)計并不能完全地擺脫對于通用性的考量,這使得NPU遲遲無法表現(xiàn)出對于GPU的顯著優(yōu)越性。
但這并不意味著NPU這一概念是無意義的,一些技術(shù)方向上的潛在突破將成為NPU的取勝之匙。在后續(xù)的文章中,我們將結(jié)合在近期的頂級學(xué)術(shù)會議上匯報的相關(guān)研究進(jìn)展,為對這一炙手可熱的概念感興趣的朋友建立一個更加立體的認(rèn)知。
(注:本文不代表作者任職單位觀點。)