博客專欄

EEPW首頁(yè) > 博客 > 深度學(xué)習(xí)模型大小與模型推理速度的探討(1)

深度學(xué)習(xí)模型大小與模型推理速度的探討(1)

發(fā)布人:計(jì)算機(jī)視覺(jué)工坊 時(shí)間:2021-10-07 來(lái)源:工程師 發(fā)布文章

作者丨田子宸@知乎(已授權(quán))

來(lái)源丨h(huán)ttps://zhuanlan.zhihu.com/p/411522457

編輯丨極市平臺(tái)

導(dǎo)讀

本文對(duì)衡量深度學(xué)習(xí)模型大小的一些常用指標(biāo),如計(jì)算量、參數(shù)量、訪存量、內(nèi)存占用等進(jìn)行探討,分析這些指標(biāo)對(duì)模型部署推理的影響,尤其是計(jì)算量與訪存量對(duì)模型推理速度的影響,并給出在不同硬件架構(gòu)下設(shè)計(jì)網(wǎng)絡(luò)結(jié)構(gòu)的一些建議。

0、前言

當(dāng)年頭一次實(shí)習(xí)做算法的時(shí)候,主管給的第一個(gè)任務(wù)就是“把一個(gè)大的分割模型砍成一個(gè)小的”。當(dāng)時(shí)并不理解模型“大”、“小”的真正含義,就簡(jiǎn)單的選取計(jì)算量作為評(píng)價(jià)指標(biāo),瘋狂砍計(jì)算量(backbone 換 MobileNet/ShuffleNet、Conv 換成 DepthWise Conv、以及一些奇奇怪怪的融合結(jié)構(gòu)等等),把模型計(jì)算量砍了將近 10 倍,結(jié)果一部署發(fā)現(xiàn)速度并沒(méi)有快多少,反而是把最初的 ResNet 簡(jiǎn)單砍掉幾個(gè) block 效果更好。

也是從那時(shí)起接觸了訪存量、流水線、RoofLine 模型等概念,對(duì)模型推理速度的問(wèn)題產(chǎn)生了興趣,從此踏上了深度學(xué)習(xí)推理優(yōu)化的不歸路(劃掉)。

如今做推理優(yōu)化和 HPC 已經(jīng)有一段時(shí)間了,還是偶爾能回想起當(dāng)年不懂推理時(shí)設(shè)計(jì)的與硬件嚴(yán)重不匹配的模型。此外在工作中跟研究員溝通時(shí),也會(huì)發(fā)現(xiàn)部分研究員對(duì)模型大小和模型推理速度的關(guān)系不太了解,設(shè)計(jì)出一些很難發(fā)揮硬件計(jì)算能力的模型結(jié)構(gòu)。因此在這里對(duì)一些用于評(píng)價(jià)模型大小的指標(biāo)——計(jì)算量、參數(shù)量、訪存量、內(nèi)存占用等指標(biāo)進(jìn)行詳細(xì)探討,分析這些指標(biāo)會(huì)對(duì)模型的部署推理產(chǎn)生何種影響,詳細(xì)討論計(jì)算量和訪存量對(duì)模型推理速度的影響,并給出不同硬件架構(gòu)下設(shè)計(jì)高效網(wǎng)絡(luò)結(jié)構(gòu)的一些建議。

本文不僅僅是為了給出網(wǎng)絡(luò)的設(shè)計(jì)建議,更是希望能夠有效傳達(dá)性能優(yōu)化的基礎(chǔ)理論知識(shí),以及性能分析的基本思路,幫助各位同學(xué)減少網(wǎng)絡(luò)設(shè)計(jì)與部署之間的 gap,更高效的完成網(wǎng)絡(luò)設(shè)計(jì)與部署工作。非常希望本文能夠?qū)Υ蠹业墓ぷ饔兴鶐椭?,也非常歡迎大家在評(píng)論區(qū)留言探討。

一、常用的模型大小評(píng)估指標(biāo)

目前常用于評(píng)價(jià)模型大小的指標(biāo)有:計(jì)算量、參數(shù)量、訪存量、內(nèi)存占用等,這些指標(biāo)從不同維度評(píng)價(jià)了模型的大小。本節(jié)僅作簡(jiǎn)單介紹,熟悉的小伙伴可以跳過(guò)此節(jié),直接看后面的分析與探討。

1. 計(jì)算量

