深度學(xué)習(xí)Int8的部署推理原理和經(jīng)驗(yàn)驗(yàn)證
論文出處:《Integer Quantization for Deep Learning Inference Principles and Empirical Evaluation》
時(shí)間:2020.April
單位:NVIDIA
0.前言
這篇paper主要的共享是工程上的經(jīng)驗(yàn)分享,做了比較充足的實(shí)驗(yàn),基本誤差在1%以內(nèi),也給出了比較workable的int8量化部署的workflow。而且對(duì)以前比較多paper”避而不談“的mobilenet系列和BERT模型的int8量化做了詳盡的實(shí)驗(yàn)。
1、Introduction
這部分我不一一細(xì)說,就總結(jié)幾點(diǎn)很顯而易見的量化的好處:
1、32-bit的乘加變成了8-bit的乘加,同樣的硬件單元下可以speed up;
2、32-bit的參數(shù)變成了8-bit,顯然是model size變小了,需要的空間也變少了,ROM和RAM都減少了;
3、因?yàn)閮?nèi)存的要求降低了,對(duì)cache的利用率等其他內(nèi)存系統(tǒng)操作等效率也會(huì)提高。
Table 1給出了理論位寬對(duì)吞吐、帶寬等的要求,有用的信息是累加的數(shù)據(jù)類型,這一點(diǎn)在做量化部署實(shí)現(xiàn)的時(shí)候非常重要,其他數(shù)值只是個(gè)理論值,實(shí)際用處不大。

2、相關(guān)工作
這部分總結(jié)得非常好,有必要我也總結(jié)一下。
1、《Quantization and training of neural networks for effificient integer-arithmetic-only inference》,也就是做量化必須看的paper,也是tflite的實(shí)現(xiàn),也是目前QAT的做法的主流參考。這篇說的是如何用全整形進(jìn)行推理,這部分我用c代碼全部實(shí)現(xiàn)了(下次一定寫稿)。
2、《Quantizing deep convolutional networks for effificient inference: A whitepaper》,白皮書,無需多言,必看paper,也是google出品。
3、《 Discovering low-precision networks close to full-precision networks for effificient embedded inference.》這篇說的是,在imagenet上,量化成int8后只需要1個(gè)epoch就會(huì)恢復(fù)到float-32的精度;一個(gè)trick即采用退火學(xué)習(xí)率調(diào)度和最后的學(xué)習(xí)率需要很??;截?cái)嚅撝挡捎玫陌俜直鹊牟呗浴?/p>
4、《 Pact: Parameterized clipping activation for quantized neural networks.》,PACT講的是激活函數(shù)的值域范圍是可學(xué)習(xí)的。
然后很多低于8-bit的量化工作,比如1-bit、2-bit等,一些非均勻分布的量化算法(這種實(shí)際應(yīng)用中對(duì)速度有比較大的影響,大部分情況都不使用)。
上述基本都是圖像領(lǐng)域的,也例舉了一些nlp領(lǐng)域的,比如Q8bert。最近關(guān)于BERT的量化的工作有以下:Q8BERT、Q-BERT、TernaryBERT、BinaryBERT、BiBERT等。
3、量化基礎(chǔ)
均分量化即Uniform quantization分兩步:
1、選擇要量化的數(shù)值(浮點(diǎn))的范圍并截?cái)?,截?cái)嗉创笥跀?shù)值范圍的就讓其為數(shù)值范圍的最大值,反正就變成數(shù)值范圍的最小值,min(range_min, max(x, ?range_max));
2、將截?cái)嗪蟮臄?shù)值映射到整數(shù)上,這一步有round的操作。如圖所示:

