close

12.6 模型量化基礎概念

前言 量化是模型壓縮和加速常用的方法,因其效果相較於蒸餾、剪枝都要好,因此被大量的應用。 TensorRT也提供了模型量化的功能,本節開始來學習如何利用TensorRT進行模型量化,實現模型存儲的減小,時延的降低,輸送量的提升。 由於量化是非常大的概念,知識點和技巧非常多,因此量化將分為三個小節,第一個小節介紹量化基礎概念,第二小節介紹TensorRTPTQPost-Trainning Quantization,訓練後量化)的方法,第三節介紹QAT(Quantization-aware training,量化感知訓練)

量化概念

模型量化(model quantization)是通過降低權重和啟動值的資料精度,以此減少模型計算時間和能耗的方法。

通常情況下,模型權重和啟動值以FP32/FP16進行訓練和存儲,當精度降低到Int8時,存儲資料的記憶體開銷減少了4倍(相對於FP32),矩陣乘法的計算成本減少了16倍。

大量研究及工程實踐表明,模型量化有一定的魯棒性,在降低存儲、提高推理效率的同時,模型精度損失相對較小,如Nvidia文章《integer quantization for deep learning inference principles and empirical evaluation》中給出的精度損失統計表格,通常掉點在1個點上下,但可帶來幾十倍的效率提升。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

量化優點

量化最直觀的優點是帶來速度提升和存儲的降低,但其好處遠不止這些,它還可以為環境保護,抵禦全球變暖提供幫助,因為低比特模型可以帶來更少的熱量揮發。

根據文章《A Survey of Quantization Methods for Efficient》的分析,FP32的乘/加操作消耗的能量是Int830/18.5倍,由此可見低比特可以顯著降低能量消耗與熱量揮發。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

由此可知,量化可以帶來:

  1. 存儲降低:通過將權重和啟動值從高位精度(如32位元)降低到低位精度(如8位元),模型所需的存儲空間大大減少。
  2. 訪問減少:低位元精度的量化模型需要較少的記憶體頻寬和存儲頻寬來讀取和傳輸權重和啟動值
  3. 速度提升:由於低精度模型執行矩陣乘法等計算操作時的計算量減少,模型的推理速度可以顯著提高
  4. 電費減少:量化模型的計算操作需要更少的能量,功耗降低,從而減少了電費開支
  5. 熱量減少:由於量化模型對處理器的負載較低,因此產生的熱量也相對較少,這對於移動設備和嵌入式系統等散熱受限的環境中的長時間性能非常重要。

量化的數學公式

在數位信號處理領域,量化是指將信號的連續取值近似為有限多個離散值的過程,在模型量化中也是類似的,用較少的數(例如:Int8)表示較多的數(例如:FP32)

用較少的數表示較多的數,實際上是一個線性映射,求一個縮放值scale和一個偏移量offset,將FP32中的數縮放到int8表示的256個數中的某一個數。

可以參考下圖,最上面是FP32可表達的資料範圍,經過縮放和偏移以及四捨五入,將資料劃分到[-128, 127]之間,這類似於長條圖統計

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

將浮點型資料轉換為整型資料有多種形式,根據整型資料的0點是否為中間位置,可將量化分為對稱量化Symmetric Quantization)和非對稱量化Asymmetric Quantization)。參考MIT TinyML 第六節的兩頁PPT來學習對稱量化和非對稱量化。(PS:此處講的均是線性量化)

浮點型資料與整型資料轉換公式如下:

r = S(q - Z)

q = r / S + Z

  • r:浮點型
  • q:整型
  • S:縮放因數scale
  • Z:零點數值Zero

對稱量化

對稱量化是零點在0處,為此需要取絕對值的最大值作為上限、下限,這樣就可得到零點在0處。

然後根據公式計算縮放值scaleS = 2.12 / 1 = 2.12,更一般的可以寫為 S = 2.12 - (-2.12) / 1 - (-1) = (22.12) / (21) = 2.12 / 1 = 2.12

由於Z=0,不需要計算Z

