博客專欄

EEPW首頁 > 博客 > 深度學習模型大小與模型推理速度的探討(2)

深度學習模型大小與模型推理速度的探討(2)

發(fā)布人:計算機視覺工坊 時間:2021-10-07 來源:工程師 發(fā)布文章

3. 推理時間

這里涉及到一個 gap,很多部署的同學們更喜歡談“計算效率”,而實際上算法同學真正關(guān)心的點是“推理時間”,導致兩者在對接的時候經(jīng)常會出現(xiàn)一些 misleading。因此我這里單獨開一節(jié)來探討一下“推理時間”的評估方法。

其實也很簡單,按照 RoofLine 模型,我們很容易就能得到算子實際的執(zhí)行時間:

77.png

這是一個分段函數(shù),拆開來可得:

88.png

一句話總結(jié):對于訪存密集型算子,推理時間跟訪存量呈線性關(guān)系,而對于計算密集型算子,推理時間跟計算量呈線性關(guān)系。

講到這里,我們就能初步回答本章一開始的問題了:按照 RoofLine 模型,在計算密集區(qū),計算量越小,確實推理時間越小。但是在訪存密集區(qū),計算量與推理時間沒關(guān)系,真正起作用的是訪存量,訪存量越小,推理的時間才越快。在全局上,計算量和推理時間并非具有線性關(guān)系。

上一節(jié)中,OP4 雖然計算效率很低,但由于訪存量也很低,因此其實推理速度還是快于其他幾個 OP 的。但是我們可以觀察到,其計算量雖然只有 OP1 的 1/130,但是推理時間僅降低到了 1/6,兩者并非是線性關(guān)系(也是當年我把模型減到 1/10 計算量,但其實沒快多少的原因)。

再舉兩個例子強化一下,首先看這兩個卷積,他們的計算量差不多,但是因為都在訪存密集區(qū),OP3 的訪存量遠低于 OP5,其推理也更快:

6.jpg

下面這個栗子更明顯,OP5 和 OP6 的區(qū)別僅僅是一個是 DepthWise Conv,一個是普通 Conv,其他參數(shù)沒有變化。按照我們之前的直觀感受,Conv 換成 DepthWise Conv 應該會更快,但實際上兩者的推理時間是差不多的(這組參數(shù)也是當年我用過的【手動捂臉):

7.jpg

4. 小結(jié)

從上面的討論中我們可以看出:計算量并不能單獨用來評估模型的推理時間,還必須結(jié)合硬件特性(算力&帶寬),以及訪存量來進行綜合評估。并非是計算量越低模型推理越快。在評價模型大小時,也建議加上訪存量作為重要的評價指標。

需要強調(diào)的一點是,不同的硬件平臺峰值算力和內(nèi)存帶寬不同,導致同一個模型在平臺 1 上可能是計算密集的,在平臺 2 上可能就變成了訪存密集的。例如上文提到的 Intel X86 平臺,“拐點”值為 48,而 NVIDIA V100“拐點”值為 173.6,上文舉的例子在 V100 平臺上僅有 OP2 落在了計算密集區(qū),剩下的全部是訪存密集的。因此,同樣的模型在不同平臺上性質(zhì)可能會發(fā)生改變,需要具體情況具體分析。

我們很難給出一個通用性的結(jié)論,究其原因是 RoofLine 模型本身是一個非線性模型。這里必須要強調(diào)一點的是,除了峰值算力和內(nèi)存帶寬之外,還有硬件限制、系統(tǒng)環(huán)境、軟件實現(xiàn)等諸多因素會影響程序的實際性能,使得其非線性特性更加嚴重。因此 RoofLine 模型僅僅只能提供一個性能上界的評估方式,并不代表能夠達到的實際性能。實際性能最準確的測量方式只有真機實測。

RoofLine 模型更重要的是提供了一種分析性能的思想,即計算密集型程序更多的受限于硬件算力,而訪存密集型程序更多的受限于硬件內(nèi)存帶寬。在理解這一點的基礎(chǔ)上設(shè)計網(wǎng)絡(luò)結(jié)構(gòu),并分析網(wǎng)絡(luò)的性能,將更有理論參考。不會再對”計算量減半,為啥推理時間沒變“這種問題抱有疑問了(說的就是我【流淚)

下文將對 RoofLine 模型的一些限制進行討論,分析哪些因素將以何種方式影響程序,使得其到達不了 RoofLine 模型估計的性能上界。

(下文要開始難度升級了,建議沒看懂 RoofLine 模型的同學們再把這一章看一遍,不然后面會看的有點懵)