描述在代碼和論文中常見的稱呼:
Quantize:將一個(gè)實(shí)數(shù)轉(zhuǎn)換為一個(gè)量化的整數(shù), 即可float32 變成int8
Dequantize:將一個(gè)數(shù)從一個(gè)量化的整數(shù)表示形式轉(zhuǎn)換為一個(gè)實(shí)數(shù),即int8變成float32
Range Mapping:即一組數(shù)值的范圍 [β, α]
Affifine Quantization:f(x) = s · x + z ,即非對(duì)稱量化,s是縮放因子,z是零點(diǎn),對(duì)于int8,那么int8的值域范圍就是[0,255]

Scale Quantization :f(x) = s · x, ?即對(duì)稱量化,對(duì)于int8,那么int8的值域范圍就是[-127, 127],不適用128這個(gè)數(shù)值,原因在IAQ論文說了是為了能用16-bit的累加器來存int8*int8,因?yàn)橛肋h(yuǎn)不存在-128 × -128,也就是改乘法的結(jié)果的絕對(duì)值不會(huì)超過2^14,可以保證用16-bit的累加器來存這個(gè)乘法結(jié)果。
Tensor Quantization Granularity:per-tensor & per-channel: 這里更加細(xì)致地分析了顆粒度如何從per-tensor變到per-channel,還有中間心態(tài)的顆粒度,但實(shí)際并不會(huì)做太多騷操作,感興趣的朋友們可以翻原文來了解。per-tensor就是整個(gè)神經(jīng)網(wǎng)絡(luò)層用一組量化參數(shù)(scale, zero-point),per-channel就是一層神經(jīng)網(wǎng)絡(luò)每個(gè)通道用一組量化參數(shù)(scale, zero-point)。那么就是per-channel需要存更多的量化參數(shù),對(duì)gemm的計(jì)算也有一點(diǎn)影響。
下圖表示了這兩種顆粒度的實(shí)驗(yàn)。值得注意的是,table3的實(shí)驗(yàn)是只量化weight的對(duì)比實(shí)驗(yàn),可以看到per-channel和per-tensor精度上基本沒什么區(qū)別,但per-tensor對(duì)fold BN在輕量化網(wǎng)絡(luò)會(huì)有比較的性能影響,而per-channel不會(huì)有這個(gè)情況。
個(gè)人觀點(diǎn),這個(gè)圖并不能下結(jié)論:per-channel和per-tensor在int8量化推理下沒有太大的差異,因?yàn)檫@只量化weight,而沒有考慮其他,比如量化activation。

Affifine Quantization即非對(duì)稱量化在做矩陣乘法的時(shí)候比對(duì)稱量化多了好幾項(xiàng):
下面是非對(duì)稱量化的乘法,即y=w × x,這里不考慮bias。
而對(duì)稱量化的乘法:多的兩項(xiàng)為:
這項(xiàng)可以提前算好,因?yàn)閣和z的數(shù)值是事先知道的。
這項(xiàng)只能運(yùn)行中計(jì)算,因?yàn)閤是神經(jīng)網(wǎng)絡(luò)中的激活值。
那么,實(shí)際應(yīng)用為了提高推理速度,更加愿意用對(duì)稱量化;這樣又有新的問題了:非對(duì)稱量化多了這么些操作,有什么增益嗎?
答:在激活函數(shù)是relu的時(shí)候,激活值全大于0,這個(gè)情況下還是用對(duì)稱量化就會(huì)浪費(fèi)一個(gè)bit的表示能力,只能[0, 127];
Calibration:Calibration是用來選模型參數(shù)和激活值的最大值和最小值,用來做截?cái)唷?/p>
又三種校準(zhǔn)的策略:
max-min:tensor的最大值和最小值,這個(gè)策略沒有截?cái)唷?/p>
KL散度(KL divergence):最小化量化后int8與float32數(shù)據(jù)的KL散度,tensorrt采用這個(gè)策略。
百分比(Percentile):選取tensor的99%或者其他百分比的數(shù)值,其余的截?cái)唷?/p>
4、PTQ:訓(xùn)練后量化
即對(duì)訓(xùn)練好的模型做量化,但不finetune。
前面發(fā)現(xiàn)per-tensor的量化,在有折疊BN的情況下會(huì)有比較大的精度損失,故作了table4的實(shí)驗(yàn),可以發(fā)現(xiàn)在只量化weight的情況下,per-channel量化和max-min的校準(zhǔn)策略,折疊BN并不會(huì)帶來影響,證明了在這個(gè)策略下可以使用折疊BN。折疊BN的好處就是算子融合,把之前需要2層即conv+bn變成了1層,減少了計(jì)算和取值。