計(jì)算量可以說(shuō)是評(píng)價(jià)模型大小最常用的指標(biāo)了,很多論文在跟 baseline 進(jìn)行比較時(shí),都會(huì)把計(jì)算量作為重要的比較依據(jù)。

計(jì)算量是模型所需的計(jì)算次數(shù),反映了模型對(duì)硬件計(jì)算單元的需求。計(jì)算量一般用 OPs (Operations) ,即計(jì)算次數(shù)來(lái)表示。由于最常用的數(shù)據(jù)格式為 float32,因此也常常被寫作 FLOPs (Floating Point Operations),即浮點(diǎn)計(jì)算次數(shù)。(這里為了跟傳統(tǒng)習(xí)慣保持一致,下文就統(tǒng)一采用 FLOPs 啦)

模型的整體計(jì)算量等于模型中每個(gè)算子的計(jì)算量之和。而每個(gè)算子的計(jì)算量計(jì)算方法各不一致。例如對(duì)于 Eltwise Sum 來(lái)講,兩個(gè)大小均為 (N, C, H, W) 的 Tensor 相加,計(jì)算量就是 N x C x H x W;而對(duì)于卷積來(lái)說(shuō),計(jì)算量公式為(乘加各算一次):

PyTorch 有不少工具可以模型計(jì)算量,但需要注意的是這些工具有可能會(huì)遺漏一些算子的計(jì)算量,將其計(jì)算量算成 0,從而導(dǎo)致統(tǒng)計(jì)的計(jì)算量跟實(shí)際計(jì)算量有輕微的偏差,不過(guò)大多數(shù)情況下這些偏差影響不大。

2. 參數(shù)量

早期的論文也很喜歡用參數(shù)量來(lái)評(píng)價(jià)模型大小。

參數(shù)量是模型中的參數(shù)的總和,跟模型在磁盤中所需的空間大小直接相關(guān)。對(duì)于 CNN 來(lái)說(shuō)參數(shù)主要由 Conv/FC 層的 Weight 構(gòu)成,當(dāng)然其他的一些算子也有參數(shù),不過(guò)一般忽略不計(jì)了。

參數(shù)量往往是被算作訪存量的一部分,因此參數(shù)量不直接影響模型推理性能。但是參數(shù)量一方面會(huì)影響內(nèi)存占用,另一方面也會(huì)影響程序初始化的時(shí)間。

參數(shù)量會(huì)直接影響軟件包的大小。當(dāng)軟件包大小是很重要的指標(biāo)時(shí),參數(shù)量至關(guān)重要,例如手機(jī) APP 場(chǎng)景,往往對(duì) APK 包的大小有比較嚴(yán)格的限制;此外有些嵌入式設(shè)備的 Flash 空間很小,如果模型磁盤所需空間很大的話,可能會(huì)放不下,因此也會(huì)對(duì)參數(shù)量有所要求。

除了在設(shè)計(jì)模型時(shí)減少參數(shù)量外,還可以通過(guò)壓縮模型的方式降低軟件包大小。例如 Caffe 和 ONNX 采用的 Protobuf 就會(huì)對(duì)模型進(jìn)行高效的編碼壓縮。不過(guò)壓縮模型會(huì)帶來(lái)解壓縮開(kāi)銷,會(huì)一定程度增加程序初始化的時(shí)間。

3. 訪存量

訪存量往往是最容易忽視的評(píng)價(jià)指標(biāo),但其實(shí)是現(xiàn)在的計(jì)算架構(gòu)中對(duì)性能影響極大的指標(biāo)。

訪存量是指模型計(jì)算時(shí)所需訪問(wèn)存儲(chǔ)單元的字節(jié)大小,反映了模型對(duì)存儲(chǔ)單元帶寬的需求。訪存量一般用 Bytes(或者 KB/MB/GB)來(lái)表示,即模型計(jì)算到底需要存/取多少 Bytes 的數(shù)據(jù)。

和計(jì)算量一樣,模型整體訪存量等于模型各個(gè)算子的訪存量之和。對(duì)于 Eltwise Sum 來(lái)講,兩個(gè)大小均為 (N, C, H, W) 的 Tensor 相加,訪存量是 (2 + 1) x N x C x H x W x sizeof(data_type),其中 2 代表讀兩個(gè) Tensor,1 代表寫一個(gè) Tensor;而對(duì)于卷積來(lái)說(shuō),訪存量公式為:

1.png

訪存量對(duì)模型的推理速度至關(guān)重要,設(shè)計(jì)模型時(shí)需要予以關(guān)注。

