透過StartDT AI Lab專欄之前多篇文章敘述,相信大家已經對計算機視覺技術及人工智慧演算法在奇點雲AIOT戰略中的支撐作用有了很好的理解。同樣,這種業務牽引,技術覆蓋的模式也收穫了市場的良好反響,而奇點雲AIOT在市場的大面積鋪開又給演算法部門帶來了新的挑戰,也就是如何進一步的降低演算法端計算成本,從而提升業務利潤。
目標很簡單,就是將現有演算法模型在不降低準確性的前提下,縮小模型尺寸以節省硬體儲存成本,簡化模型計算複雜度,以節省硬體計算成本。這又小又快的模型最佳化要求,我們一般統稱為模型加速問題。對這一問題的解決,在學術界也是由來已久,有了很多非常值得借鑑的探索。本文便為大家揭開模型加速的神秘面紗。
為什麼做模型加速?
在正式揭開之前,首先需要了解到深度學習是怎麼成功的:為什麼深度神經網路在現在這個時代能成功而不是在上世紀80,90年代呢?相比於之前,主要的突破來自以下幾個方面:一是諸如隨機梯度下降之類的最佳化演算法的改進,二是越來越大的標註資料集,三是引入能夠滿足模型訓練和推理巨大算力需求的GPU這種高效能運算硬體。
(不同模型在CPU和GPU上的影像分類任務的表現)
但是昂貴的GPU,因為工業界的應用對成本非常敏感。因此,像google這類大廠一般開發自家 的AI晶片(TPU)從源頭上省錢。因此,模型加速對應的第一個問題就是工業界最關心的效率問題:如何 將演算法能夠穩定高效地部署到硬體上使之能夠產生最大的價值。
進行模型加速的第二個目標就是快!很多場景對速度的要求是非常高的:最容易聯想到的場景就是深度 神經網路影像處理技術密集使用的無人駕駛,在這種剎⻋慢個0.5s都會造成重大事故的場景下,對模型的推理速度永遠是要求極高的。
另一個場景是在移動裝置上在移動應用中注入AI能力,這是在移動網際網路遇到AI時的必然反應。現在比較著名的應用有各家推出的人工智障語音服務助手,Siri,小愛同學等。
模型加速的第二個目標就是如何在效能受限的裝置上部署能夠滿足需要 的模型。加速後的模型的引數和計算量更小從而可以有效降低計算和儲存開銷,能夠部署到移動端這種效能受限的裝置上。關於移動端效能,這裡說組資料:移動端常⻅的ARM晶片的A72大核的算力大概是 30G FLOPs,而桌面端的Intel酷睿i3的算力是1000G,也就說如果要把在伺服器端進行推理的模型拿來放在移動端上去執行,這個加速比例至少是30倍以上。
如何進行模型加速?
模型加速一般是對已經訓練好的深度模型進行精簡來得到輕量且準確率相當的模型。這裡有一個重要的前提:深度神經網路並不是所有的引數都在模型中發揮作用,大部分引數其實是冗餘的,只有一小部分對模型的效能產生關鍵作用。
根據這一前提條件,目前工業界主要透過以下幾種方式對模型進行加速:包括不會改變網路機構的權值量化,知識蒸餾,緊湊型神經網路的設計和會改變網路的網路剪枝。學術界和工業界對著幾個方向的研究側重點略有差異:前者對經湊型神經網路的設計更感興趣,畢竟是從源頭上解決問題的方法;而後者對剪枝量化這種偏向工程實現的更關注,畢竟加速效果穩定可控。這裡主要簡單講下我們在生產中比較常用的幾種方式:1、權值量化 2、知識蒸餾 3、網路剪枝。
01 權值量化
量化的思路簡單概括下就是把相近的值變成一個數。最常用的量化方式就是INT8量化,即把神經網路裡面的原來用精度浮點數(FP32)儲存的權值和計算中間值用整形(INT8)表示。計算機中的值都是用二進位制儲存的,FP32是用32bit來儲存,INT8是用8個bit來儲存。從下圖可以看到,FP型別用了23bit來表示小數部分,因此使用INT8集意味著只能用更稀疏的值和更小的數值範圍(-127~128),小數的部分和超過128的部分都會被省略,如果直接就這樣量化,那麼這部分損失的值就會極大的影響模型精度。
(來源:wiki:fp32的儲存方式)
(FP32量化到INT8的值的變化)
那既然會影響精度,為什麼我們還是要冒著⻛險去做量化呢?這主要是兩個方面的原因:一方面是現代的計算晶片對於低bit的數值計算要比高 bit的快很多,尤其是現在很多AI晶片都設計了專⻔的INT8計算核來專⻔處理INT8數值的計算,比如瑞星微出品的RK3399 pro晶片就帶了一個算力達3T FLOPs的NPU;另一方面是計算機記憶體和GPU視訊記憶體載入8bit的數值速度更快,視訊記憶體消耗更小,同樣的視訊記憶體下就可以載入更多更大的網路進行計算。
(來源:https://devblogs.nvidia.com/nvidia-turing-architecture-in-depth/:RTX2080ti對FP32, FP16和INT8
那麼為什麼INT8數值型別在深度神經網路中中能夠應用呢?不是有數值精度損失麼?主要原因有兩個:
1、訓練好的深度神經網路是出了名的對噪聲和擾動魯棒性強。
2、大部分訓練好的權重都落在一個很小的區間內。
這個是有文章作為理論支撐的,Han Song在ICLR2016發表的DEEP COMPRESSION: COMPRESSING DEEP NEURAL NETWORKS WITH PRUNING, TRAINED QUANTIZATION AND HUFFMAN CODING作為神經網路壓縮的開山大作裡面就對AlexNet網路的卷積層的權重分佈進行了分析。下面左邊這個圖就是其中一層神經網路的權重,基本上分佈在-0.1到0.1之間。
如果進行4bit量化,4bit能夠最大表示16個數值,因此大部分權重都有塌縮,能夠保持原來的值的只有16個值,這16個值的分佈如右圖所示,分佈的圖形還是挺吻合的。那麼如果進行8bit的量化,最大能夠保持256個值,對原始權重的保留會更加完整,量化造成的數值損失會很小。
根據這個特性,最直觀、最簡單量化方式就是乘一個係數把FP32型別的小數部分縮放為整數,然後用這 個INT8整數進行計算,計算結果再除以這個係數還原成FP32的值。因為數值集中在很小的範圍內,因此縮放的時候就不太需要擔心會有大量的值轉化後會溢位INT8的表示範圍。因此對於實際值和量化值的對映關係,一般可以用以下公式表示:
其中,r表示實際值;q表示量化的位元數,比如int8量化就是8;z表示量化後的0點值。在實際操作 中,縮放比例、進行縮放的原始數值的最大最小值邊界這些值都是需要反覆除錯最佳化的,最佳化較好的量 化加速效果4倍的情況下一般能夠保持模型的精度損失不超過0.5%。
02 網路剪枝
另一項比較重要的神經網路的加速方法就是模型減枝,剪枝這個方式在許多經典的機器學習中也很常見,比如決策樹,GBM演算法。在神經網路中,剪枝原理受啟發於人腦中的突觸修剪,突觸修剪即軸突和樹突完全衰退和死亡,是許多哺乳動物幼年期和⻘春期間發生的突觸消失過程。突觸修剪從出生時就開始了,一直持續到 20 多歲。
前面提到過,神經網路的引數量非常多,而其中大部分的引數在訓練好之後都會集中在0附近,對整個網路的貢獻非常小。剪枝的目的就是把這些對網路貢獻很小的節點從網路中刪除,從而使網路變得稀疏,需要儲存的引數量變少。當然後遺症也是有的,一方面模型的精度會有所下降,另一方面那些冗餘的引數可能是神經網路魯棒性強的原因,因此剪完枝模型的魯棒性也會有所損失。
經典的剪枝方法是使用預訓練模型進行裁剪,裁剪的原則就是設定一個閾值或一定的裁剪比例,然後把低於閾值的權值拋棄,再使用訓練集進行微調來得到最後的剪枝模型。這種方法操作上非常簡單,裁剪的評價指標有很多種,比如權重大小,權重梯度大小,權重獨立性等,但是往往要耗費非常多的時間來進行反覆調參和微調訓練。這種就是現在主流的結構化剪枝方法,裁剪的粒度比較粗,對神經網路整個層進行裁剪,損失的精度相對來說比較大,但是優勢在於不用關心使用的模型和硬體,通用性很好。
(來源:HanSong 2015 NIPS:神經元剪枝前後的結構)
後來的研究又提出了效果更好的非結構化剪枝方法,裁剪的粒度較細,可以對神經網路層的單個神經元進行剪枝,精度損失比較小,但是依賴於特定演算法與硬體平臺,操作起來比較複雜。另外,隨著強化學習和生成對抗網路在深度學習領域的廣泛應用,越來越多的剪枝演算法使用強化學習和對抗生成網路產生剪枝模型。強化學習可以使用機器自動搜尋剪枝模型空間,根據剪枝要求獲取最佳的剪枝模型。生成對 抗網路同樣可以在對抗網路的指導下,使得生成器生成滿足需求的剪枝模型。
03 知識蒸餾
在使用了上面兩種加速方式還不能滿足需要的話,這個時候就可以試試15年Hinton和 Google創世julao Jeff Dean提出來知識蒸餾。在很多工上,複雜的大網路一般表現都會比簡單的小網路表現要強。使用輕量的緊湊小網路在模型訓練的時候加入在改資料集上訓練 收斂好的大網路作為而外的監督資訊,使小網路能夠擬合大網路,最終學習到與大網路類似的函式對映關係。那麼在部署的時候我們就可以用跑的快的小網路替換大網路來執行任務。
(知識蒸餾方法的基本結構)
知識蒸餾可以實現深度神經網路計算量最大的⻣架網路的替換,從方法論上比較通用,因此在奇點雲實際影像任務中都有很強的應用價值,而從加速效果上來說,使用的小網路計算量越小,加速倍數就越多,當然一般這種情況下的模型學習效果也越差,精度損失越大。但是不同的任務對網路抽取的特徵的使用方式差異還是比較大的,一般來說需要根據不同的任務調整蒸餾方法的策略。
結語
綜上, StartDT AI Lab在模型加速的實踐上,綜合運用權值量化、知識蒸餾、緊湊型神經網路設計和網路剪枝,不斷小型化、快速化、準確化業務所需各類模型,極大提升研發效率。