三、影響模型推理性能的其他因素

RoofLine 模型可以用來評估程序的性能上界,但是實際能達到的性能還會受到硬件限制、系統(tǒng)環(huán)境、軟件實現(xiàn)等諸多因素的影響,距離性能上界有一定距離。本章將對這些影響因素進行分析。

1. 硬件限制對性能上界的影響

前面 RoofLine 模型使用的峰值算力及內(nèi)存帶寬,是根據(jù)紙面數(shù)據(jù)計算得到的,是理論上的最大值。但在實際情況下,硬件會因為種種原因,無法達到這個理論值。因此建議大家對硬件進行micro-benchmark,以獲取硬件的真實性能上限。

以上文的 Intel X86 CPU 為例,我們之前計算的 avx512 理論算力為 4.608 TFLOPs/s,但這個數(shù)值的前提是頻率能維持在 4.5 GHz。然而實際上在使用 16 核跑 avx512 指令時,CPU 頻率會下降到約 2.9 GHz,此時理論算力僅剩下 2.96 TFLOPs/s,而實測值僅有 2.86 TFLOPs/s。

除了頻率之外,有些芯片可能會因為一些設(shè)計上或?qū)崿F(xiàn)上的原因,導致在實際使用時達不到理論峰值。比如一些低端芯片不支持多****、不支持亂序執(zhí)行、采用了阻塞式 Cache 等等,一些芯片甚至會有一些性能 bug,導致在實際使用時幾乎到達不了理論峰值(這里我個人傾向于把這些原因歸結(jié)為硬件限制帶來的損失)。

內(nèi)存同理,該平臺理論帶寬為 96GB/s,但實測下來最高讀帶寬僅有 74 GB/s,僅能到達理論帶寬的 77%。

我們可以得到修正后的 RoofLine 模型,圖中藍色填充部分反映了因?qū)嶋H算力和內(nèi)存帶寬達到不了理論值而造成的損失:

8.jpg

修正了實測峰值算力和內(nèi)存帶寬后的 RoofLine 模型,藍色填充部分為硬件限制帶來的損失

修正后的模型“拐點”發(fā)生了變化,因此算子的性質(zhì)也會發(fā)生變化。建議拿到硬件后對硬件進行 micro-benchmark,這里推薦兩個測試工具:

一個是高叔叔寫的浮點峰值測試方法的文章,最后有 github 鏈接,大家可以 clone 下來測試硬件峰值:

還有一個是 stream 測試工具,可以用于測試內(nèi)存帶寬:

2. 系統(tǒng)環(huán)境對性能的影響

除非程序運行在裸機中,否則操作系統(tǒng)一定會對性能上界產(chǎn)生一定影響,比如操作系統(tǒng)在多核間的調(diào)度損失、操作系統(tǒng)的內(nèi)存管理帶來的損失、操作系統(tǒng)本身占用的運算資源等等。

對于一般的深度學習推理任務而言,現(xiàn)代操作系統(tǒng)對性能的影響并不是特別明顯。但是在一些特殊情況下,也會帶來嚴重的性能損失。我這里將會舉兩個例子:

一個是 Android 系統(tǒng)在大小核上的調(diào)度,一旦程序在 CPU 上的占用率不足(比如是周期工作的任務),則有可能被 Android 調(diào)度到小核上,帶來性能損失。

另一個例子是內(nèi)存缺頁。在 Linux 系統(tǒng)上,當向系統(tǒng)申請內(nèi)存頁后,系統(tǒng)只是返回了虛擬頁,等到程序?qū)嶋H使用虛擬頁時,才會通過觸發(fā)缺頁異常的方式,進入操作系統(tǒng)內(nèi)核分配物理頁,這一過程會嚴重降低性能。

好在這些問題可以通過軟件進行一部分彌補,例如調(diào)度問題可以使用綁核來解決,缺頁問題可以通過綁定物理頁(需要內(nèi)核態(tài))或內(nèi)存池來解決。因此操作系統(tǒng)帶來的影響是可控的。

除了操作系統(tǒng)帶來的影響,系統(tǒng)中運行的其他進程也會對當前進程造成影響。比如一個系統(tǒng)中運行了多個深度學習實例,或者系統(tǒng)后臺一些 APP 自啟動了等等。這些進程都會占用核心算力和內(nèi)存帶寬,造成當前進程性能損失。

這往往會導致在工程測試環(huán)境下性能達標的模型,在實際部署時性能下降。因此,必須關(guān)注工程測試環(huán)境和實際部署系統(tǒng)環(huán)境的差異。如有條件,最好在實際部署環(huán)境下進行測試。

