AI模型壓縮技術-量化(Quantization)

Tommy Huang
11 min readSep 4, 2022

我們都知道現實世界是連續的狀態,而電腦世界是離散的狀態,什麼意思呢? 我們看一下下圖,最右邊的馬力歐(高清)的狀態,可以想像是現實世界是連續的狀態,而電腦世界在圖像呈現上是一格一格子的狀態(左圖)是離散的狀態。

https://zh.wikipedia.org/zh-tw/%E9%A9%AC%E5%8A%9B%E6%AC%A7_%28%E8%A7%92%E8%89%B2%29

但其實在電腦上看到的圖形都是離散,包含上面左邊馬力歐的圖,我們把圖在放大,其實可以看到圖片還是一格一格的狀態,見下圖。

所以在電腦世界如果想要圖片越清楚(先不考慮每個格子的顏色),最簡單的方式就是圖的格子數要越大越好。
大家可以想像早期的30萬畫素的圖片(解析度是640×480),現在電視常看到的200萬畫素的FULL HD(1920×1080),到手機常看到800萬畫素的4K(3840×2160)。
除了眼睛的感受看之外,最大的差異就是儲存容量(先不考影像慮壓縮),一張30萬畫素的JPG檔案和800萬畫素的JPG檔案,檔案大小就有差吧。

那這跟這篇要講的量化(Quantization)有什麼關係?

想像一樣,我們在看圖片的時候,假設拍攝是800萬畫素,在手機呈現你看的時候是200萬畫素(假設不用手指頭放大的情況),你的眼睛應該也看不出差異,如果有也是很些微的不清楚。

在AI模型也是同樣道理,我們可以將AI模型想成是800萬畫素的圖片,有沒有辦法AI模型弄成30萬畫素,然後人眼看不出差異。

最簡單的方式就是把模型的浮點數換成整數,也就是「浮點(float)運算」轉換成「定點(integer)運算」,也就是這篇要講的量化(Quantization)。

什麼是浮點數? 簡單說就是有小數的數字,例如123.456789。

什麼是整數? 就是123。

所以浮點轉整數,就是123.456789取整數(或是4捨5入),變成123。

那AI模型這樣做量化(Quantization)有什麼差別或好處?

儲存(模型儲存大小)差異、計算差異、功耗差異

單精度浮點數(float point, FP) 32bit在電腦一個數字就4 Byte,而八位元的整數(INT-8)只占1 Byte,所以123.456789在電腦儲存用一個4 Byte的FP32,而123只需要1 Byte,所以就差了四倍,但兩者誤差就差了0.456789,這個誤差看起來很小,坦白說在神經網路因為層數增加,誤差可能呈現指數放大,所以在學術大部分的的量化研究傾向在浮點轉換成整數運算後,誤差要怎麼最小化?

前面提到如果模型用INT8來儲存,大小差四倍,從4 Byte變成1 Byte感覺好像還好,但我們想像一下一般AI模型模型大小通常都幾百萬幾千萬參數,例如ResNet18的參數就高達3千多萬,如果我們用FP32來儲存,換算出來一個ResNet18要用到126MB來儲存,如果用INT8,模型就可以壓縮到只剩1/4的大小則只需要31.5MB左右。差異就出來了,這樣是不是很棒,在計算元和儲存的memory之間溝通的資料也減少,大幅減少頻帶寬需求,最重要的是內存的頻帶寬需求也會減少。

整數運算和浮點運算速度也有差異,整數運算會快很多(但我用電腦模擬整數和浮點數運算比不出來整數有比較快,可能在CPU上比不出來,見reference),但在GPU上用NV的TensorRT是有比較快,但有可能是TensorRT在針對模型架構優化,從reference可以看到如果運算的單元非高端的筆電CPU,如果是低端的設備,INT會比較快。

Reference: https://zhuanlan.zhihu.com/p/343228234

因為浮點運算在運算的過程中,小數點的位置是變動的(可能要理解IEEE754),定點運算則是不變的,好處是浮點數的動態範圍較大,精度可以很細,缺點是硬體較複雜,浮點數的設計會導致較高的功耗,功耗增加會提高設計運行的總成本,而定點運算硬體設計相對簡單、功耗較低,缺點是容易溢位,造成誤差。

溢位(overflow): 假設8位元整數,最大表現數字是255,如果兩個8位元整數相加,一個數字剛好是255,一個是10,假設承接加法的設計也是8位元整數,所以最大只能用255表示,但實際上255+10=265>255已經超過可以承接的設計的8位元整數,這個時候就稱為溢位。

因此我們訓練後的模型如果要部屬(deployment)在比較邊緣的設備上(例如NPU晶片或是IOT智慧門鎖之類低功耗的設備),如果依舊採用伺服器訓練好的浮點運算模型,邊緣設備硬體的運算資源就不一定夠力,採用浮點運算不是一條正確的方向,所以在邊緣運算大多採用整數來進行,就可以解掉儲存、運算和耗能的問題。

量化(Quantization)