4. 內(nèi)存占用

內(nèi)存占用是指模型運(yùn)行時(shí),所占用的內(nèi)存/顯存大小。一般有工程意義的是最大內(nèi)存占用,當(dāng)然有的場(chǎng)景下會(huì)使用平均內(nèi)存占用。這里要注意的是,內(nèi)存占用 ≠ 訪存量。

內(nèi)存占用在論文里不常用,主要原因是其大小除了受模型本身影響外,還受軟件實(shí)現(xiàn)的影響。例如有的框架為了保證推理速度,會(huì)將模型中每一個(gè) Tensor 所需的內(nèi)存都提前分配好,因此內(nèi)存占用為網(wǎng)絡(luò)所有 Tensor 大小的總和;但更多的框架會(huì)提供 lite 內(nèi)存模式,即動(dòng)態(tài)為 Tensor 分配內(nèi)存,以最大程度節(jié)省內(nèi)存占用(當(dāng)然可能會(huì)犧牲一部分性能)。

和參數(shù)量一樣,內(nèi)存占用不會(huì)直接影響推理速度,往往算作訪存量的一部分。但在同一平臺(tái)上有多個(gè)任務(wù)并發(fā)的環(huán)境下,如推理服務(wù)器、車載平臺(tái)、手機(jī) APP,往往要求內(nèi)存占用可控??煽匾环矫媸侵竷?nèi)存/顯存占用量,如果占用太多,其他任務(wù)就無(wú)法在平臺(tái)上運(yùn)行;另一方面是指內(nèi)存/顯存的占用量不會(huì)大幅波動(dòng),影響其他任務(wù)的可用性。

5. 小結(jié)

計(jì)算量、參數(shù)量、訪存量、內(nèi)存占用從不同維度定義了模型的大小,應(yīng)根據(jù)不同的場(chǎng)合選用合適的指標(biāo)進(jìn)行評(píng)價(jià)。

模型推理速度不單單受模型計(jì)算量的影響,也與訪存量和一些其他因素息息相關(guān)。下文將詳細(xì)討論影響模型推理速度的因素。

二、計(jì)算量越小,模型推理就越快嗎

答案是否定的。

實(shí)際上計(jì)算量和實(shí)際的推理速度之間沒(méi)有直接的因果關(guān)系。計(jì)算量?jī)H能作為模型推理速度的一個(gè)參考依據(jù)。

模型在特定硬件上的推理速度,除了受計(jì)算量影響外,還會(huì)受訪存量、硬件特性、軟件實(shí)現(xiàn)、系統(tǒng)環(huán)境等諸多因素影響,呈現(xiàn)出復(fù)雜的特性。因此,在手頭有硬件且測(cè)試方便的情況下,實(shí)測(cè)是最準(zhǔn)確的性能評(píng)估方式。

在設(shè)計(jì)網(wǎng)絡(luò)結(jié)構(gòu)時(shí),如果有實(shí)測(cè)的條件,建議在模型迭代早期對(duì)性能也進(jìn)行測(cè)試。一些 NAS 的方法也會(huì)對(duì)搜索出來(lái)的網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行測(cè)速,或者干脆對(duì)硬件速度進(jìn)行了建模,也作為初期搜索的重要參數(shù)。這種方法設(shè)計(jì)出來(lái)的網(wǎng)絡(luò)在后期部署時(shí),會(huì)極大減少因性能問(wèn)題迭代優(yōu)化的時(shí)間和人力開(kāi)銷。

這里我將討論影響模型在硬件上推理速度的一些因素,一方面希望可以幫助手動(dòng)/自動(dòng)設(shè)計(jì)網(wǎng)絡(luò)結(jié)構(gòu)的同學(xué)更快的設(shè)計(jì)更高效的網(wǎng)絡(luò)結(jié)構(gòu),另一方面希望當(dāng)模型部署時(shí)性能出現(xiàn)問(wèn)題時(shí)能夠?yàn)榇蠹姨峁┓治鲈虻乃悸贰?/p>

這一問(wèn)題我將從如下 3 個(gè)點(diǎn)進(jìn)行討論:

計(jì)算密度與 RoofLine 模型

計(jì)算密集型算子與訪存密集型算子

推理時(shí)間

1. 計(jì)算密度與 RoofLine 模型