3. 軟件實現(xiàn)對性能的影響

除了硬件限制和系統(tǒng)環(huán)境外,一個任務的軟件實現(xiàn)好壞對性能有著重大的影響。

例如對于同樣的矩陣操作任務,使用 python 寫的多重 for 循環(huán),和用 numpy 高度優(yōu)化過的矩陣操作函數(shù),性能可以差出 1~2 個數(shù)量級。

對于深度學習模型推理而言,推理框架對模型性能的影響主要體現(xiàn)在:是否充分利用了硬件的流水線資源、是否高效利用了硬件中的緩存、是否采用了時間復雜度更低的算法、是否解決了操作系統(tǒng)帶來的性能損失(如上文的調(diào)度問題和內(nèi)存缺頁問題)、是否進行了正確高效的圖優(yōu)化等等。

由于影響因素很多,因此軟件對性能的影響往往呈現(xiàn)出很強的非線性,導致在評估性能時很難給出一些普適性的結(jié)論,很多時候只能具體情況具體分析。(有的時候甚至有點玄學【捂臉)

例如同樣計算量的向量四則運算和超越函數(shù),后者往往會慢于前者的原因是很多硬件不支持超越函數(shù)的 SIMD 指令;再比如空洞卷積(dilated Conv)性能會弱于普通卷積的原因是前者對訪存的利用不如后者高效等等。

在軟件實現(xiàn)的影響下,RoofLine 模型的上界再次下降,達到圖中的紅線(真實的非線性可能會比我隨手畫的要復雜的多):

9.jpg

RoofLine 模型各種性能損失示意圖,圖中曲線不代表真實比例

因此,在評估或分析深度學習推理性能時,簡單的計算量/訪存量指標是完全不夠的,只能做個性能上界參考。實際能達到的性能其實還要關(guān)注很多很多因素,例如算子的訪存模式、數(shù)據(jù)排布、是否能夠進行圖融合、是否有精度可接受的低時間復雜度算法、算法并行度是否充足、各種運算的比例等等因素。

這些因素對于算法同學而言可能過于復雜,并不需要掌握。但如果所在的公司/部門有交流的機會的話,可以跟部署/優(yōu)化的同學針對模型結(jié)構(gòu)和算子進行探討,以獲取性能優(yōu)化的建議。

這里可以一些一般性的結(jié)論,僅供參考:

對于一些訪存非常密集且訪存 pattern 連續(xù)的算子,如 Concat、Eltwise Sum、ReLU、LeakyReLU、ReflectionPad 等,在 Tensor 數(shù)據(jù)量很大的情況下,軟件實現(xiàn)的損失會非常小,正常情況下基本都能達到內(nèi)存帶寬實測上限;如果框架采用了融合策略的話,基本可以達到 0 開銷。

對于 Conv/FC/Deconv 等算子,在計算密度很高的情況下,大多數(shù)框架是能夠很接近算力峰值的。但對于計算密度不是特別高的 case,不同框架的表現(xiàn)不一,需要實測才能確定。不過從大趨勢而言,都是計算密度越高,硬件的利用率越高的。

盡量使用常用的算子參數(shù),例如 Conv 盡量使用 3x3_s1/s2,1x1___s1/s2 等,這些常用參數(shù)往往會被特殊優(yōu)化,性能更好。

4. 小結(jié)

RoofLine 模型僅能用于估計模型所能達到的性能上界,而實際部署時,還會受硬件限制、系統(tǒng)環(huán)境、軟件實現(xiàn)等因素的影響,導致無法達到 RoofLine 模型所定義的性能上界。

此外,由于這些因素往往會導致性能曲線有較強的非線性,理論分析和實測會有一定差距,有時這些因素會嚴重影響性能曲線,甚至會導致算子的性質(zhì)發(fā)生變化。因此本節(jié)討論的內(nèi)容只是提供一些分析的思路與技巧,實測始終是最準確的性能評估方式。

四、面向推理速度的模型設(shè)計建議

前面討論了一大堆,其實最實用的還是“怎么設(shè)計模型能夠達到更快的推理速度”。

在給出我的個人建議之前,首先要先聲明的是:由于不同硬件、不同環(huán)境、不同框架的差異會很大,這些建議可能并不是在所有條件下都適用。在設(shè)計算法或性能測試遇到疑問時,建議咨詢部署/優(yōu)化的同學。

好了,廢話不多說(其實已經(jīng)說了很多了),給出我的一些個人建議:

