全网最全-网络模型低比特量化
CSDN的公式是在是太蛋疼了,如果要看公式的可以上知乎上面看原文
神經網絡低比特量化中訓練和推理是如何實現的? - ZOMI醬的回答- 知乎 https://www.zhihu.com/question/510246227/answer/2300794034
1.1 神經網絡模型量化概述
隨著深度學習的發展,神經網絡被廣泛應用于各種領域,模型性能的提高同時也引入了巨大的參數量和計算量。模型量化是一種將浮點計算轉成低比特定點計算的技術,可以有效的降低模型計算強度、參數大小和內存消耗,但往往帶來巨大的精度損失。尤其是在極低比特(<4bit)、二值網絡(1bit)、甚至將梯度進行量化時,帶來的精度挑戰更大。
這篇文章比較詳細,所以下面這個圖是這篇文章的一個整體目錄。當然啦,除了非常多的文字,這篇文章塞了59個公式,涉及到量化在推理和訓練的內容。雖然可能看得很辛苦,但是也希望可以多多支持ZOMI醬哈。打公式不容易,發現錯誤歡迎評論留言指正。
與FP32類型相比,FP16、INT8、INT4的低精度類型所占用空間更小,因此對應的存儲空間和傳輸時間都可以大幅下降。以手機為例,為了提供更人性和智能的服務,現在越來越多的OS和APP集成了深度學習的功能,自然需要包含大量的模型及權重文件。以經典的AlexNet為例,原始權重文件的大小已經超過了200MB,而最近出現的新模型正在往結構更復雜、參數更多的方向發展。顯然,低精度類型的空間受益還是很明顯的。低比特的計算性能也更高,INT8相對比FP32的加速比可達到3倍甚至更高,功耗上也對應有所減少。
模型量化即以較低的推理精度損失將連續取值(或者大量可能的離散取值)的浮點型模型權重或流經模型的張量數據定點近似(通常為int8)為有限多個(或較少的)離散值的過程,它是以更少位數的數據類型用于近似表示32位有限范圍浮點型數據的過程,而模型的輸入輸出依然是浮點型,從而達到減少模型尺寸大小、減少模型內存消耗及加快模型推理速度等目標。
首先量化會損失精度,這相當于給網絡引入了噪聲,但是神經網絡一般對噪聲是不太敏感的,只要控制好量化的程度,對高級任務精度影響可以做到很小。
其次,傳統的卷積操作都是使用FP32浮點,浮點運算時需要很多時間周期來完成,但是如果我們將權重參數和激活在輸入各個層之前量化到INT8,位數少了乘法操作少了,而且此時做的卷積操作都是整型的乘加運算,比浮點快很多,運算結束后再將結果乘上scale_factor變回FP32,這整個過程就比傳統卷積方式快很多。
提前從體系結構的考量角度思考量化帶來的另一個好處是節能和芯片面積,怎么理解呢?每個數使用了更少的位數,做運算時需要搬運的數據量少了,減少了訪存開銷(節能),同時所需的乘法器數目也減少(減少芯片面積)。
1.1.1 主要的量化方法
一邊而言,量化方案主要分為兩種:在線量化(On Quantization)和離線量化(Off Quantization),在線量化指的是感知訓練量化(Aware Quantization),離線量化指的是訓練后量化(Post Quantization)。訓練量化根據名字的意思很好理解,其實就是在網絡模型訓練階段采用量化方案進行量化。訓練后量化中的量化方案跟訓練并不相關,主要是在模型離線工具(模型轉換工具的時候)采用量化方案進行量化。
感知量化訓練(Aware Quantization)
實際上無論是Tensorflow、MindSpore、Pytroch的量化感知訓練是一種偽量化的過程,它是在可識別的某些操作內嵌入偽量化節點(fake quantization op),用以統計訓練時流經該節點數據的最大最小值,便于在使用端測轉換工具(推理轉換工具)的時候,轉換成端側需要的格式時進行量化使用。
目的是減少精度損失,其參與模型訓練的前向推理過程令模型獲得量化損失的差值,但梯度更新需要在浮點下進行,因而其并不參與反向傳播過程。
某些操作無法添加偽量化節點,這時候就需要人為的去統計某些操作的最大最小值,但如果統計不準那么將會帶來較大的精度損失,因而需要較謹慎檢查哪些操作無法添加偽量化節點。
值得注意的是,偽量化節點的意義在于統計流經數據的最大最小值,并參與前向傳播,讓損失函數的值增大,優化器感知到這個損失值得增加,并進行持續性地反向傳播學習,進一步提高因為偽量化操作而引起的精度下降,從而提升精確度。
值得注意的是,訓練時候的原理與在端測推理的時候,其工作原理并不一致。
2. 訓練后動態量化(Post Dynamic Quantization)
訓練后動態量化是針對已訓練好的模型來說的,針對大部分已訓練,未做任何量化處理的模型來說均可用此方法進行模型量化。
其工作比較簡單,在端測轉換工具的時候,對網絡模型的權重進行統計其每一層卷積的layer或者channel的最大值和最小值,然后通過量化公式對數據進行byte轉換。這樣得到的權重參數比以前小1/4。推理的時候,在內存初始化的時候對網絡模型中的權重進行反量化操作變成float進行正常的推理。
3. 訓練后校正量化(Post Calibration Quantization)
訓練后靜態量化,同時也稱為校正量化或者數據集量化。其原理是對于Mindspore在端測低比特推理的時候(Inference),需要生成一個校準表來量化模型。這個量化校準表的生成需要輸入有代表性的數據集,對于分類任務建議輸入五百張到一千張有代表性的圖片,最好每個類都要包括(即數據無偏)。
量化算法介紹
一般而言,無論per channel還是per layer量化方案,對于weight權重的量化使用對稱量化,對于activate激活的量化使用非對稱量化。
其原因是對于權重而言,其數據的分布為對稱的如或,因此采用對稱量化可以進一步有效降低計算量,使得數據分布更加符合其真實的分布;activate激活在網絡中通常使用ReLU和ReLU6等作為網絡模型的激活函數,其數據分布集中在或者,如果采用對稱方案會加劇數據的離散程度,另外一個原理是會造成數據的浪費,如[-128,0]之間并不存儲任何數據,只有[0,127]有數據分布。
下面以int8作為量化的標準,介紹一下兩種量化算法的主要細節。
對稱量化symmetry
對稱的量化算法原始浮點精度數據與量化后INT8數據的轉換如下:
float=scale ×int
其中,scale默認是float32浮點數,為了能夠表示正數和負數,int采用signed int8的數值類型。通過將float32原始高精度數據轉換到signed int8數據的操作如下,其中round為取整函數,量化算法需要確定的數值即為常數scale:
由于在神經網絡的結構以層(Layer)來進行劃分的,因此對權值和數據的量化可以層Layer為單位來進行,對每層Layer的參數和數據分別進行不同scale的量化。
對權值和數據的量化可以歸結為尋找scale的過程,由于int8為有符號數,要保證正負數值表示范圍的對稱性,因此對所有數據首先進行取絕對值的操作,使待量化數據的范圍變換為,再來確定scale,其scale正確的計算公式為:
另外對于offset的計算公式為:
offset=0
確定了scale之后,itn8數據對應的表示范圍為 [-128×scale,127×scale] ,量化操作即為對待量化數據以 [-128×scale,127×scale] 進行飽和式截斷,即超過范圍的數據飽和到邊界值,然后進行第一條公式所示量化計算即可。
2. 非對稱asymmetric
非對稱的量化算法與對稱的量化算法,其主要區別在于數據轉換的方式不同,如下,同樣需要確定scale與offset這兩個常數:
float=scale×(uint+offset)
確定后通過原始float32高精度數據計算得到uint8數據的轉換即為如下公式所示:
uint8=round(float/scale)-offset
其中,scale是float32浮點數,uint為unsigned INT8定點數,offset是int32定點數。其表示的數據范圍為[ scale×offset,scale×(255+offset) ]。若待量化數據的取值范圍為 [x_{min}, x_{max}] ,則scale的計算公式如下:
offset的計算方式如下:
對于權值和數據的量化,都采用上述公式的方案進行量化, x_{min} 和 x_{max} 為待量化參數的最小值和最大值, Q_{max} 和 Q_{min} 為:
3. 量化初始化
在一般的端測推理的時候,由于網絡模型的輸入并沒有偽量化節點記錄輸入tensor的最大值和最小值,因為無法求得量化參數scale和offset,這個時候推理框架許可要根據輸入數據的標準差deviation和均值mean進行計算,得到對應的量化參數。
其中標準差Standard Deviation的計算公式為下:
其對應的scale為:
Offset的計算為:
值得注意的是,由于在其他端測推理框架(如tflite)需要手工輸入標準差deviation和均值mean,容易導致對數據分析、數據輸入的錯誤和框架的割裂,因此感知量化訓練的時候會對模型的輸入和輸出加上fakeQuant偽量化節點,記錄數據min和max,從而求得Mindspore端測用到input tensor的scale和offset。
1.1.2 感知量化訓練
上面講解了基本的量化公式和量化的方法,下面來詳細展開感知量化訓練(Aware Quantization)模型中插入偽量化節點fake quant來模擬量化引入的誤差。端測推理的時候折疊fake quant節點中的屬性到tensor中,在端測推理的過程中直接使用tensor中帶有的量化屬性參數。
偽量化節點
為量化節點(Fake Quant)的意義在于:
1)找到輸入數據的分布,即找到min和max值;
2)模擬量化到低比特操作的時候的精度損失,把該損失作用到網絡模型中,傳遞給損失函數,讓優化器去在訓練過程中對該損失值進行優化。
a. 基本原理
低比特量化模型運行時,需要確定scale與offset兩個量化參數:
其中,是float32浮點數,uint8為unsigned int定點數,offset是int32定點數。其表示的數據范圍為:
[scale×offset,scale×(2^n+offset)]
若待量化數據的取值范圍為[a,b],則scale和offset的計算方式如下:
對于權值和數據的量化,都采用上述公式的方案進行量化,min和max為待量化參數的最小值和最大值。
前面呢,曾經提到一般而言,權重數據是對稱,為了可以進一步減少數據的計算,較少額外的存儲數據,因此推薦使用對稱的量化算法。但是在對mobieNetV2,mobileNetV3的實際測試開發的過程中,發現數據大部分是有偏的,例如mobileNetV2中:
此時權重對應的數據并不是以0為中心點對稱,featture.child8.conv.child3.weight的權重數據分布范圍是,為了更好地擬合更多的數據,對更多的數據具有更好的泛化性,因此統一使用了非對稱的量化算法。
b. 正向傳播
為了求得網絡模型tensor數據精確的Min和Max值,因此在模型訓練的時候插入偽量化節點來模擬引入的誤差,得到數據的分布。
為了更好地表示上面公式的作用,正向傳播的時候fake quant節點對數據進行了模擬量化規約的過程,如下圖所示:
首先對數據根據min和max值進行截斷,然后把float數據轉換成為int數據,之后再把int數據重新轉換成為float數據,該操作會丟失掉float1與float2轉換之間的精度差。對于量化感知訓練,通過模擬量化操作時候對數據進行規約操作,所以網絡模型中每一個tensor數據可以根據下面公式進行封裝成為op,得到:
x_{out}=SimQuant(x)
c. 反向傳播
按照正向傳播的公式,如果方向傳播的時候對其求導數會導致權重為0,因此反向傳播的時候相當于一個直接估算器:
δ_{out}=δ_{in},I_{(x∈S)}∈S:x:x_{min}≤x≤x_{max}
最終反向傳播的時候fake quant節點對數據進行了截斷式處理,如下圖所示:
d. 更新Min和Max
FakeQuant偽量化節點主要是根據找到的min和max值進行偽量化操作,更新min和max分別為running和moving,跟batch normal算子一樣,這里不進行過多的講述,具體在Mindspore框架中會自動根據網絡模型的結構進行自動插入不同的形式,具體用戶不感知。
2. BN折疊
初步實施方案中構圖比較復雜的主要集中在如何拆分BN層,本節將會對拆分的原理進行細化,落實確定到每一個算子上面,包括每個算子的具體計算公式,控制原理。
a. BN Fold原理
網絡模型中經常使用BN層對數據進行規約,有效降低上下層之間的數據依賴性。然而大部分在推理框架當中都會對BN層和卷積操作進行融合,為了更好地模擬在推理的時候的算子融合操作,這里對BN層進行folding處理。下面左邊圖是(a)普通訓練時模型,右邊圖是(b) 融合后推理時模型。
下面圖中左邊是BN折疊的BN folding訓練模型,右邊是BN folding感知量化訓練模型。
b. Correction數據矯正
-
貝塞爾矯正(Bessel Correction)
在計算方差的時候,論文并沒有提及貝塞爾校正,因為貝塞爾校正是通用的統計學方法,用于校正方差。
-
Batch Normal矯正
由于每次更新batch參數的delta的時候,都是使用當前batch的統計數據,這會使得權重參數連帶著一起被當前的batch影響,為了避免當前權重數據w的抖動,加入correction的校正因子將權重縮放到長期batch統計數據中。
模型開始訓練的時候會在fold conv卷積的輸出除以correction因子,這樣的操作是為了讓模型直接去學習正常的BN操作(根據當前的batch進行學習),在學習到一定程度之后,凍結當前的BN不再更新全局delta,然后fold conv卷積的操作中直接作用,并同時修改bias,作為correction_2更新到ADD算子中。
c. BN FOLD訓練圖
-
算子
組合模式ConvD+BN+ReLU拆分子圖并加入FakeQuant算子,一共拆分為為以下幾個算子:Conv2D、BatchNormFold、CorrectionMul、MulFold、FakeQuantWithMinMaxPreChannel、ConvMul、CorrectionAdd、AddFold、ReLU、FakeQuantWithMinMax。
-
正向圖
下面左邊為原始設計bn折疊訓練圖,右邊是實際Mindspore執行經過優化融合的訓練圖。
圖中主要注意的點為BN_Fold_1和BN_Fold_2,其中BN_Fold_1的作用有兩個:拆分融合的BN層對weight的影響,和對權重數據進行校正;BN_Fold_2的作用有兩個:拆分融合的BN層對bias的作用影響,和對bias數據進行校正。
d. BN FOLD推理圖
-
算子
組合模式ConvD+BN+ReLU拆分子圖并加入FakeQuant算子,一共拆分為以下個算子:Conv2D、BatchNormFold、MulFold、FakeQuantWithMinMaxPreChannel、AddFold。
-
驗證圖示例
正向推理驗證圖,上面的所有公式都會化為這個圖的實際計算方式。
1.1.3 訓練后量化
訓練后靜態量化(Post Calibration Quantization),同時也稱為校正量化或者數據集量化。其原理是對于Mindspore在端測低比特推理的時候(Inference),需要生成一個校準表來量化模型。其核心是取得數據值的量化參數表。
1. 權值量化
權值在進行推理加速時均已確定,因此不需要對權值進行校準。如果使用對稱量化方案,max使用權值的絕對值的最大值,對于非對稱量化算法,max和min使用權值的最大值和最小值。
根據算法驗證結果,對于Convolution,每個卷積核按照per channel的方式采用一組獨立的量化系數(scale和offset),量化后推理精度較高。因此,Convolution權值的量化根據卷積核數量分組進行,計算得到的scale和offset的數量與卷積核數量相同。Dense的權值使用一組scale和offset。
2. 數據量化
數據量化是對每個要量化的Operation的輸入數據進行統計,每個Operation計算出最優的一組scale和offset。
數據是推理計算的中間結果,其數據的范圍與輸入高度相關,需要使用一組參考輸入作為激勵,得到每個Operation的輸入數據用于確定量化max和min。數據的范圍與輸入相關,為了使確定的min和max在網絡接收不同輸入時有更好的魯棒性,因此提出基于統計分布確定min和max的方案。
該方案的思路為最小化量化后數據的統計分布與原始高精度數據的統計分布差異性,操作流程如下:
使用直方圖統計的方式得到原始float32數據的直方圖統計分布;
在給定的min和max搜索空間中選取若干個和分別對待量化數據進行量化,分別得到量化后的數據;
使用同樣的直方圖統計的方式得到n個的直方圖統計分布;
分別計算中每個與的統計分布差異性,找到差異性最低的一個對應的min和max作為確定的量化數值。
在上述操作中,涉及的超參數包括進行直方圖統計時選取的直方圖bin個數、min和max的搜索空間、統計分布差異性的指標。
對于直方圖bin個數,該參數直接反應了直方圖統計特征的分布數個數,由于數據經過量化后會集中到256個離散的點上,因此bin的個數不宜過大,否則絕大多數的bin都沒有數值。
max的搜索空間可以通過search_start_scale,search_end_scale與search_step來確定。
-
search_start_scale為搜索空間起始點與search_value的比值。
-
search_end_scale為搜索空間結束點與search_value的比值。
search_step為搜索空間中每次搜索的值與seach_value的比值步進值。以max_candidate=100,search_start_scale=0.8,search_end_scale=1.2,search_step=0.01為例,對稱量化算法下,其定義的max搜索空間為從100*0.8=80到100*1.2=120的范圍,每次步進100*0.01=1,一共41個d_max搜索值;非對稱量化算法下,搜索0.8*(max–min) ~ 1.2*(max–min),確定最好的一個系數。
繼續舉多一個例子, search_start_scale =0.3,search_step=0.01,search_end_scale==1.7,bin=150。需要在0.3*max~1.7*max這個范圍中找一個最好的max,搜索步長是0.01max,因此需要搜索(1.7-0.3)/0.01 + 1 = 141個max數值。直方統計的bin個數也可以設置,假設當前是150。對于算法方案一,將0-2*max的數據分為150段,統計數據落在每段中的頻率,使用數據的絕對值統計,對于算法方案二,在0.3*(max – min)~1.7*(max - min)這個范圍中找一個最好的ratio,將0-2*(max - min)的數據分為150段,統計數據落在每段中的頻率,使用data – min的值來統計頻率。141個數值都要統計,因此一個量化算子需要存儲141*150個數值。多個batch情況下對frequancy進行累加。
統計分布差異性的指標為計算兩個長度為n直方圖、分布之間的信息差異度,選取的指標包括如下三種:
1) Kullback-Leibler Divergence(KL散度)
2) Symmetric Kullback-Leibler Divergence(對稱KL散度)
3) Jensen-Shannon Divergence(JS散度):首先生成一個新的分布M,為與的均值,JS Divergence為相對M的KL Divergence與相對M的KL Divergence的均值
3. Calibration流程
a. Calibration功能
離線Calibration需要完成以下功能:
對算子的輸入數據量化校準,計算出數據的最優scale和offset;
將算子的權值量化為INT8,計算出權值的scale和offset。
將算子的bias量化為INT32。
由于算子輸入數據在推理過程中才能產生,因此離線Calibration還要實現inference功能。與普通inference過程的不同之處在于對每個需要量化的op的輸入數據和權值數據進行了量化和反量化過程。
b. Calibration過程
Calibration過程可以分為4步:
遍歷graph中的node,對需要量化的算子的權重進行量化。
第一次inference,搜索需要量化的算子的輸入數據的max和min。
第二次inference,進行數據的直方統計。
計算分布差異性能指標(見4.2),根據指標選擇最好的min和max,然后計算出數據的scale和offset,根據數據和權值的scale,進行bias量化。
值得注意的是,min不一定是所有數據batch中的最小值,max也不一定是所有batch中的最大值,與min_percentile和max percentile的值相關。
假設每個batch處理10張圖片,共100個batch,某個op的1張圖片輸入數據是1000個數,max_percentile = 0.99999,數據總量是10*100*1000 = 1000000個數。1000000*0.99999 = 999990。把所有輸入數據從大到小排序,max取第10個數。因此需要緩存10個數,對第一個batch的輸入1000個數進行從大到小排序,取前10大的數進行緩存,第二個batch的輸入1000個數進行從大到小排序,取前10個數,與緩存的10個數共20個數進行排序,取前10大的數,以此類推,最終獲得所有batch數據中前10大的數。
Inference有兩種方式,第一種是數據不做量化進行推理,第二種是數據量化后進行推理。數據量化是指算子的當前batch輸入數據使用當前batch的max和min進行量化,將數據量化為INT8,再由INT8轉回FP32進行inference計算。
第二次inference,進行數據的直方統計。根據第2步已經根據max_percentile找到需要的max的值。
最后,計算分布差異指標,根據指標選擇最好的min和max,然后計算出數據的scale和offset,根據數據和權值的scale,進行bias量化。
c. 搜索空間
影響搜索空間的參數可以分為兩類:一類是增加搜索組合的數量的可以稱之為配置參數,一類是影響單個模型結果的稱之為超參數(不增加結果數量)。
1.1.4 端測量化推理
端側量化推理的結構方式主要由3種,分別是下圖的(a) Fp32輸入Fp32輸出、(b) Fp32輸入int8輸出、(c) int8輸入int32輸出。
INT8卷積示意圖,里面混合里三種不同的模式,因為不同的卷積通過不同的方式進行拼接。
使用INT8進行inference時,由于數據是實時的,因此數據需要在線量化,量化的流程如圖所示。數據量化涉及Quantize,Dequantize和Requantize等3種操作。
1. Quantize量化
將float32數據量化為int8。離線轉換工具轉換的過程之前,計算出數據量化需要的scale和offset,如果采用對稱量化算法,則根據公式4進行數據量化,如果采用非對稱量化算法,則根據本文公式6進行數據量化。
2. Dequantize反量化
INT8相乘、加之后的結果用INT32格式存儲,如果下一Operation需要float32格式數據作為輸入,則通過Dequantize反量化操作將INT32數據反量化為float32。
3. Requantize重量化
INT8乘加之后的結果用INT32格式存儲,如果下一層需要INT8格式數據作為輸入,則通過Requantize重量化操作將INT32數據重量化為INT8。
總結
以上是生活随笔為你收集整理的全网最全-网络模型低比特量化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: appcan使用心得体会
- 下一篇: 【COCOS2DX-游戏开发之二四】 q