深度學(xué)習模型大小與模型推理速度的探討(1)
作者丨田子宸@知乎(已授權)
來(lái)源丨h(huán)ttps://zhuanlan.zhihu.com/p/411522457
編輯丨極市平臺
導讀
本文對衡量深度學(xué)習模型大小的一些常用指標,如計算量、參數量、訪(fǎng)存量、內存占用等進(jìn)行探討,分析這些指標對模型部署推理的影響,尤其是計算量與訪(fǎng)存量對模型推理速度的影響,并給出在不同硬件架構下設計網(wǎng)絡(luò )結構的一些建議。
0、前言
當年頭一次實(shí)習做算法的時(shí)候,主管給的第一個(gè)任務(wù)就是“把一個(gè)大的分割模型砍成一個(gè)小的”。當時(shí)并不理解模型“大”、“小”的真正含義,就簡(jiǎn)單的選取計算量作為評價(jià)指標,瘋狂砍計算量(backbone 換 MobileNet/ShuffleNet、Conv 換成 DepthWise Conv、以及一些奇奇怪怪的融合結構等等),把模型計算量砍了將近 10 倍,結果一部署發(fā)現速度并沒(méi)有快多少,反而是把最初的 ResNet 簡(jiǎn)單砍掉幾個(gè) block 效果更好。
也是從那時(shí)起接觸了訪(fǎng)存量、流水線(xiàn)、RoofLine 模型等概念,對模型推理速度的問(wèn)題產(chǎn)生了興趣,從此踏上了深度學(xué)習推理優(yōu)化的不歸路(劃掉)。
如今做推理優(yōu)化和 HPC 已經(jīng)有一段時(shí)間了,還是偶爾能回想起當年不懂推理時(shí)設計的與硬件嚴重不匹配的模型。此外在工作中跟研究員溝通時(shí),也會(huì )發(fā)現部分研究員對模型大小和模型推理速度的關(guān)系不太了解,設計出一些很難發(fā)揮硬件計算能力的模型結構。因此在這里對一些用于評價(jià)模型大小的指標——計算量、參數量、訪(fǎng)存量、內存占用等指標進(jìn)行詳細探討,分析這些指標會(huì )對模型的部署推理產(chǎn)生何種影響,詳細討論計算量和訪(fǎng)存量對模型推理速度的影響,并給出不同硬件架構下設計高效網(wǎng)絡(luò )結構的一些建議。
本文不僅僅是為了給出網(wǎng)絡(luò )的設計建議,更是希望能夠有效傳達性能優(yōu)化的基礎理論知識,以及性能分析的基本思路,幫助各位同學(xué)減少網(wǎng)絡(luò )設計與部署之間的 gap,更高效的完成網(wǎng)絡(luò )設計與部署工作。非常希望本文能夠對大家的工作有所幫助,也非常歡迎大家在評論區留言探討。
一、常用的模型大小評估指標
目前常用于評價(jià)模型大小的指標有:計算量、參數量、訪(fǎng)存量、內存占用等,這些指標從不同維度評價(jià)了模型的大小。本節僅作簡(jiǎn)單介紹,熟悉的小伙伴可以跳過(guò)此節,直接看后面的分析與探討。
1. 計算量
計算量可以說(shuō)是評價(jià)模型大小最常用的指標了,很多論文在跟 baseline 進(jìn)行比較時(shí),都會(huì )把計算量作為重要的比較依據。
計算量是模型所需的計算次數,反映了模型對硬件計算單元的需求。計算量一般用 OPs (Operations) ,即計算次數來(lái)表示。由于最常用的數據格式為 float32,因此也常常被寫(xiě)作 FLOPs (Floating Point Operations),即浮點(diǎn)計算次數。(這里為了跟傳統習慣保持一致,下文就統一采用 FLOPs 啦)
模型的整體計算量等于模型中每個(gè)算子的計算量之和。而每個(gè)算子的計算量計算方法各不一致。例如對于 Eltwise Sum 來(lái)講,兩個(gè)大小均為 (N, C, H, W) 的 Tensor 相加,計算量就是 N x C x H x W;而對于卷積來(lái)說(shuō),計算量公式為(乘加各算一次):
PyTorch 有不少工具可以模型計算量,但需要注意的是這些工具有可能會(huì )遺漏一些算子的計算量,將其計算量算成 0,從而導致統計的計算量跟實(shí)際計算量有輕微的偏差,不過(guò)大多數情況下這些偏差影響不大。
2. 參數量
早期的論文也很喜歡用參數量來(lái)評價(jià)模型大小。
參數量是模型中的參數的總和,跟模型在磁盤(pán)中所需的空間大小直接相關(guān)。對于 CNN 來(lái)說(shuō)參數主要由 Conv/FC 層的 Weight 構成,當然其他的一些算子也有參數,不過(guò)一般忽略不計了。
參數量往往是被算作訪(fǎng)存量的一部分,因此參數量不直接影響模型推理性能。但是參數量一方面會(huì )影響內存占用,另一方面也會(huì )影響程序初始化的時(shí)間。
參數量會(huì )直接影響軟件包的大小。當軟件包大小是很重要的指標時(shí),參數量至關(guān)重要,例如手機 APP 場(chǎng)景,往往對 APK 包的大小有比較嚴格的限制;此外有些嵌入式設備的 Flash 空間很小,如果模型磁盤(pán)所需空間很大的話(huà),可能會(huì )放不下,因此也會(huì )對參數量有所要求。
除了在設計模型時(shí)減少參數量外,還可以通過(guò)壓縮模型的方式降低軟件包大小。例如 Caffe 和 ONNX 采用的 Protobuf 就會(huì )對模型進(jìn)行高效的編碼壓縮。不過(guò)壓縮模型會(huì )帶來(lái)解壓縮開(kāi)銷(xiāo),會(huì )一定程度增加程序初始化的時(shí)間。
3. 訪(fǎng)存量
訪(fǎng)存量往往是最容易忽視的評價(jià)指標,但其實(shí)是現在的計算架構中對性能影響極大的指標。
訪(fǎng)存量是指模型計算時(shí)所需訪(fǎng)問(wèn)存儲單元的字節大小,反映了模型對存儲單元帶寬的需求。訪(fǎng)存量一般用 Bytes(或者 KB/MB/GB)來(lái)表示,即模型計算到底需要存/取多少 Bytes 的數據。
和計算量一樣,模型整體訪(fǎng)存量等于模型各個(gè)算子的訪(fǎng)存量之和。對于 Eltwise Sum 來(lái)講,兩個(gè)大小均為 (N, C, H, W) 的 Tensor 相加,訪(fǎng)存量是 (2 + 1) x N x C x H x W x sizeof(data_type),其中 2 代表讀兩個(gè) Tensor,1 代表寫(xiě)一個(gè) Tensor;而對于卷積來(lái)說(shuō),訪(fǎng)存量公式為:
訪(fǎng)存量對模型的推理速度至關(guān)重要,設計模型時(shí)需要予以關(guān)注。
4. 內存占用
內存占用是指模型運行時(shí),所占用的內存/顯存大小。一般有工程意義的是最大內存占用,當然有的場(chǎng)景下會(huì )使用平均內存占用。這里要注意的是,內存占用 ≠ 訪(fǎng)存量。
內存占用在論文里不常用,主要原因是其大小除了受模型本身影響外,還受軟件實(shí)現的影響。例如有的框架為了保證推理速度,會(huì )將模型中每一個(gè) Tensor 所需的內存都提前分配好,因此內存占用為網(wǎng)絡(luò )所有 Tensor 大小的總和;但更多的框架會(huì )提供 lite 內存模式,即動(dòng)態(tài)為 Tensor 分配內存,以最大程度節省內存占用(當然可能會(huì )犧牲一部分性能)。
和參數量一樣,內存占用不會(huì )直接影響推理速度,往往算作訪(fǎng)存量的一部分。但在同一平臺上有多個(gè)任務(wù)并發(fā)的環(huán)境下,如推理服務(wù)器、車(chē)載平臺、手機 APP,往往要求內存占用可控??煽匾环矫媸侵竷却?顯存占用量,如果占用太多,其他任務(wù)就無(wú)法在平臺上運行;另一方面是指內存/顯存的占用量不會(huì )大幅波動(dòng),影響其他任務(wù)的可用性。
5. 小結
計算量、參數量、訪(fǎng)存量、內存占用從不同維度定義了模型的大小,應根據不同的場(chǎng)合選用合適的指標進(jìn)行評價(jià)。
模型推理速度不單單受模型計算量的影響,也與訪(fǎng)存量和一些其他因素息息相關(guān)。下文將詳細討論影響模型推理速度的因素。
二、計算量越小,模型推理就越快嗎
答案是否定的。
實(shí)際上計算量和實(shí)際的推理速度之間沒(méi)有直接的因果關(guān)系。計算量?jì)H能作為模型推理速度的一個(gè)參考依據。
模型在特定硬件上的推理速度,除了受計算量影響外,還會(huì )受訪(fǎng)存量、硬件特性、軟件實(shí)現、系統環(huán)境等諸多因素影響,呈現出復雜的特性。因此,在手頭有硬件且測試方便的情況下,實(shí)測是最準確的性能評估方式。
在設計網(wǎng)絡(luò )結構時(shí),如果有實(shí)測的條件,建議在模型迭代早期對性能也進(jìn)行測試。一些 NAS 的方法也會(huì )對搜索出來(lái)的網(wǎng)絡(luò )結構進(jìn)行測速,或者干脆對硬件速度進(jìn)行了建模,也作為初期搜索的重要參數。這種方法設計出來(lái)的網(wǎng)絡(luò )在后期部署時(shí),會(huì )極大減少因性能問(wèn)題迭代優(yōu)化的時(shí)間和人力開(kāi)銷(xiāo)。
這里我將討論影響模型在硬件上推理速度的一些因素,一方面希望可以幫助手動(dòng)/自動(dòng)設計網(wǎng)絡(luò )結構的同學(xué)更快的設計更高效的網(wǎng)絡(luò )結構,另一方面希望當模型部署時(shí)性能出現問(wèn)題時(shí)能夠為大家提供分析原因的思路。
這一問(wèn)題我將從如下 3 個(gè)點(diǎn)進(jìn)行討論:
計算密度與 RoofLine 模型
計算密集型算子與訪(fǎng)存密集型算子
推理時(shí)間
1. 計算密度與 RoofLine 模型
計算密度是指一個(gè)程序在單位訪(fǎng)存量下所需的計算量,單位是 FLOPs/Byte。其計算公式很簡(jiǎn)單,很多教材、資料里也稱(chēng)之為計算訪(fǎng)存比,用于反映一個(gè)程序相對于訪(fǎng)存來(lái)說(shuō)計算的密集程度:
RoofLine 模型是一個(gè)用于評估程序在硬件上能達到的性能上界的模型,可用下圖表示:
RoofLine 模型
用公式描述:
當程序的計算密度I較小時(shí),程序訪(fǎng)存多而計算少,性能受內存帶寬限制,稱(chēng)為訪(fǎng)存密集型程序,即圖中橙色區域。在此區域的程序性能上界=計算密度×內存帶寬,表現為圖中的斜線(xiàn),其中斜率為內存帶寬的大小。計算密度越大,程序所能達到的速度上界越高,但使用的內存帶寬始終為最大值。
反之如果計算密度I較大,程序性能受硬件最大計算峰值(下文簡(jiǎn)稱(chēng)為算力)限制,稱(chēng)為計算密集型程序,即圖中藍色區域。此時(shí)性能上界=硬件算力,表現為圖中的橫線(xiàn)。此時(shí)計算速度不受計算密度影響,但計算密度越大,所需內存帶寬就越少。
在兩條線(xiàn)的交點(diǎn)處,計算速度和內存帶寬同時(shí)到達最大值。
在不同設備上,同一個(gè)程序的性質(zhì)可能發(fā)生變化
在不同設備上,同一個(gè)程序的性質(zhì)可能發(fā)生變化。例如上圖中的程序2,在算力稍弱的設備2上屬于計算密集型程序,而在算力較強的設備1上就屬于訪(fǎng)存密集型程序了(感謝評論區指正)。如果想要充分發(fā)揮設備1的性能,應當適當加大程序的計算密度(比如到程序3的位置)。
2. 計算密集型算子與訪(fǎng)存密集型算子
網(wǎng)絡(luò )中的算子可以根據計算密度進(jìn)行分類(lèi)。一般來(lái)講,Conv、FC、Deconv 算子屬于計算密集型算子;ReLU、EltWise Add、Concat 等屬于訪(fǎng)存密集型算子。
同一個(gè)算子也會(huì )因參數的不同而導致計算密度變化,甚至改變性質(zhì),比如在其他參數不變的前提下,增大 Conv 的 group,或者減小 Conv 的 input channel 都會(huì )減小計算密度。
舉個(gè)栗子,對于不同參數的卷積,計算密度如下:
可以看到,不同參數下卷積算子的計算密度有很大的差異。第 4 個(gè)算子 Depthwise Conv 計算密度僅有 2.346,在當下的很多設備上都屬于訪(fǎng)存密集型算子。
算子的計算密度越大,約有可能提升硬件的計算效率,充分發(fā)揮硬件性能。我們以一個(gè) Intel X86 服務(wù)器平臺為例(10980 XE)。該平臺 CPU 頻率為 4.5 GHz,我們以 16 核為例,其理論 FP32 算力為 4.608 TFLOPs/s,內存帶寬理論值為 96 GB/s。在此平臺上的 RoofLine 模型為:
Intel 10980 XE 16 核 RoofLine 模型,以及各個(gè)算子的計算密度與性能
該平臺“拐點(diǎn)”的計算密度為 48,計算較為密集的 OP1 和 OP2 處在計算密集區,能夠達到平臺的算力峰值;而 OP3 和 OP4 處在訪(fǎng)存密集區,受內存帶寬限制不能到達算力峰值,尤其是 OP4,由于計算訪(fǎng)存比過(guò)低,計算效率僅有可憐的 4.9%,計算效率并不高。
*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。