方法論建議:

了解目標硬件的峰值算力和內(nèi)存帶寬,最好是實測值,用于指導網(wǎng)絡(luò)設(shè)計和算子參數(shù)選擇。

明確測試環(huán)境和實際部署環(huán)境的差異,最好能夠在實際部署環(huán)境下測試性能,或者在測試環(huán)境下模擬實際部署環(huán)境。

針對不同的硬件平臺,可以設(shè)計不同計算密度的網(wǎng)絡(luò),以在各個平臺上充分發(fā)揮硬件計算能力(雖然工作量可能會翻好幾倍【捂臉)。

除了使用計算量來表示/對比模型大小外,建議引入訪存量、特定平臺執(zhí)行時間,來綜合反映模型大小。

實測是最準確的性能評估方式,如果有條件快速實測的話,建議以實測與理論分析相結(jié)合的方式設(shè)計并迭代網(wǎng)絡(luò)。

遇到性能問題時,可以逐層 profiling,并與部署/優(yōu)化同學保持緊密溝通,具體問題具體分析(適當了解一下計算相關(guān)理論的話,可以更高效的溝通)。

網(wǎng)絡(luò)設(shè)計建議:

對于低算力平臺(CPU、低端 GPU 等),模型很容易受限于硬件計算能力,因此可以采用計算量低的網(wǎng)絡(luò)來降低推理時間。

對于高算力平臺(GPU、DSP 等),一味降低計算量來降低推理時間就并不可取了,往往更需要關(guān)注訪存量。單純降低計算量,很容易導致網(wǎng)絡(luò)落到硬件的訪存密集區(qū),導致推理時間與計算量不成線性關(guān)系,反而跟訪存量呈強相關(guān)(而這類硬件往往內(nèi)存弱于計算)。相對于低計算密度網(wǎng)絡(luò)而言,高計算密度網(wǎng)絡(luò)有可能因為硬件效率更高,耗時不變乃至于更短。

面向推理性能設(shè)計網(wǎng)絡(luò)結(jié)構(gòu)時,盡量采用經(jīng)典結(jié)構(gòu),大部分框架會對這類結(jié)構(gòu)進行圖優(yōu)化,能夠有效減少計算量與訪存量。例如 Conv->BN->ReLU 就會融合成一個算子,但 Conv->ReLU->BN 就無法直接融合 BN 層

算子的參數(shù)盡量使用常用配置,如 Conv 盡量使用 3x3_s1/s2、1x1___s1/s2 等,軟件會對這些特殊參數(shù)做特殊優(yōu)化。

CNN 網(wǎng)絡(luò) channel 數(shù)盡量選擇 4/8/16/32 的冪次,很多框架的很多算子實現(xiàn)在這樣的 channel 數(shù)下效果更好(具體用多少不同平臺不同框架不太一樣)。

框架除了計算耗時外,也處理網(wǎng)絡(luò)拓撲、內(nèi)存池、線程池等開銷,這些開銷跟網(wǎng)絡(luò)層數(shù)成正比。因此相比于“大而淺”的網(wǎng)絡(luò),“小而深”的網(wǎng)絡(luò)這部分開銷更大。一般情況下這部分開銷占比不大。但在網(wǎng)絡(luò)算子非常碎、層數(shù)非常多的時候,這部分開銷有可能會影響多線程的擴展性,乃至于成為不可忽視的耗時因素。

一些其他建議:

除了優(yōu)化網(wǎng)絡(luò)結(jié)構(gòu)、推理框架性能外,還可以考慮通過一些其他工程技巧來提升系統(tǒng)整體的性能。例如:對推理服務流水化,并行數(shù)據(jù)讀取與計算的過程,掩蓋 IO 延時。

本文介紹了評估模型大小的四個常用指標——計算量、參數(shù)量、訪存量、內(nèi)存占用,從 RoofLine 模型入手詳細討論了影響模型推理速度的影響因素,并給出了面向推理速度的模型設(shè)計方法論與建議。

撰寫本文的目的,不僅僅是給算法同學提供有效的網(wǎng)絡(luò)設(shè)計建議,更多的還是希望能夠傳達性能優(yōu)化的基礎(chǔ)知識與分析思路,減少算法設(shè)計到部署之間的 gap,更快速高效的設(shè)計推理友好的網(wǎng)絡(luò)模型。希望能對大家的工作有所幫助。

由于本人知識水平有限,如有錯誤和不詳盡的地方,望大家不吝指出,非常歡迎大家在評論區(qū)留言探討。

*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: 深度學習

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