分類

展開全部 | 收合全部

分類

展開全部 | 收合全部

【Quantization #1】Quantization 基本概念筆記 (Symmetric, Asymmetric, QAT, scale, zero points)

前言

Quantization 作為模型加速一個非常重要的演算法,
這邊整理一下

Quantization 用途

Quantization 就是一個把連續值變成離散的過程,
2.123 變成 2 之類的

優點

將 float 轉成 int,

  • 可以達到計算加速
  • 需要的儲存空間減少 (例如:float32, 4 bytes 變 int8, 1 bytes)
  • 功耗減少

但相對的當然也有缺點

缺點

  • 因為有轉換的過程,就會產生誤差需要處理
    (這其中也包含著轉成 int 後的數字有沒有足夠的解釋原始 float 數據的能力,此與分布有關係)

Quantization 分類

主要分為兩類

  • Post-training Quantization
  • Quantization aware training

Post-training Quantization

看到 「post-」,就知道這個是後處理的部分,通常是拿已經訓練好的 model 直接進行 Quantization

Quantization aware training (QAT)

對比上面,這個就是邊訓練邊做 Quantization

粗略比較兩種 Quantization

Post-training Quantization 當然是最泛用,可以直接現有的就直接轉,
但考慮到裡面資料的分布,直接作 Quantization 有可能導致解釋力不足,
(可以設想一個情況,資料分布非常不平均,在 Quantization 後可能導致資料都被過度的集中,變成反應不出原始資料的分布)

Quantization aware training 基本上就是訓練時就邊做 Quantization,
比較麻煩,但出來的結果相對品質會更好 (如果追求 Quantization 後還要高的 accuary,也許就會採取這個策略)

Quantization 基本概念

分成 Symmetric Quantization 和 Asymmetric Quantization (也有中文翻譯作對稱/非對稱)

Symmetric Quantization (對稱)

Symmetric 重點在公式皆滿足

  • Quantize 公式:「X_quant = round(X_原始 / scale)
  • 依照下圖公式 (Dequantize):「X_原始 = X_quant * scale」

(這也表示 zero-point 被限制等於 0)

zero-point 正如其名,用來解釋「原始的哪個數值」quant 後會到 0 的位置

Symmetric Quantization 的好處就是在「我們不用處理 offset, zero-point 等額外的運算」,相對就比較簡化


* Reference: https://arxiv.org/pdf/2106.08295

這裡也分為 unsigned int8 (0-255) 與 signed int8(-128 ~ 127)
不過我們應該是可以先不用管這麼多,基本上原文提到 unsigned 是專門用來處理 ReLU 那種只有單邊數值的數據。

很明顯的缺點就是如果左右的數據一邊大一邊小,比較小那邊的解析度會被另外一邊害到 (因為 0 已經被固定)

Asymmetric Quantization (非對稱,最常見,重點!!!)

  • Quantize 公式:「X_quant = round((X_原始 / scale) + zero_point)
  • 依照下圖公式 (Dequantize):「X_原始 = (X_quant – zero_point) * scale

相比 Symmetric,從整個數據的分布去考量,zero point 不在限制為 0,
因此整個數據的分佈可以更合理!


* Reference: https://arxiv.org/pdf/2106.08295

這邊我們推算一下,
如果 Quantize 公式是 「X_quant = round((X_原始 / scale) + zero_point)」,
原始的最小值,在除以 scale 後加上 zero_point 應該要位於 quant 後最小的位置,也就是 0
所以 0 = round((X_原始 / scale) + zero_point
X_原始_min = -zs」就這樣推算出來

而我們也可以知道

zero_point= -round((X_原始 / scale)
但這樣好像有點難看,於是又有了一個 offset 的詞,像是把原來的範圍移動的感覺,
因此 offset = round((X_原始 / scale) = -(zero_point)

名詞解釋

zero-point

zero-point 正如其名,用來解釋「原始的哪個數值」quant 後會到 0 的位置
Symmetric,zero-point 被固定在 0
Asymmetric,zero-point 可以反應在「X_原始 / scale」要加上的偏移量 (移動的感覺)

留意 Asymmetric 公式:「X_quant = round((X_原始 / scale) + zero_point)

offset

  • offset = -(zero-point)

offset,中文是偏移量,但中文不重要我自己多了中文的解釋反而更亂,解釋是用作調整數據範圍「至新的中心點」
說實在我也常被這個詞越搞越亂,現在我也只記他好像是 zero-point 的相反,
然後把 zero-point 定義記好 「原始數據 quant 後 0 的位置!」

然後 X_原始_min = -sz ,這樣 quant 後才會等於 0。

bit-width

有幾個 bit 能用來表示,常見的 b = 8 (bit)
能表示範圍 = 2^8 – 1 = 255 個數值

scale

縮放的比例,因為概念相對直覺,這邊比較晚提到,
通常計算是

scale =(max – min) / (2^b -1)

  • max-min 可以算出全部的數值範圍
  • 2^b -1 代表著用於表示的全部數字

除完就可以得到每一個間距大概要抓多少了。

dynamic range

直翻可能是動態範圍,不過中文不重要,
這表示範圍太大可能導致解析度差(表示力不足),
簡單想像:「超級大的範圍只用 0-255 表示?」

dynamic range 與 scale 的關係

想一下就會發現 dynamic range 其實跟 scale 息息相關,
因為 scale 大才能反應出大的 dynamic range,

通常可以有個判斷的依據 (但實際還是要是情況而定)
scale > 0.5 (dynamic range 太大了)
scale < 0.01 (dynamic range 很小,有可能還滿精準的)

(警告) 此區對觀念沒把握的不要亂看,是我自己的混淆區,亂看可能跟著混淆

Quantization 與 Normalization?

  • Quantization 的結果是離散的 (discrete)
  • Normalization 的結果依然是連續的 (continuous)
  • Quantization 的目的是讓連續的值,轉換到「有限範圍的離散值」,目標是減少儲存空間、加速運算等
  • Normalization 的目的是調整數據的範圍,有可能是轉換到「0-1 或 -1~1」,目的是確保「在不同的維度上有一致性」,也可以是為了權重的相等
  • Quantization 的「離散」結果,會產生一些資訊上的誤差
  • Normalization 的結果只是比例上的縮放,讓資料範圍保持一致,資訊保持著一定的比例,很少會額外增加誤差

Reference

Howard Weng
Howard Weng

我是 Howard Weng,很多人叫我嗡嗡。這個網站放了我的各種筆記。希望這些筆記也能順便幫助到有需要的人們!如果文章有幫助到你的話,歡迎幫我點讚哦!
另外,因為定位是「個人的隨手筆記」,有些文章內容「⚠️可能我理解有誤⚠️」或「?只寫到一半?」,如果有發現這樣的情況,歡迎在該文章的最下面留言提醒我!我會儘快修正或補上!感謝大家的建議與幫忙,讓網站能變得更好?

文章: 890

★留個言吧!內容有誤或想要補充也歡迎與我討論!