設計神經網路硬體架構時,我們在思考些什麼?(上)| 硬創公開課
基於神經網路的人工智慧近年取得了突破性進展,正在深刻改變人類的生產和生活方式,是世界各國爭相發展的戰略制高點。
神經網路作為實現人工智慧任務的有效演算法之一,已經在各種應用場景獲得廣泛的應用。從雲端到移動端,不同應用場景也對神經網路的計算能力提出了不同的需求。
神經網路的廣泛應用離不開核心計算晶元。目前的主流通用計算平台包括CPU和GPU,存在著能效較低的問題(能效即能量效率,是性能與功耗的比值)。為了獲得更高的能效,我們需要設計一種專用的神經網路計算晶元來滿足要求。國際IT巨頭,如英特爾、谷歌、IBM,都在競相研發神經網路計算晶元。
然而,神經網路的結構多樣、數據量大、計算量大的特點,給硬體設計帶來了巨大挑戰。因此,在設計面向神經網路的高性能、高能效硬體架構時,我們需要思考清楚以下三個問題:
好的計算模式應該是怎樣的?
為了支持這樣的計算模式,架構應該怎樣設計?
已經實現的硬體架構,針對具體演算法和應用需求,如何配置成最優的計算模式?
雷鋒網本期公開課特邀請到清華大學微納電子系四年級博士生塗鋒斌,為我們分享神經網路硬體架構的設計經驗。他將通過介紹其設計的可重構神經網路計算架構 DNA (Deep Neural Architecture),與大家分享在設計神經網路硬體架構時需要思考的問題。他在完成設計的同時,解決了這些問題,並對現有的硬體優化技術做出了總結。
本文根據雷鋒網硬創公開課演講原文整理,並邀請了塗鋒斌進行確認,在此感謝。由於全文篇幅過長,分(上)(下)兩部分,敬請期待。
公開課視頻: 設計神經網路硬體架構時,我們在思考些什麼_騰訊視頻 https://v.qq.com/x/page/r0504zxvl3j.html
各位觀眾晚上好,我是來自清華大學的塗鋒斌,今天非常榮幸收到雷鋒網(公眾號:雷鋒網) AI 科技評論的邀請,在此給大家做一節硬創公開課,主題是《設計神經網路硬體架構時,我們在思考什麼?》
首先做一個自我介紹。我是清華大學微納電子系的博士生塗鋒斌,今年直博四年級,我的導師是魏少軍教授和尹首一副教授,博士課題是高能效神經網路加速晶元設計,研究興趣包括深度學習,計算機體結構及集成電路設計。
我作為核心架構設計者,完成了可重構神經計算晶元 Thinker 的設計。該晶元作為清華大學代表性成果,參加了 2016 年全國雙創成果展,獲得李克強總理的高度讚許。相關研究成果已經發表數篇國際頂級會議和權威期刊論文。
本次公開課將從以下五個方面展開。
研究背景
我將介紹神經網路的一些背景知識及特點,它們給硬體設計帶來哪些挑戰?
計算模式
從演算法和調度的角度分析神經網路需要怎樣的計算模式;而基於優化的計算模式,我們需要怎樣的架構支持神經網路的計算?
架構設計
針對計算模式的需求,如何設計高性能、高能效的神經網路計算架構?可重構神經網路計算架構 DNA(Deep Neural Architecture)具有哪些特點?
實驗結果
DNA 的性能與能效表現如何?與頂尖工作相比的情況如何?
總結思考
針對神經網路硬體架構的設計展開一些思考和討論。
在經過前面的學術風暴後,我將打開攝像頭與大家互動,進入提問環節。
一、研究背景
無處不在的神經網路
隨著人工智慧時代的到來,圖像識別、語音識別、自然語言處理等智能任務在生活中無處不在。而神經網路作為當前實現這類智能任務最有效的演算法之一,已經獲得廣泛的應用。
比方說:
百度圖片搜索;
微軟語音識別;
谷歌在線翻譯;
……
可以說,神經網路在我們的生活中真是無處不在。
那麼什麼是神經網路?我們不妨從神經元開始理解。如圖所示,這是一個生物上的神經元。它由樹突、細胞體、軸突和神經末梢這四個部分構成。
1. 通過樹突接受輸入信號;
2. 在細胞體內進行信號處理;
3. 通過軸突和神經末梢把輸出信號傳至其它神經元;
4. 而大量的神經元就構成了我們的神經系統。
而這就啟發了人工神經元模型的誕生。我們可以看到,它的示意圖其實與神經元是十分相似的。它仍然由左邊的多個輸入,經過加權求和與非線性運算得到輸出。
一個簡單的神經元能做些什麼?
舉個簡單的例子。在空間中有紅色和藍色兩類點。用簡單的神經元,我們可以在空間中做一套曲面,將這兩類點分開。這就是一個非常簡單的分類問題。神經網路/神經元非常擅長用於做分類問題。
那麼,當我們有很多神經元後,我們可以得到一個神經網路,它又能用來做什麼?
這幅圖給出了一個非常簡單的典型單層神經網路。其中的每一個圓圈代表一個神經元,它們相互連接,就構成了一個神經網路。一個相對複雜的結構可以做些什麼?
如圖所示,空間中仍然有紅藍兩種顏色的點,我們採用了相對複雜的神經網路,可以在空間中畫一條分類的曲面,我們可以看到,問題比剛才的問題難度更大,圖中的這條粉色線勾勒出的這條曲面,才能對複雜問題進行分類。
在 2012 年,神經網路 AlexNet 在 ImageNet 圖像分類競賽上取得突破,獲得了 85% 的準確率,相較於之前最好的識別率提升了 10% 以上。這是一個非常大的突破,在當時引起了非常廣泛的關注。而現在,每年舉辦的 ImageNet 的識別精確度已經超過了 95%,已經超過人類識別圖片的能力。這是一個非常驚人的結果。直至今年,每年拔得頭籌的團隊都是採用神經網路。
AlexNet 是一個非常典型的、被大家廣泛研究的神經網路,因為它的層次很深,共有 8 個層次,人們也稱之為深度神經網路,而基於深度神經網路的機器學習演算法,我們也給它取了一個非常好聽的名字叫「深度學習」。大家經常會在媒體上聽到詞,其實它的本質依然是神經網路。
各種應用場景對神經網路的需求
而正是因為神經網路如此強大的能力,目前廣泛地應用於各種應用場景,例如:
雲端:公司會架設一些伺服器來提供人工智慧的服務;
移動端:無論是智能手機、智能汽車、無人機或是機器人,都會運用神經網路實現圖像識別、物體跟蹤和語音識別的智能任務。
而不同應用場景對神經網路也提出了不一樣的計算需求,比如:
在數據中心,大家非常關注計算的性能和並行度,對功耗的需求並不大,當然,功耗自然是越低越好;
而在無人機的應用場景下,大家會關注在滿足最基本的識別或智能需求,保證性能的前提下,儘可能地降低功耗。因為在移動端,電池容量非常有限,對低功耗自然有著很強的需求。
現有通用計算平台的不足
然而,現有通用計算平台(CPU、GPU)具有一些不足。
以 CPU 為例,它的性能差,能效低。能效是能量效率的簡稱,是性能與功耗的比值。我們通常用 GOPS/W (千兆操作數每秒每瓦) 的單位來描述能效,它是一個非常好地衡量計算效率的指標。
我們這裡討論的能效是考慮了片外存儲的系統級能效。後面提及的能效也是指的同一概念。
我們在伺服器上做了一個實驗,在 CPU 上計算 AlexNet 需要 254.5 ms,相當於處理 4-5 張圖片,而功耗需要 80 W,總能效為 0.2 GOPS/W。而同樣的情況在 GPU 上計算,總能效為 1.7 GOPS/W,我們希望能效能達到 100 GOPS/W 甚至更高。
神經網路的三大特點
但是,神經網路的三大特點給硬體加速帶來巨大挑戰。
挑戰一:不同網路的層次不同
我們列舉了四個非常經典的神經網路,分別是 AlexNet(11 層)、VGG(19 層)、GoogLeNet(22 層)與 ResNet(152 層),我們可以看到,因為識別精度的不同,我們往往會設計更深更複雜的神經網路,會導致網路層次變多,給硬體加速帶來很大挑戰。
-
挑戰二:不同層的類型不同
同樣以 AlexNet 為例子,神經網路由三種主要層類型組成,包括卷積層(CONV)、池化層(POOL)與全連接層(FC)。圖中紅框部分即為卷積層,而藍框部分屬於池化層,綠框部分為全連接層。每一層的計算都有些許不同。
挑戰三:不同層的參數多樣,數據量、計算量大
以 AlexNet 為例,最左列呈現了所有層的類型和名字,後面的一系列參數表示它的核尺寸、步長、輸入輸出圖尺寸等。因為參數不同,它們的數據量與計算量都不同,且非常大。
在卷積層上,它的計算量非常大;而全連接層中,計算量相比卷積層稍小,但數據量尤其是權重量則非常大。
這三大特點仍然使硬體加速的實現帶來一些挑戰。
1. 不同網路的層數、參數不同——計算的靈活性比較高
2. 不同層的類型不同,參數多樣——計算複雜度高---降低硬體的性能
3. 數據量、計算量大——提高功耗
總體而言,我們需要一個靈活高效的硬體架構支持我們的神經網路。
我們的設計目標和實現
這樣一來,我們的設計目標就確定了,即設計一個面向神經網路的高能效計算架構,它需要具備以下三個特點:
首先它要靈活支持不同網路;
其次要兼顧性能與能效;
再者,在針對不同的應用場景,我們得以進一步優化性能或能效,即選擇進一步偏向性能優先的實現,或是偏向能效優先的實現。
在本次公開課裡面,我們會以我實現的一個計算架構為設計實例,展開我的一些討論和思考。
設計實例是一款面向卷積神經網路(CNN)的計算架構,架構的代號叫做「DNA」,它主要具有三大特點:
特點一:可重複的數據傳輸通路
可以支持混合的數據服務模式來提高能效。
特點二:可重構計算引擎
可以支持高效的映射方法,同時兼顧靈活性和性能。
特點三:具有調度框架
可以重複 DNA 的架構的計算資源來優化性能,或者能效,或者說二者同時優化。
這就是這款架構的三大特點。
我們設計時思考的問題
在展開我們的討論之前,也是我們在設計這款架構之前一直在思考的三個問題。要設計好一個架構必須解決這三大問題:
問題一:對於神經網路來說,一個好的計算模式究竟是怎麼樣的?
問題二:為了支持的一個計算模式,我們的硬體架構需要怎樣去設計?
問題三:當我們已經實現了一款硬體架構,在針對具體的演算法應用的需求時,我們如何對架構進行配置,使其配置成一個最優的計算模式,滿足我們的計算需求?
我們總結的設計理念,也是我們在一直貫徹於設計過程當中的一個理念:我們認為計算模式與架構的設計是相輔相成的;在設計計算模式的過程中,實際上也是在設計硬體架構,二者是不能完全分開的。
剛剛講完了研究的一些背景,還有我們一些基礎的思考,那麼現在,我們會從演算法和調度的角度,從演算法的硬體用計算模式的角度來進行分析和優化,來看看怎樣才是一個好的計算模式。
二、計算模式
研究對象
首先我們要先明確一下我們的研究對象。
在本次公開課裡面,我們主要以卷積層的計算為主要的研究對象。有兩大原因:
卷積層的計算佔到總計算量的 90% 以上,因此優化卷積層本身是很有必要的。
其他層的計算剛剛提到的池化層和全連接層,它們的計算模式與卷積層是非常類似的,因此我們對卷積層的優化方可以很容易地遷移到其它層的計算上。
我們詳細地來看看卷積層計算。如圖所示,是一個卷積層的計算示意圖,它的輸入是一個 3D 的特徵圖(Input Map),經過一個 3D 的卷積核(kernel)的掃描,在對應點做一些運算後,就會得到一張輸出的 Output Map。我們可以看到,3D 的輸入特徵圖,它總共有 N 個 channel,也就是 N 張特徵圖。
我們總共有 M 個 kernel,經過輸入特徵圖進行計算之後就可以得到 M 張,或者說有 M 個 channel 的 Output Map,就是卷積層的計算。
卷積運算
我們再進一步看下卷積運算又是怎麼一回事。
剛剛講到的卷積核(kernel)會在左邊 5×5 的 Input Map 上進行掃描,黃色的方框是一個 3×3 的卷積核。我們可以看到,每一個黃色小框的右下角會有一個權重分析,也就是具體的權重值。卷積核進行掃描的每個位置都會進行神經元的計算,並得到右邊 3×3 的 Output Map 上的每一個點。可以看到,隨著卷積核在 Input Map 的掃描,就可以得到 Output Map 上的每一個點,而具體的神經元計算其實和我們之前提及的人工神經元模型計算是完全一致的,這就是一個卷積運算的過程。
架構模型
在講完研究對象之後,我們還要再講一下架構模型。
如圖所示,這是我們歸納出來的一個神經網路的硬體架構模型,它主要由片上和片外兩部分構成。
左邊的大矩形就是我們要設計的神經網路硬體架構,而右邊架構的外部有一個主處理器和一個片外存儲叫做 Off-Chip DRAM,這兩個東西是掛載在晶元外部的,而我們主要設計的,就是左邊大矩形內部的結構。
在架構裡面有一個核心控制器 controller,然後片上通常會有三塊 buffer,即 Input Buffer、Output Buffer 及 Weight Buffer,分別存儲神經網路的輸入數據、輸出數據和權重。而中間的黃色部分為 Computing Core 也就是計算核心。
在核心的內部會有一些計算器,比如 Input REGs 與 Output REGs(輸入輸出寄存器),而最最核心的計算單元就是這裡的「CE」它的全稱叫做 convolution engine,即卷積引擎或者說計算引擎。輸入的數據會經過局部的計算器傳輸到計算引擎上,而計算機內部再繼續剖開,就是一個一個的計算單元,我們稱之為 PE,英文叫做 processing element(處理單元),做的是最基本的運算。
神經網路內部最基本的運算是乘加運算,這就是我們最基礎的一個硬體架構模型,後面我們的所有討論都會基於的一個模型來展開。
優化目標
在講完了我們的硬體架構模型以及研究對象以後,我們還要再講一講優化目標。剛剛也提到了兩個優化目標,一個是能效(energy efficiency),另一個是性能。
優化目標 1:能效
剛剛我們也提過,能效的單位是 GOPS/W,表示的是每單位的功耗可以獲得怎樣的性能,它表徵的是一個計算效率的問題。
在公開課裡面,我會盡量少用公式做過多的討論,為了方便大家理解,我經常會用一些例子來解釋,但是因為這兩個公式非常重要,後面的討論都是基於它們,所以我必須花一點篇幅來解釋。
首先,energy efficiency 是性能與功耗的比值,而性能我們通常用每秒做多少操作數來衡量,即 Operation/T(操作數除以計算的總時間),而 Power 是 Energy/T (總能耗除以時間) 的一個結果,我們可以看到 T 就被約掉了。
而另外我們注意到的一點是,對於神經網路固定的一個演算法來說,它的總操作數也是一個固定的值,所以我們首先得到一個結論:能效值與能耗值是成反比的。那麼如果要優化能效,其實我們只需要優化能耗就好了。我們的能耗越低,那能效也會越高。因此,我們把問題轉化成了能耗問題。
我們繼續分析能耗。能耗主要由兩部分構成。
一個是訪問存儲器的能耗,簡稱訪存能耗,用 EnergyMA 來表示。
另一部分即計算能耗,用 EnergyCompute 來表示。
那麼它們分別可以用怎樣的形式來建模?我們也分別對這兩個式子做一個細緻的分析。
訪存能耗有片上的存儲也有片外的存儲,另外就是 MADRAM,也就是 DRAM 的訪問次數, 而 EDRAM 則是單位 DRAM 的訪問能耗。二者相乘就得到了 DRAM 的總訪問能耗,另外一部分就是訪問 buffer 的能耗。
這裡的表達式與 DRAM 是類似的,也是由訪問次數乘以單位訪問能耗構成的,而對於計算的能耗,它是由兩個因子來相乘得到的,一個是總的計算操作數 Operation,另外一個就是單位操作能耗 Eoperation,
對於一個給定的 CNN 模型,它的總操作數是固定的,那麼我們可以認為總的計算能耗,在單位操作能耗不變的情況下,它也可以認為是一個固定的值,因此,影響能耗的關鍵因素,就是說對 DRAM 的訪問次數以及 buffer 的訪問次數。
我們可以看到,能效的優化問題,其實最後就轉化為對 DRAM 以及 buffer(注意 buffer 就是片上緩存)的訪問次數的優化。如果我們的訪問次數很少的話,那麼它的能耗就會比較低,能效就會比較高,此後我們就集中對這兩個關鍵因素進行討論就可以了。
優化目標 2:性能
第二個優化目標是性能。我仍然要具體介紹一個公式。
前面我們提及性能(Performance)的單位是 GOPS,即每秒的操作數,而我們定義了 Performance 的一個公式,由幾個因子相乘。
第一項是硬體乘加單元數 MAC,我們這裡定義為就是硬體上的總的乘加單元的個數或者說基本計算單元的個數。硬體有一個總的計算單元的個數,相當於是一個常量。
第二項是計算單元的利用率,簡稱 PE Utilization,指的是在整個計算的過程當中,硬體計算單元的實際利用率是多高;
第三項是計算核心的頻率(Frequency),硬體在工作的時候會有一個計算的頻率,頻率的高低會直接影響到總的性能高低。如果硬體乘加單元數越高,利用率高,計算核心頻率高,那麼我的總性能肯定是越好的;而對於一個給定的一個硬體架構,影響它的性能的關鍵因素就是計算單元,在整體的計算工作過程當中,它的利用率是高還是低,PE 越高,它的性能就會越高,這是我們的一個觀點。
由此,我們也同樣把性能關鍵的優化目標轉換成能夠具體分析甚至可以優化的一個對象,叫做 PE Utilization,也就是我們計算資源的利用率。
我們簡單總結一下,剛剛分別討論了兩個重要的優化目標,分別是能效和性能。通過對能效和性能的表達式的分析,我們將分別從訪存次數 MA 以及計算單元的利用率 PE Utilization 這兩個角度,對計算模式進行優化。
到此為止,我們對研究對象、目標的架構以及優化目標都做了非常細緻的分析,那我們就可以展開討論了。
在設計裡面,我們採用一種逐層加速的策略來針對層數不同的神經網路,因為剛剛也提到,神經網路本身的計算量非常大,特別是在現在網路層次越來越深的情況下,基本上不太可能在硬體上直接把一個神經網路直接映射到一個硬體上去做計算,所以我們採用一種大家現在慣常使用的計算方法,叫做逐層加速,即一層一層的來計算神經網路,最終得到輸出結果。
我們的核心方法是使用循環變換的方法來優化其計算模式,圖中的代碼其實表示的就是一個卷積層的計算,它是由四層循環來表示的,其中 R、C、M、N 還有 K,這些參量都是和之前提到的基本卷積層計算參量是一一對應的。
我們通過對循環進行優化,實際上就可以把它轉換成對神經網路特別是卷積層的計算模式優化,並採用循環變換一個很好的方法,對計算模式進行優化。
那麼什麼叫做計算模式?我們仍然是結合之前的架構圖來介紹。
計算模式主要由兩部分來構成。
一部分我們稱為數據復用模式(藍色箭頭)。數據復用模式指的是,我們存儲在存儲器當中的數據以及權重,無論是存在片外還是片內,它如何進行數據的交互,如何進行數據的傳輸數據。也就是說,數據服務模式主要描述的是數據傳遞的傳輸方式。
而第二個部分就是我們稱之為卷積映射方法(紅框),對於最核心的計算核心來說,數據傳遞到了計算核心內部之後,如何進行具體的計算映射。
二者構成的就是數據傳輸及計算映射,或者構成了一個整體,也就是計算模式,而我們的分析都會針對這兩個部分分別展開。
我們在這裡主要採用兩類循環變換方法。
一類叫做循環交換(Loop Interchange):
主要優化的是數據的復用模式減少訪存次數。
第二個循環變換方法叫做循環分塊(Loop Tiling):
主要優化的是卷積映射方法,提高計算資源的利用率。
值得注意的是,訪問次數以及計算資源利用率,就是我們剛剛提煉出來的、需要主動優化的兩類主要參量,它們會直接對應到性能和能耗這兩個優化目標。
數據復用模式
首先我們來講講數數據的復用模式。
在我們的工作當中,我們提出了三類基本的數據的復用模式,分別是:輸入復用(Input Reuse,IR)、輸出復用(Output Reuse,OR)、權重複用(Weight Reuse,WR),他們分別充分地利用了輸入數據、輸出數據及權重的復用性,我們給出了三種基本復用模式的示意圖以及對應的偽代碼,這裡就不做特別細緻地展開了。
需要值得一提的是,在我們領域的兩個頂級會議上,即 ISCA 16 以及 ISSCC 17 的 Tutorial 上均指出之前的工作都只採用一種固定的數據復用模式。我們在後面的分析會告訴大家,採用固定的服務模式並不是一種特別好的策略。
在我們的方法裡面,我們將多種數據復用模式組合在一起,按照具體的計算以及演算法的需求來進行調度,這是我們的一個核心想法。
這裡會結合輸入復用(Input Reuse)來做稍微細緻一點的分享,但不會涉及到過多的數學或者說特別細緻的代碼講解。
對於輸入復用來說,我們這裡有一個簡單的示意圖,中間還是一個計算核心,而圍繞在旁邊的還是片上的 buffer,所謂的輸入復用表示的是,,我們讀取一部分存儲在 Input Buffer 裡面的數據,放到計算核心內部,再對這些輸入的數據進行充分的復用。具體來說,我們會讀入 TN 個小的 map,在核心內部會做充分的計算,將這一層對應的 M 個 map,即所有和它相關的輸出數據都遍歷一遍,把對應的計算都完成。在這個過程中計算核心需要與片上的 Output Buffer 進行頻繁的交互,與此同時,權重 Buffer 也需要有頻繁的訪問。但是因為在過程中我對輸入數據進行了充分的復用,所以我們在這種模式下面對於輸入數據,它僅僅需要從 Input Buffer 裡面導入一次,導入到 Core 內部就好了。
這個過程叫做輸入復用,所對應的循環表達就是下面一個式子,不做具體的展開。我們可以看到,紅色虛線框的這部分就是核心內部完成的計算,而輸入復用對應的一種循環表達,其實是對外部的四層循環做一個次序的調整,就是我之前提到的循環次序調換,而其中涉及到的 Tm、Tn、Tr、Tc,分別對應的是之前提到的 M、N、R、C。我們這裡稱為 Tiling 參數,因為核心內部的局部存儲非常有限,所以我們將 Input Buffer 內部的這些數據和權重導入到核心內部的時候就要做一個分塊,也就是說我計算任務是一部分一部分來完成的,採用這樣一種方式完成整個的計算任務。而剛提到的 Output Reuse 與 Weight Reuse,它其實所改變的就是外部存儲循環的計算次序,也就是 Loop Interchange。
針對這樣的數據復用方式,我們會展開一些分析。
訪存分析模型
我們之前有提到,我們需要分析的是它的訪存的總能耗是怎麼樣的,其中的一個關鍵因素就是訪問次數(Memory Access)如何,簡稱 MA,是由這樣一個公式來得到的。
至於公式 TI、TO、TW 只是當前層的輸入、輸出和權重的總量,TPO 表示的是當前層的最終輸出數據總量,它是一個常數;αi、αo、αw對應的就是輸入輸出權重的復用因子,我就不過多解釋了。
這裡我們直接上結論,對於片上 buffer 的訪問來說,因為是輸出復用,所以 αi 是 1,但是輸出和權重需要多次的訪問,所以它們會乘上一個大於 1 的一個因子,是由 Tiling 參數和計算參數決定的;而對於低端的訪問,它是一個相對複雜一點的公式,主要體現在 αo 和 αw 上,它是一個與片上緩存容量相關的一個表達形式,但因為是輸入復用,所以其復用次數仍然是 1(用紅色表示)。對於輸入復用來說,訪問是 1,我們可以很容易地推測出來。
對於輸出數據還有權重來說,它的訪問次數也應該是最小的,這裡我就不做過多的展開了。
能耗分析模型
那我們有了一個能效訪問次數的分析模型之後,就能以此做一個能耗的分析模型,公式也很簡單,我們之前已經詳細的討論過了。而我們也提到,計算能耗是一個固定的值,因此會著重對訪存能耗進行分析,而用剛剛的訪存分析模型,我們已經得到了最低端訪問次數的模型(紅色部分)和 buffer 的訪問次數模型,那麼單位的 DRAM 的訪存和 buffer 的訪存分別是怎樣一個值?其實這和具體的設計有關,我們也會做一些實驗。
在我們的設計中,對於 DDR3 的,因為每個 Dram 的單位訪存能耗是 70pj/bit,而片上 buffer 的單位訪存能耗是 0.42pj/bit。我們其實對訪存能耗式子中的每一個項都做了非常精確的一個刻畫,那麼,我們通過一個能效的分析模型就可以評估出不同的計算模式,在不同的參數上面它的能耗是多大,這樣就能我們的優化目標掛鉤了。
AlexNet CONV3 的訪存分析
我們這裡做一個簡單的分析,用 AlexNet 的 CONV3 做一個訪存次數的分析。我直接給了一個分析的圖,這裡簡單解釋一下,橫坐標是 Tiling 的參數,左邊縱坐標是片上 buffer 的總次數,而三個顏色的柱子分別對應的是 IR、OR 與 WR,表示它們在不同的 Tiling 參數的訪存次數,為了方便我們直接來看比較結果。
這三種基本的計算模式,它們兩兩作比得到的比值如圖。這裡紅色的曲線表示是已知唯一的一個基準線,
首先,對於不同的數據復用模式以及不同的 Tiling 參數來說,訪存次數是有差異的,而在不同的情況下,最好的數據復用模式也會有所不同。
其次,傳統的或者是當下的工作通常採用一種相對固定的數據復用模式,
而在我們的工作里,我們將三種基本的數據復用模式結合起來,構成一種混合的數據復用模式,根據具體情況來選擇最優的一種模式。
剛剛講完的數據復用模式,是計算模式很重要的一個部分,那麼現在我們來簡單講講卷積映射方法。我們仍然以一個實際例子來簡明地給大家解釋一下。
卷積映射方法
這是卷積計算的一個示意圖,有一個 3×3 的一個 Input Map,kernel 的大小是 2×2,然而卷積的步長是 1,那麼就經過一個卷積之後得到結果它是一個 2×
2 的 Output Map,而這裡彩色的箭頭表示就是說對於每一個 Output Map 上的點,它所對應的輸入數據來自哪一個區域,具體來說就是說對於 Output Map 的 O0 點,它所需要的數據是 I0、I1、I3 和 I4,而對於 O1 點來說,他的數據是 I1、I2、I4 和 I5 這四個點。
我們可以看到,這四個輸出點,它們所對應的輸入數據的範圍是相互覆蓋的,我們看到是 I1、I3、I4、I5 和 I7 這五個點,它們是處於重疊部分的一個區域。就是說,實際上這些點在計算的過程中是存在數據復用的。數據復用就是說數據可以重複利用。比如說,用於 O0 點的計算的數據是可以給到 O1 點進行計算的,即 I1 和 I4,其他的也是類似原理,也就是它存在數據復用的一個機會。
這裡我們就給出大家經常使用的一種卷積映射方法,仍然以剛剛卷積的例子為例,但我們會結合具體的一個硬體結構,CE(計算引擎)的尺寸是 2×2,意味著它內部有 2×2 總共四個 PE(最基本的計算單元)構成,而這幅圖給出來的是一個卷積映射方法的具體過程。
首先,對於 Output Map 上的四個點,計算任務與 PE 2×2 的陣列是對應的,我們這裡就是你看就是 O0 點的計算任務會映射到 PE0 的計算單元上,其他三個點也以此類推,意味著對於某一個 PE 來說,所需要承擔的計算就是對應點所需要進行的計算。特彆強調一點,所謂的計算任務(乘加計算過程)也就是在上面完成。
第二個要點,輸入輸入數據會按照如圖所示的一個軌跡(一個 S 形的折線軌跡)進行掃描,最開始輸入的是左上角的四個點(I0、I1、I3 和 I4),通過掃描 PE0 上的數據,比如 I1 和 I4,會傳遞到 PE1 上,然後通過掃描將外部數據送入到 PE 內部,數據兩兩之間又會進行一個數據傳遞,就用到了我們剛剛所提到的數據復用的機會。
第三點,對於權重來說,它緊跟著輸入數據的節拍,先後輸入陣列,整體的過程就是卷積映射的方法,這個方法是一個非常經典的、大家通常會使用的方法。在現有很多的當前的工作中都採用類似的一些方法,比方說像一些利用陣列形式計算的硬體架構都會通常採取類似的方法,當然在細節上會稍許的不同,不過基本上的原理是類似的。
但剛剛講的映射方法仍然存在一些問題,主要是因為計算參數的多樣性會導致計算資源利用率的問題。我剛才提到,利用計算資源利用率和性能會直接掛鉤,具體來說它主要有兩方面因素的影響,
一方面就是卷積的步長大於 1,
另外一方面就是計算資源的形態,或者說它的結構不匹配。
具體來說,仍然以實例講解一下。卷積步長如果大於 1,這裡以卷積步長為 2 作為例子,PE 的陣列規模是 8×8,要計算的是 4×4 的一個 Output Map。再用剛剛的方式進行計算,實際發揮有效計算的 PE 其實是 1357 這些點(紅色區域)。也就是說,間隔的點會做一些有效計算,而灰色的點雖然實際也在工作,但是它並沒有做有效的計算,所計算出來的數據並不是我們所需要的。
在這個例子里,PE 的利用率僅僅只有 25%,這是比較低的一個數字。
第二點,從我們計算的圖的尺寸,特別是 Output Map 的尺寸,它會與計算資源的規模以及形態會不匹配,具體來說,如果要計算一個 6×6 的一個圖,但是我的陣列大小是 8×8。顯而易見的,只有 6×6 部分他做了有效的計算,而其餘的邊緣部分並沒有做有效的階段,甚至直接沒有用。這樣的話,我們計算出來的利用率僅僅只有 56.25,將近一半的計算資源沒有用上,實在太可惜了。
因此我們希望在計算過程當中,計算資源可以一直工作,或者說它的利用率儘可能接近百分之百,就能達到很高的一個利用率以及性能,這是我們希望看到的。
並行卷積計算方法
我們提出一種叫做「並行卷積計算方法」的一種映射方式,大家看這個圖就很容易明白。因為這個方法本身的概念上其實很容易理解。
左邊是剛剛講的例子,採用我們方法後,我們試圖在陣列上面同時計算四張 Map,利用率能從 25% 提升到將近 100%,這是一個很好的計算結果,它的並行度能提升四倍,那主要是因為我們同時計算四個 Output Map。值得一提的是 Output Map 所需要用到的輸入數據其實是一樣的,或者說它們的數據是共享的,這也就直接指導了我們後面的硬體架構設計。
第二個例子,我們仍然使用並行卷積映射的方法,雖然處理方式有所不同,但是概念上還是非常接近的,為了解釋方便,我們這裡換了一種表達的形式。
這裡我們給出時間軸上的一個展開圖,左邊是傳統的情況,右邊就是用我們的方法之後的一種情況,簡單來說,傳統方法是在 8×8 的陣列上計算 6×6 的輸出圖,如果要計算 16 張不同的 Map(用不同顏色表示),那我們總共需要 16 次迭代,我們可以認為一次迭代代表一次時鐘周期,那麼 PE 的利用率只有 56.25%。
我們採取了另一個操作,對每一個 map 做一個更深層次的一個 Tiling,分塊地將一個 6×6 的塊分割成一個一個 2×2 的小塊,把 16 張 Map 的 2×2 小塊映射到陣列上面。也就是說,我們同時在一個陣列上計算 16 個運行的 Map,但是每個 Map 尺寸更小,那麼我計算完一張 map 的迭代次數只有 9 次,原來是 6×6,現在是 2×2,我只要 9 次迭代就可以完成,但是因為其他的 map 都是並行計算,所以其他的計算也可以同時完成。這樣的一種方式將原來的計算的 16 次迭代就縮短為 9 次迭代,PE 利用率接近 100%。
另外值得一提的是,這些不同的 Map 所需要的數據仍然是共享形式,這一點之後我們會提到。
我們提出一種並行卷積映射方法,這個公式與傳統卷積映射方法公式有些許的改變,主要體現在引入了一個更深層次的 Tiling 參數 Trr 和 Tcc,在分子上面引入了一個並行的因子 P。
主要的核心思想就是通過並行地計算更多的輸出圖,以獲得更高的計算資源應用率。在核心內部的計算過程,我們另外引入兩層 Tiling 來實現並行操作。
以上為硬創公開課上集,下集敬請期待。
雷鋒網原創文章,未經授權禁止轉載。詳情見轉載須知。
推薦閱讀:
※神經翻譯?
※Andrew NG 深度學習課程筆記:二元分類與 Logistic 回歸
※神經網路的訓練可以採用二階優化方法嗎(如Newton, Quasi Newton)?
※從零開始:教你如何訓練神經網路