有了SZ就可以對浮點型資料和整型資料進行互相轉換.如下圖所示,圖片來源https://efficentml.ai

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

非對稱量化

非對稱量化的上下限就根據真實分佈選擇,這樣通常Z就不是0

  • 根據公式計算ScaleS = 2.12 - (-1.08) / 1 - (-2) = 1.07
  • 根據公式計算Zero, Z = round(-2 - -1.08/1.07) = -1

嘗試量化 r=0,觀察q對應什麼值:

q = r / S + Z = 0/1.07 + -1 = -1

可以發現,非對稱量化時,浮點數的0值在量化後變為了Z值。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

動態範圍計算方法

在計算scale時,如何選擇資料的上限、下限將會影響最終量化效果。

例如上文的對稱量化是有資料損失的,是不飽和量化。因為直接取絕對值的最大值作為上限,取負作為下限,通常會存在一個資料區間是沒有浮點數據的,但會佔據量化後的一部分資料表示,這些資料表示則會被浪費掉,導致量化後是不飽和的。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

Min-Max

除了上文中的Min-Max方法、通常還採用HistgramEntropy進行動態範圍的選擇。

這裡推薦B站博主手寫AI視頻教程這裡對其視頻做筆記分享。

Histogram

為了選擇合適的上限、下限,可以通過長條圖進行資料統計,然後根據資料分佈情況,選擇恰當的上下限,以此解決離群點帶來的不飽和問題。

通常Histogram需要設置一個超參數,用來確定上下限收縮的範圍,稱為limit

通常limit=0.9999, 0.99999之類。表示從上限、下限進行收縮,收縮之後的資料頻次占總數據量的99%

可採用雙指針實現上述過程:

  • 首先定左指標、右指標分別指向左邊界和右邊界
  • 計算當前雙指標之間的長條圖覆蓋率,如果小於等於設定的覆蓋率閾值,則返回此刻的左指標指向的長條圖值,如果不滿足,則需要調整雙指標的值,向中間靠攏
  • 如果當前左指標所指向的長條圖值大於右指標所指向的長條圖值,則右指標左移,否則左指針右移
  • 迴圈,直到雙指標覆蓋的區域滿足要求

得到上限、下限後,再根據量化公式計算SZ

 

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

EntropyK-L散度)

Entropy方法是一種基於概率分佈的動態範圍計算方法,通過對原始資料進行長條圖統計,得到真實資料分佈p,然後通過KL散度(相對熵,用於描述兩個概率分佈之間的相似性)來衡量分佈qp之間的相似性,最終找到一個與p很相似的q分佈,q的分佈上限、下限就可以作為動態範圍。

下圖是計算q分佈的偽代碼,具體過程包含較多細節,推薦大家觀察博主的視頻即可,在此瞭解採用的Entropy是通過概率分佈的方式尋找動態範圍,此方法在TensorRT中也有實現和運用。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

weightbiasactivation的量化

上文對量化數值的變化及選擇進行了介紹,但對於模型具體運算過程是如何對FP32資料進行量化為int8,最終由反量化回FP32進行輸出,還需要進一步分析。

在模型中,需要量化的內容主要有三個,分別是weightbiasactivation

weightbias好理解,當模型訓練好之後,就可以選定動態範圍,然後計算scaleZ值,就可得到量化方法及量化後的weightbias

activation也需要量化,這個一開始不好理解,這個要從運算溢出講起。

例如兩個int8計算時,如100 + 100 = 200,這是採用int8(可表示[-128, 127])就無法表示200,因此對於運算後的值(啟動值)通常需要更高精度來表示,如int32

但對於啟動值輸出又需要採用int8來表示,這時候就需要將int32量化為int8的過程,這就是啟動值(activation)量化。

可通過下圖觀察一個網路層在量化後是如何計算的,同時可知道一個網路層需要在哪幾個地方進行量化(計算scaleZ值)。

圖中對於weightsbias和網路層輸出都需要經過quantize,即量化。量化的scaleZ值則是在部署前進行確定,這些值的確定也是模型量化核心的內容。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