tabel 4僅僅只是weight量化那肯定是不夠的,需要對(duì)activation也量化做的量化才是實(shí)際部署使用的,效果如下圖table 5,可以看到不用的模型/任務(wù)(分類/檢測(cè)/NLP),需要采用的校準(zhǔn)策略是不一樣的,也就是校準(zhǔn)策略沒有哪一中可以稱霸。基本int8的量化,在分類、檢測(cè)、NLP上精度損失都不大,是可以真實(shí)落地使用的量化比特位。

5、恢復(fù)精度的技術(shù):Partial Quantization(部分量化)和QAT(量化中訓(xùn)練)
Partial Quantization:量化后對(duì)模型效果影響比較大(也就是更加敏感)的就用高比特來表示,用float32/float16/int16。這個(gè)敏感度判別采用最直接簡(jiǎn)單的方法:每次只量化一層跑一遍,看模型效果的影響,影響大的就更敏感,反之就不敏感。
因?yàn)榍懊娴膶?shí)驗(yàn)發(fā)現(xiàn)efficientNet精度影響比較大,用他來實(shí)驗(yàn)partial quantization

可以看出,最開始的層和最后的層對(duì)精度影響很大,另外depthwise conv對(duì)精度的影響也比較大。depthwise conv的問題可以使用weight equalization來緩解精度損失。
Quantization-Aware Training(QAT): QAT就是在訓(xùn)練中插入fake quantize節(jié)點(diǎn) 做dequantize(quantize(x, b, s), b, s),對(duì)quantize這個(gè)節(jié)點(diǎn)因?yàn)閷?dǎo)數(shù)為0,采用STE(即梯度為0)來解決。QAT的實(shí)驗(yàn)如下table 7,會(huì)發(fā)現(xiàn)有些情況下QAT-int8比float32還好一丟丟,這時(shí)候論文作者的描述格局非常大:”Likewise, we do not interpret cases where accuracy is higher than fp32 as quantization acting as a regularizer, it is more likely to be noise or the result of the additional fifine-tuning.“,意思就是這只是實(shí)驗(yàn)中的“噪聲”,也就是并不是方法多么sota,就只是實(shí)驗(yàn)的隨機(jī)性罷了。大格局!

可學(xué)習(xí)的量化參數(shù):作者實(shí)驗(yàn)了PACT的方法,學(xué)習(xí)截?cái)嘀涤?。結(jié)論是:當(dāng)預(yù)設(shè)的range合理的時(shí)候,PACT幾乎沒有增益,也就是告訴大家不用迷信這種方法。

6. 推薦的量化的流程圖

weight:對(duì)稱量化+per-channel+max-min校準(zhǔn)策略+[-127, 127]activation:per-tensor+對(duì)稱量化
先進(jìn)行PTQ,即可量化所有層,校準(zhǔn)策略遍歷完,max-min、KL散度、百分比99.99%/99.999%,達(dá)不到要求做部分量化;
Partial Quantization:只量化某一層跑推理,記錄模型效果并且排序,用來選擇敏感度,敏感度大的用高精度;,還是達(dá)不到要求用QAT;
QAT:加載效果最好的量化模型參數(shù),插入偽量化節(jié)點(diǎn),用原來初始學(xué)習(xí)率的1%做完QAT的初始學(xué)習(xí)率,采用退化學(xué)習(xí)率衰減器。
論文附錄有煉丹配方