進入正題,量化(Quantization)主要用來讓模型進行forward定點運算進行加速推理,量化是直接對模型進行壓縮成為整數,(本篇文章不提模型架構的壓縮法,在Model Compression文獻中有滿多介紹https://arxiv.org/pdf/1710.09282.pdf),我早期也是看這篇學的,這篇我們只介紹怎麼量化和還原,不介紹模型怎麼做量化的Inference。

前言其實已經提到,Quantization就是在做浮點轉定點,也就是前面提到的123.456789轉換成123,超簡單的對吧。如果在AI Quantization真的這麼簡單那也不用介紹了,AI Quantization在做得事情是有一組權重(浮點數),例如是[0.1, 0.2, 1.2, 2.5, 2.1, -1.0, -2.0,-2.5],怎麼「好好利用」整數可以表示的範圍來表示這些浮點數。

量化(Quantization)又可以分為Post-training Quantization和Quantization aware training。

Post-train Quantization: 簡單說就是AI模型的權重訓練(浮點數)好之後,直接將模型權重轉換成整數。

Quantization aware training: 簡單說就是AI模型的權重直接用整數來進行訓練,但通常在進行整數訓練前,AI模型會先用浮點數訓練後再用整數來進行Fine-tune訓練。

此篇文章旨在介紹Post-train Quantization,Quantization aware training就不特別介紹(比較複雜一點點)。

以INT4為例。
如果先不考慮負號,最簡單的方式就是把「浮點數的值域最大值轉換成15」,「浮點數的值域最小值轉換成0」,也就是下圖。

INT4的Quantization轉換。

那浮點數最大最小值轉換成0和15後,中間的浮點數字要怎麼轉換,我們看著上圖,INT4中0~16個整數有(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),在INT4 每個數字間隔是1,所以最簡單的方式是浮點數也想辦法切成15格。
在浮點數上這15格大小是多少怎麼切也是學術在研究的方法之一。

我們介紹最簡單的方式,就是每一格大小都一樣,所以只要把浮點的值域(最大值-最小值)除上15格,就可以了,而在浮點數上每一格子的大小也稱為Scale,見下圖。

浮點數上的間隔是一樣寬的。

浮點切好的格子,每一個大小都是固定的Scale,每一個內的數字會對應到INT4內,比如
浮點最左邊的菊線內的數字 換轉換 到整數的菊線: 取四捨五入,結果是0。
浮點中間的黃線內的數字 換轉換 到整數的黃線: 取四捨五入,結果是5。

量化其實就是這樣非常簡單。

對稱(Symmetric)量化和非對稱(Asymmetric)量化

上面範例介紹的是浮點數轉換到0~15,但整數其實是有正負值的,也就是INT4其實也可以是(-8, -7,-6,-5,-4,-3,-2,-1, +0, +1, +2, +3, +4, +5, +6, +7),也就是第一個bit是正負號。

針對量化程序又可分為對稱(Symmetric)和非對稱(Asymmetric)方式。

假設都是INT4 (用16個數字來表示)

對稱量化(INT4)值域為-8~7,-7,-6,-5,-4,-3,-2,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,共16個數字。

非對稱(INT4)值域為0~15,0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,共16個數字。

對稱(Symmetric)量化

假設浮點數的AI模型權重是

對稱(Symmetric)量化分成三大步驟,

1. 觀察浮點數資料的取絕對值後的最大值:

2. 計算Scale

在對稱量化 scale,分子項 2的次方項有減1,是因為要少去sign bit(正負號的表示)。

3. 量化: 浮點數到定點

利用對稱量化將浮點轉定點。

如果把轉好後的整數在轉回浮點數,此步驟稱為de-quantization。

我們來看看de-quantizationc後和原始浮點數的差異,

非對稱(Asymmetric)量化

非對稱(Symmetric)量化分成四大步驟,

1. 觀察浮點數資料的值域:

2. 計算Scale

3. 計算zero-point

4. 量化浮點數到定點

我們來看看在非對稱方法如果把轉好後的整數在轉回浮點數的de-quantization。

我們整合一下對稱非對稱的總誤差值,如下

大家看起來好像沒有差太多,但其實是我舉例舉不好,如果好死不死你的模型權重數都是正整數,因為對稱量化有有一個bit去用來做sign bit表示,代表如果權重都是正值,這個bit就浪費了,所以結果會差更多,我隨便舉的範例如下,

對稱還原後誤差總合為15
非對稱還原誤差總合為6

所以量化還原後誤差越小代表量化效果越好,所以滿多量化相關研究都是在研究怎麼樣Quantization後和de-quantization差異最小化。

AI模型量化候用INT跑的好處: 模型變小(檔案減少)、功耗低一點、運算更快。

有優點就有缺點,量化後的模型通常會有精度的減低,從上範例就可以知道每一層量化都會有誤差,而且深度學習網路通常是非常多層,如果一層誤差出來會不斷傳給下一層,所以誤差累乘滿可怕的(跟梯度爆炸消失差不多意思),所以量化會造成辨識率下降,但這幾年學術的努力,量化減少performance的情形已經慢慢趨緩。
(真心話,小模型也可能因為量化偏誤反而結果更好,但這情形比較少發生)。

對稱量化範例code:

非對稱量化範例code:

--

--

Tommy Huang

怕老了忘記這些吃飯的知識,開始寫文章記錄機器/深度學習相關內容。Medium現在有打賞功能(每篇文章最後面都有連結),如果覺得寫的文章不錯,也可以Donate給個Tipping吧。黃志勝 Chih-Sheng Huang (Tommy), mail: chih.sheng.huang821@gmail.com