瞭解了需要量化的物件後,下面來學習校準(Calibration的概念。

對於weightbias,當模型訓練結束後,數值分佈就已確定,因此無需額外操作獲取資料分佈,即可進行scaleZ值的計算。

對於activation就不行,它依賴於具體資料的輸入。因此,對於activation的量化,往往需要採用真實資料的輸入(前向傳播),然後統計啟動值的資料分佈,用於量化。

對於activation,採用真實資料獲取資料分佈再量化計算scaleZ值,這個過程叫做校準(Calibration

PTQQAT

量化也好,校準也好,都是將高精度資料進行統計,然後計算scaleZ值,在部署的推理過程中進行低比特量化。

根據計算scaleZ值的階段不同,模型量化可分為PTQQAT兩大類,兩者各有優缺點。

  • PTQPost-training quantization,訓練後量化),是不需要訓練資料(輸入資料和標籤對資料),通常採用小部分資料(不需要標籤)進行模型啟動值校準,統計啟動值的分佈,然後選擇量化scaleZ值,對於weightbias直接根據模型資料進行量化。
  • QAT(Quantization-aware training,量化感知訓練) ,是需要訓練資料,並需要在訓練階段插入偽量化層,訓練得到帶QDQ節點的資料,然後在量化時採用QDQ節點進行量化,可以得到比PTQ更高的精度。
  •  
    • QDQquantize節點、dequantize節點)節點是QAT的靈魂,是一個量化節點和反量化節點,可在訓練時進行反覆運算優化,思想是在訓練的時候獲得一個好的Q節點,它的scaleZ值是比較好的scaleZ值,為什麼說它得到的值比較好呢?因為這些值可通過DQ節點恢復出更接近真實值的資料,因此認為訓練階段獲得的Q節點中的scaleZ值是較好的選擇。

根據TensorRT官方介紹pdfQDQ(也稱FQ fake quantize,偽量化節點)的插入如下圖所示,最終部署時可直接採用Q節點中的scaleZ值。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

PTQQAT的對比,可參考B站博主ZOMI醬的視頻

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

通過綜述《A Survey of Quantization Methods for Efficient》圖4,也可以很好的理解PTQQAT之間的差別。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

那麼PTQQAT如何選擇? 通常根據精度損失的多少來選,優先選擇方便的PTQ進行驗證,通常PTQ2個點以內,如果PTQ掉點過大,可採用QAT

下圖是Nvidia對模型量化前後精度損失的統計,絕大多數模型採用PTQ掉點0-2個點,甚至還有精度提高的模型。

特別需要注意的是efficientnet及其他輕量化設計的模型結構對於PTQ是不適用的,需要採用QAT進行量化。

<<AI人工智慧 PyTorch自學>> 12.6 模型量化

小結

本節詳細介紹了量化的基礎知識和概念,對於初入門量化概念的朋友來說,信息量會有一些大,這裡做一下要點總結。

  • 量化概念:高精度用低精度資料表示,可減少存儲,提高推理速度
  • 線性量化:分為對稱和非對稱量化,公式是r = S(q - Z) q = r / S + Z r是高精度資料,q是量化後資料
  • SZ的求取:可通過Min-MaxHistogramEntropy三種方法確定資料上限和下限,然後根據通用公式求取
  • 量化對象:通常量化物件有weightbiasactivation,前兩者不需要資料推理,後者需要真實資料推理才可進行統計,並計算SZ
  • 量化方法:根據是否需要訓練,量化分為PTQQAT
  • PTQ:不需要訓練資料,需要小批量真實資料(校準資料)進行推理,對activation進行量化。
  • QAT:需要訓練資料,在訓練階段插入QDQ節點,在部署推理時,Q節點可實現高精度量化。

下一小節將介紹在TensorRT中實現PTQ

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 HCHUNGW 的頭像
    HCHUNGW

    HCHUNGW的部落格

    HCHUNGW 發表在 痞客邦 留言(0) 人氣()