深度學(xué)習(xí)Int8的部署推理原理和經(jīng)驗(yàn)驗(yàn)證
論文出處:《Integer Quantization for Deep Learning Inference Principles and Empirical Evaluation》
時(shí)間:2020.April
單位:NVIDIA
0.前言
這篇paper主要的共享是工程上的經(jīng)驗(yàn)分享,做了比較充足的實(shí)驗(yàn),基本誤差在1%以內(nèi),也給出了比較workable的int8量化部署的workflow。而且對(duì)以前比較多paper”避而不談“的mobilenet系列和BERT模型的int8量化做了詳盡的實(shí)驗(yàn)。
1、Introduction
這部分我不一一細(xì)說,就總結(jié)幾點(diǎn)很顯而易見的量化的好處:
1、32-bit的乘加變成了8-bit的乘加,同樣的硬件單元下可以speed up;
2、32-bit的參數(shù)變成了8-bit,顯然是model size變小了,需要的空間也變少了,ROM和RAM都減少了;
3、因?yàn)閮?nèi)存的要求降低了,對(duì)cache的利用率等其他內(nèi)存系統(tǒng)操作等效率也會(huì)提高。
Table 1給出了理論位寬對(duì)吞吐、帶寬等的要求,有用的信息是累加的數(shù)據(jù)類型,這一點(diǎn)在做量化部署實(shí)現(xiàn)的時(shí)候非常重要,其他數(shù)值只是個(gè)理論值,實(shí)際用處不大。

2、相關(guān)工作
這部分總結(jié)得非常好,有必要我也總結(jié)一下。1、《Quantization and training of neural networks for effificient integer-arithmetic-only inference》,也就是做量化必須看的paper,也是tflite的實(shí)現(xiàn),也是目前QAT的做法的主流參考。這篇說的是如何用全整形進(jìn)行推理,這部分我用c代碼全部實(shí)現(xiàn)了(下次一定寫稿)。
2、《Quantizing deep convolutional networks for effificient inference: A whitepaper》,白皮書,無需多言,必看paper,也是google出品。3、《 Discovering low-precision networks close to full-precision networks for effificient embedded inference.》這篇說的是,在imagenet上,量化成int8后只需要1個(gè)epoch就會(huì)恢復(fù)到float-32的精度;一個(gè)trick即采用退火學(xué)習(xí)率調(diào)度和最后的學(xué)習(xí)率需要很??;截?cái)嚅撝挡捎玫陌俜直鹊牟呗浴?br />4、《 Pact: Parameterized clipping activation for quantized neural networks.》,PACT講的是激活函數(shù)的值域范圍是可學(xué)習(xí)的。
然后很多低于8-bit的量化工作,比如1-bit、2-bit等,一些非均勻分布的量化算法(這種實(shí)際應(yīng)用中對(duì)速度有比較大的影響,大部分情況都不使用)。
上述基本都是圖像領(lǐng)域的,也例舉了一些nlp領(lǐng)域的,比如Q8bert。最近關(guān)于BERT的量化的工作有以下:Q8BERT、Q-BERT、TernaryBERT、BinaryBERT、BiBERT等。
3、量化基礎(chǔ)
均分量化即Uniform quantization分兩步:1、選擇要量化的數(shù)值(浮點(diǎn))的范圍并截?cái)啵財(cái)嗉创笥跀?shù)值范圍的就讓其為數(shù)值范圍的最大值,反正就變成數(shù)值范圍的最小值,min(range_min, max(x, ?range_max));
2、將截?cái)嗪蟮臄?shù)值映射到整數(shù)上,這一步有round的操作。如圖所示:

描述在代碼和論文中常見的稱呼:
Quantize:將一個(gè)實(shí)數(shù)轉(zhuǎn)換為一個(gè)量化的整數(shù), 即可float32 變成int8
Dequantize:將一個(gè)數(shù)從一個(gè)量化的整數(shù)表示形式轉(zhuǎn)換為一個(gè)實(shí)數(shù),即int8變成float32
Range Mapping:即一組數(shù)值的范圍 [β, α]
Affifine Quantization:f(x) = s · x + z ,即非對(duì)稱量化,s是縮放因子,z是零點(diǎn),對(duì)于int8,那么int8的值域范圍就是[0,255]

Scale Quantization :f(x) = s · x, ?即對(duì)稱量化,對(duì)于int8,那么int8的值域范圍就是[-127, 127],不適用128這個(gè)數(shù)值,原因在IAQ論文說了是為了能用16-bit的累加器來存int8*int8,因?yàn)橛肋h(yuǎn)不存在-128 × -128,也就是改乘法的結(jié)果的絕對(duì)值不會(huì)超過2^14,可以保證用16-bit的累加器來存這個(gè)乘法結(jié)果。
Tensor Quantization Granularity:per-tensor & per-channel: 這里更加細(xì)致地分析了顆粒度如何從per-tensor變到per-channel,還有中間心態(tài)的顆粒度,但實(shí)際并不會(huì)做太多騷操作,感興趣的朋友們可以翻原文來了解。per-tensor就是整個(gè)神經(jīng)網(wǎng)絡(luò)層用一組量化參數(shù)(scale, zero-point),per-channel就是一層神經(jīng)網(wǎng)絡(luò)每個(gè)通道用一組量化參數(shù)(scale, zero-point)。那么就是per-channel需要存更多的量化參數(shù),對(duì)gemm的計(jì)算也有一點(diǎn)影響。
下圖表示了這兩種顆粒度的實(shí)驗(yàn)。值得注意的是,table3的實(shí)驗(yàn)是只量化weight的對(duì)比實(shí)驗(yàn),可以看到per-channel和per-tensor精度上基本沒什么區(qū)別,但per-tensor對(duì)fold BN在輕量化網(wǎng)絡(luò)會(huì)有比較的性能影響,而per-channel不會(huì)有這個(gè)情況。
個(gè)人觀點(diǎn),這個(gè)圖并不能下結(jié)論:per-channel和per-tensor在int8量化推理下沒有太大的差異,因?yàn)檫@只量化weight,而沒有考慮其他,比如量化activation。

Affifine Quantization即非對(duì)稱量化在做矩陣乘法的時(shí)候比對(duì)稱量化多了好幾項(xiàng):
下面是非對(duì)稱量化的乘法,即y=w × x,這里不考慮bias。
而對(duì)稱量化的乘法:多的兩項(xiàng)為:
這項(xiàng)可以提前算好,因?yàn)閣和z的數(shù)值是事先知道的。
這項(xiàng)只能運(yùn)行中計(jì)算,因?yàn)閤是神經(jīng)網(wǎng)絡(luò)中的激活值。
那么,實(shí)際應(yīng)用為了提高推理速度,更加愿意用對(duì)稱量化;這樣又有新的問題了:非對(duì)稱量化多了這么些操作,有什么增益嗎?
答:在激活函數(shù)是relu的時(shí)候,激活值全大于0,這個(gè)情況下還是用對(duì)稱量化就會(huì)浪費(fèi)一個(gè)bit的表示能力,只能[0, 127];
Calibration:Calibration是用來選模型參數(shù)和激活值的最大值和最小值,用來做截?cái)唷?/p>
又三種校準(zhǔn)的策略:
max-min:tensor的最大值和最小值,這個(gè)策略沒有截?cái)唷?/p>
KL散度(KL divergence):最小化量化后int8與float32數(shù)據(jù)的KL散度,tensorrt采用這個(gè)策略。
百分比(Percentile):選取tensor的99%或者其他百分比的數(shù)值,其余的截?cái)唷?/p>
4、PTQ:訓(xùn)練后量化
即對(duì)訓(xùn)練好的模型做量化,但不finetune。
前面發(fā)現(xiàn)per-tensor的量化,在有折疊BN的情況下會(huì)有比較大的精度損失,故作了table4的實(shí)驗(yàn),可以發(fā)現(xiàn)在只量化weight的情況下,per-channel量化和max-min的校準(zhǔn)策略,折疊BN并不會(huì)帶來影響,證明了在這個(gè)策略下可以使用折疊BN。折疊BN的好處就是算子融合,把之前需要2層即conv+bn變成了1層,減少了計(jì)算和取值。