計(jì)算密度是指一個(gè)程序在單位訪存量下所需的計(jì)算量,單位是 FLOPs/Byte。其計(jì)算公式很簡(jiǎn)單,很多教材、資料里也稱之為計(jì)算訪存比,用于反映一個(gè)程序相對(duì)于訪存來(lái)說(shuō)計(jì)算的密集程度:

RoofLine 模型是一個(gè)用于評(píng)估程序在硬件上能達(dá)到的性能上界的模型,可用下圖表示:

2.jpg

RoofLine 模型

用公式描述:

當(dāng)程序的計(jì)算密度I較小時(shí),程序訪存多而計(jì)算少,性能受內(nèi)存帶寬限制,稱為訪存密集型程序,即圖中橙色區(qū)域。在此區(qū)域的程序性能上界=計(jì)算密度×內(nèi)存帶寬,表現(xiàn)為圖中的斜線,其中斜率為內(nèi)存帶寬的大小。計(jì)算密度越大,程序所能達(dá)到的速度上界越高,但使用的內(nèi)存帶寬始終為最大值。

反之如果計(jì)算密度I較大,程序性能受硬件最大計(jì)算峰值(下文簡(jiǎn)稱為算力)限制,稱為計(jì)算密集型程序,即圖中藍(lán)色區(qū)域。此時(shí)性能上界=硬件算力,表現(xiàn)為圖中的橫線。此時(shí)計(jì)算速度不受計(jì)算密度影響,但計(jì)算密度越大,所需內(nèi)存帶寬就越少。

在兩條線的交點(diǎn)處,計(jì)算速度和內(nèi)存帶寬同時(shí)到達(dá)最大值。

3.jpg

在不同設(shè)備上,同一個(gè)程序的性質(zhì)可能發(fā)生變化

在不同設(shè)備上,同一個(gè)程序的性質(zhì)可能發(fā)生變化。例如上圖中的程序2,在算力稍弱的設(shè)備2上屬于計(jì)算密集型程序,而在算力較強(qiáng)的設(shè)備1上就屬于訪存密集型程序了(感謝評(píng)論區(qū)指正)。如果想要充分發(fā)揮設(shè)備1的性能,應(yīng)當(dāng)適當(dāng)加大程序的計(jì)算密度(比如到程序3的位置)。

2. 計(jì)算密集型算子與訪存密集型算子

網(wǎng)絡(luò)中的算子可以根據(jù)計(jì)算密度進(jìn)行分類。一般來(lái)講,Conv、FC、Deconv 算子屬于計(jì)算密集型算子;ReLU、EltWise Add、Concat 等屬于訪存密集型算子。

同一個(gè)算子也會(huì)因參數(shù)的不同而導(dǎo)致計(jì)算密度變化,甚至改變性質(zhì),比如在其他參數(shù)不變的前提下,增大 Conv 的 group,或者減小 Conv 的 input channel 都會(huì)減小計(jì)算密度。

舉個(gè)栗子,對(duì)于不同參數(shù)的卷積,計(jì)算密度如下:

4.jpg

可以看到,不同參數(shù)下卷積算子的計(jì)算密度有很大的差異。第 4 個(gè)算子 Depthwise Conv 計(jì)算密度僅有 2.346,在當(dāng)下的很多設(shè)備上都屬于訪存密集型算子。

算子的計(jì)算密度越大,約有可能提升硬件的計(jì)算效率,充分發(fā)揮硬件性能。我們以一個(gè) Intel X86 服務(wù)器平臺(tái)為例(10980 XE)。該平臺(tái) CPU 頻率為 4.5 GHz,我們以 16 核為例,其理論 FP32 算力為 4.608 TFLOPs/s,內(nèi)存帶寬理論值為 96 GB/s。在此平臺(tái)上的 RoofLine 模型為:

5.jpg

Intel 10980 XE 16 核 RoofLine 模型,以及各個(gè)算子的計(jì)算密度與性能

該平臺(tái)“拐點(diǎn)”的計(jì)算密度為 48,計(jì)算較為密集的 OP1 和 OP2 處在計(jì)算密集區(qū),能夠達(dá)到平臺(tái)的算力峰值;而 OP3 和 OP4 處在訪存密集區(qū),受內(nèi)存帶寬限制不能到達(dá)算力峰值,尤其是 OP4,由于計(jì)算訪存比過(guò)低,計(jì)算效率僅有可憐的 4.9%,計(jì)算效率并不高。

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



關(guān)鍵詞: 深度學(xué)習(xí)

相關(guān)推薦

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

關(guān)閉