1.重新編碼后是如何運算得到最終結果的?
(1)如何用int8表示float32的計算?
其實就是多了一個放大倍數的問題,舉個例子:比如原來float32的計算為:0.1 * 0.2 + 0.3 * 0.4 = 0.14,那么使用int8計算:1*2 + 3*4 = 14,相當於原來的數值都取10倍放大倍數(int8標定也就是標定這個放大倍數),那么由於乘法的原因,最后的結果相當於放大了100倍.這樣就能使用Int8來取代float32的計算.
(2)怎么解決偏置問題及溢出問題?
假設我們的網絡是卷積后面緊跟着偏置,例如:原來float32的計算為:0.1*0.2 + 0.1 = 0.12,這時候如果采取和上面一樣的策略,那么就會得到:1*2+1 = 3,再縮小100倍得到結果:0.03,問題出在偏置放大了10倍,前面是個乘法運算,相當於放大了100倍,也就是說帶偏置的層要特殊處理一下?
另一個問題:用Int8計算卷積是很容易溢出了,比如:56*45這個值明顯大於INT8_MAX == 127,這時候怎么處理?
nvdia官方的tensorrt-int8文檔(http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf)給了一個計算卷積層的例子,可以很好的解釋這兩個疑惑,如圖所示:
可以看出:
①在計算卷積的時候,使用了int32作為中間值,這樣就解決了溢出問題(對於目前的卷積核大小,用Int8乘積之后再做和是不可能超出int32的范圍的).
②帶偏置的層不是直接用int8計算,而是先轉換為fp32計算出結果,再變換為int8,變換過程就是一個線性映射,不會太耗費資源.
另外還可以解釋一些其他疑惑:比如權重的scale是如何確定的?看上圖中的weights_scale[K]是個數組,代表的應該是不同輸出channel的放大倍數值,因此可以猜測,weights的不同輸出通道可能有不同的放大倍數,但是因為weights的分布是固定的,因此通常weights采用不飽和量化就可以(參考https://zhuanlan.zhihu.com/p/58208691,https://arleyzhang.github.io/articles/923e2c40/),個人感覺采用飽和的量化方式,精度可能有提高,比如確定了每個通道的最大值和最小值,將最大值映射為127,最小值映射為-128,總比將float32_max映射為127能取得更好的精度(僅為個人猜測).
2.KL散度的基本概念?
https://www.zhihu.com/question/41252833
tensorrt如何利用KL散度求取放大倍數(或者稱為映射閾值)?
求取過程大致如下:
①選擇一個測試集的子集,獲取原來分布的直方圖(直方圖的區間個數為2048個(bins),每個區間的范圍就是:(最大激活值-最小激活值)/ 2048)
②依次取第i個bins的值為閾值(為什么i從128開始取,因為如果i取小於127時,KL散度肯定要比i取127時大,因此i小於128的情況根本不用考慮),然后求取以此值為閾值的Int8分布。再求取原分布與新分布的KL散度值,最終取使KL最小的索引值,設為m,然后閾值設為(m+0.5)*一個bin的長度.
文章:https://arleyzhang.github.io/articles/923e2c40/中提出一個疑問:標定的T值怎么會小於128,原因是作者誤將索引和激活值混為一談,m的值是不會小於128的,但是m只是個索引,T = (m+0.5)*一個bin的長度,T是激活值,激活值是有可能出現任意值的.
3.激活值的分布不考慮負值么?
上面的例子發現bin的的索引從128開始取,是沒有考慮激活值為負數的情況,原因是nvidia官方給的tensorrt-int8量化的例子激活函數都是relu,意味着激活值沒有負值,因此可以不考慮負值,但是如果激活函數采用的不是relu,比如會產生負的激活值的tanh函數,那么在量化的時候(即確定放大倍數的時候)就要考慮負的激活值.具體如何考慮,個人猜測為:找到直方圖中的0點,從bin[start] = 0,這個start±128位置向兩端遍歷,求取KL散度的最小值的索引值.
4.求KL散度時長度不同問題怎么解決?
在上面計算KL散度之前有一步為:expand candidate_distribution_Q to 'i' bins,計算兩個分布的KL散度時,要求分布長度是相同的,原分布映射為int8分布后,長度變為128,而原分布的長度為i(將大於i的直方圖分布結果加和值bin[i],保證分布完整性),因此必須先將分布長度調整一致,參考官方文檔:
另外計算KL散度前,要先進行歸一化處理.