tabel 4僅僅只是weight量化那肯定是不夠的,需要對(duì)activation也量化做的量化才是實(shí)際部署使用的,效果如下圖table 5,可以看到不用的模型/任務(wù)(分類/檢測(cè)/NLP),需要采用的校準(zhǔn)策略是不一樣的,也就是校準(zhǔn)策略沒有哪一中可以稱霸?;緄nt8的量化,在分類、檢測(cè)、NLP上精度損失都不大,是可以真實(shí)落地使用的量化比特位。

5、恢復(fù)精度的技術(shù):Partial Quantization(部分量化)和QAT(量化中訓(xùn)練)
Partial Quantization:量化后對(duì)模型效果影響比較大(也就是更加敏感)的就用高比特來表示,用float32/float16/int16。這個(gè)敏感度判別采用最直接簡(jiǎn)單的方法:每次只量化一層跑一遍,看模型效果的影響,影響大的就更敏感,反之就不敏感。
因?yàn)榍懊娴膶?shí)驗(yàn)發(fā)現(xiàn)efficientNet精度影響比較大,用他來實(shí)驗(yàn)partial quantization

可以看出,最開始的層和最后的層對(duì)精度影響很大,另外depthwise conv對(duì)精度的影響也比較大。depthwise conv的問題可以使用weight equalization來緩解精度損失。
Quantization-Aware Training(QAT): QAT就是在訓(xùn)練中插入fake quantize節(jié)點(diǎn) 做dequantize(quantize(x, b, s), b, s),對(duì)quantize這個(gè)節(jié)點(diǎn)因?yàn)閷?dǎo)數(shù)為0,采用STE(即梯度為0)來解決。QAT的實(shí)驗(yàn)如下table 7,會(huì)發(fā)現(xiàn)有些情況下QAT-int8比float32還好一丟丟,這時(shí)候論文作者的描述格局非常大:”Likewise, we do not interpret cases where accuracy is higher than fp32 as quantization acting as a regularizer, it is more likely to be noise or the result of the additional fifine-tuning.“,意思就是這只是實(shí)驗(yàn)中的“噪聲”,也就是并不是方法多么sota,就只是實(shí)驗(yàn)的隨機(jī)性罷了。大格局!

可學(xué)習(xí)的量化參數(shù):作者實(shí)驗(yàn)了PACT的方法,學(xué)習(xí)截?cái)嘀涤?。結(jié)論是:當(dāng)預(yù)設(shè)的range合理的時(shí)候,PACT幾乎沒有增益,也就是告訴大家不用迷信這種方法。

6. 推薦的量化的流程圖

weight:對(duì)稱量化+per-channel+max-min校準(zhǔn)策略+[-127, 127]activation:per-tensor+對(duì)稱量化
先進(jìn)行PTQ,即可量化所有層,校準(zhǔn)策略遍歷完,max-min、KL散度、百分比99.99%/99.999%,達(dá)不到要求做部分量化;
Partial Quantization:只量化某一層跑推理,記錄模型效果并且排序,用來選擇敏感度,敏感度大的用高精度;,還是達(dá)不到要求用QAT;
QAT:加載效果最好的量化模型參數(shù),插入偽量化節(jié)點(diǎn),用原來初始學(xué)習(xí)率的1%做完QAT的初始學(xué)習(xí)率,采用退化學(xué)習(xí)率衰減器。
論文附錄有煉丹配方
- END -?
