機(jī)器學(xué)習(xí)服務(wù)提取圖片的特征向量">使用SAP Leonardo上的機(jī)器學(xué)習(xí)服務(wù)提取圖片的特征向量
1990
2025-03-31
目標(biāo): 在沒有明顯準(zhǔn)確度丟失的情況下將FP32的CNNs網(wǎng)絡(luò)轉(zhuǎn)換為INT8
理由: INT8類型的存儲(chǔ)方式有很高的通量和較低的內(nèi)存需求
挑戰(zhàn): 相對(duì)于FP32, INT8有明顯較低的精度和動(dòng)態(tài)范圍
解決方式: 在將權(quán)值以及計(jì)算時(shí)最小化有效信息損失.
結(jié)果: 上述轉(zhuǎn)換可以通過TensorRT來進(jìn)行實(shí)現(xiàn),同時(shí)該方法不需要額外的大量調(diào)整和重新訓(xùn)練
對(duì)于INT8 推斷(Inference),需要生成一個(gè)校準(zhǔn)表來量化模型。接下來主要關(guān)注INT8推斷(Inference)的幾個(gè)方面,即:如何生成校準(zhǔn)表,如何使用校準(zhǔn)表,和INT8推斷(Inference)實(shí)例。
面臨的挑戰(zhàn)
相對(duì)于FP32,INT8的精度和動(dòng)態(tài)范圍要小很多:
從FP32到INT8需要不止一次的類型轉(zhuǎn)換
1) 如何生成校準(zhǔn)表?
校準(zhǔn)表的生成需要輸入有代表性的數(shù)據(jù)集, 對(duì)于分類任務(wù)TensorRT建議輸入五百張到一千張有代表性的圖片,最好每個(gè)類都要包括。生成校準(zhǔn)表分為兩步:第一步是將輸入的數(shù)據(jù)集轉(zhuǎn)換成batch文件;第二步是將轉(zhuǎn)換好的batch文件喂到TensorRT中來生成基于數(shù)據(jù)集的校準(zhǔn)表,可以去統(tǒng)計(jì)每一層的情況。
2) 如何使用校準(zhǔn)表?
校準(zhǔn)這個(gè)過程如果要跑一千次是很昂貴的,所以TensorRT支持將其存入文檔,后期使用可以從文檔加載,其中存儲(chǔ)和加載的功能通過兩個(gè)方法來支持,即writeCalibrationCache和readCalibrationCache。最簡單的實(shí)現(xiàn)是從write()和read()返回值,這樣就必須每次執(zhí)行都做一次校準(zhǔn)。如果想要存儲(chǔ)校準(zhǔn)時(shí)間,需要實(shí)現(xiàn)用戶自定義的write/read方法,具體的實(shí)現(xiàn)可以參考TensorRT中的simpleINT8實(shí)例。
INT8相較于FP32的計(jì)算量變小了,同樣也需要適合小精度的計(jì)算單元來執(zhí)行,否則同樣在FP32計(jì)算單元上面執(zhí)行,則只在模型大小上面有一定的優(yōu)勢,而并不能帶來真正性能的提升,這時(shí)候就要談到GPU為INT8計(jì)算的提供的硬件支持。
對(duì)于sm_61+如Tesla P4/P40 GPU,我們提供了新的INT8點(diǎn)乘運(yùn)算的指令支持---DP4A,其將FP32單元“拆開“分成4個(gè)INT8單元,從而通過兩個(gè)FP32單元實(shí)現(xiàn)4個(gè)INT8數(shù)的點(diǎn)乘操作,最后累加成INT32的結(jié)果,計(jì)算過程如下圖所示:
從而對(duì)于Tesla P4來說,其擁有5.5T的FP32計(jì)算性能,通過DP4A指令為其賦予了INT8的計(jì)算能力,并達(dá)到了FP32的4倍也就是22T的計(jì)算性能。
線性量化
對(duì)于每一個(gè)FP32的Tensor(權(quán)值和激活值),我們無法直接用INT8來表示,因此最直接的表達(dá)方法為:
Tensor Values = FP32 scale factor * int8 array + FP32 bias
這時(shí)候我們需要考慮一個(gè)問題,我們是否真的需要FP32的bias?
對(duì)于以下兩個(gè)矩陣:
A = scale_A * QA + bias_A
B = scale_B * QB + bias_B
推理過程中絕大部分為矩陣乘法,因此這兩個(gè)矩陣相乘的計(jì)算可以表示為:
A * B = scale_A * scale_B * QA * QB + scale_A * QA * bias_B + scale_B * QB * bias_A + bias_A * bias_B
如果我們直接將去掉bias,則兩者相乘為:
A * B = scale_A * scale_B * QA * QB
通過去掉bias我們能極大的簡化計(jì)算內(nèi)容,降低對(duì)GPU中寄存器等資源的消耗,而我們的實(shí)驗(yàn)也發(fā)現(xiàn)去掉bias不會(huì)對(duì)性能產(chǎn)生很大的影響。故而TensorRT在這里采用的優(yōu)化的對(duì)稱線性量化方法:
Tensor Values = FP32 scale factor * int8 array
現(xiàn)在問題就變成如何尋找一個(gè)最優(yōu)的scale factor?
量化有以下兩種方法:
圖左-非saturation:對(duì)weights和activations使用線性量化,即找到其中絕對(duì)值最大的值,然后將這個(gè)范圍映射回INT8
圖右-saturation:選擇一個(gè)閾值T,將范圍T的FP32值映射至INT8,對(duì)于范圍外的使用-127或128
根據(jù)實(shí)驗(yàn)證明,圖左的方法轉(zhuǎn)化后會(huì)帶來很大的準(zhǔn)確度損失。而對(duì)于圖右的方法:
weights:無法提升準(zhǔn)確度
activations:能有效提升準(zhǔn)確度
因此對(duì)于weights和activations分別采用了不同的量化方法,前者使用了簡單的非saturation的方法,而后者采用的是較為復(fù)雜的saturation方法。
量化整體流程
以卷積kernel為例:
輸入為:INT8_INPUT,I8_weights
輸出為:INT8_OUTPUT
所需參數(shù):FP32 bias (來自于FP32模型中),F(xiàn)P32 scaling factors: input_scale, output_scale, weights_scale[K]
利用DP4A指令計(jì)算?INT8_INPUT與I8_weights的乘積獲得I32_gemm_out
利用input_scale以及weights_scale將I32_gemm_out轉(zhuǎn)化成為FP32的F32_gemm_out
利用input_scale, output_scale和weights_scale ? ? ?將FP32的F32_gemm_out映射至輸出的activation分布,獲得rescaled_F32_gemm_out
給rescaled_F32_gemm_out加上FP32的bias獲得rescaled_F32_gemm_out _with_bias
對(duì)rescaled_F32_gemm_out _with_bias執(zhí)行relu從而獲得F32_result
最后根據(jù)前文的閾值T將F32_result轉(zhuǎn)成I8_output
根據(jù)所選的量化方法以及量化的整體流程,對(duì)于量化最關(guān)鍵的是如何實(shí)現(xiàn)saturation方法中的閾值T的選擇,這個(gè)選擇流程被稱之為校準(zhǔn)。
校準(zhǔn)
上圖分別是vgg19-conv3_4, resnet152-res4b8_branch2a, googlenet:incetion_3a/pool的activations的分布直方圖,其中橫軸為activation值,縱軸是正則化后的值的數(shù)量級(jí)。
對(duì)于將activations從FP32映射至INT8可以看成是信息的重編碼過程,需要做的是在INT8中最大的保留FP32的信息,這里通過引入KL divergence來作為INT8的信息損失率評(píng)價(jià)指標(biāo)。
校準(zhǔn)的整體流程
選取validation數(shù)據(jù)集中一部分具有代表的數(shù)據(jù)作為校準(zhǔn)數(shù)據(jù)集
對(duì)于校準(zhǔn)數(shù)據(jù)進(jìn)行FP32的推理,對(duì)于每一層
收集activation的分布直方圖
使用不同的threshold來生成一定數(shù)量的量化好的分布
計(jì)算量化好的分布與FP32分布的KL divergence,并選取使KL最小的threshold作為saturation的閾值
整個(gè)流程將花費(fèi)幾分鐘至幾十分鐘來完成
以下是幾個(gè)常見網(wǎng)絡(luò)的部分activation分布及校準(zhǔn)結(jié)果:
GOOGLENET:Inception_5a/5x5
ALEXNET:Pool2
RESNET:Res4b30
如上三圖分別是GOOGLENET/ALEXNET/RESNET中某一層的activation的分布,其中白線的左邊的activation數(shù)據(jù)將映射至INT8中,而右邊的將被截?cái)唷?/p>
可以明顯的看到前兩個(gè)網(wǎng)絡(luò)的FP32 activation分布在INT8中得以幾乎完整的保留。
第三個(gè)圖左的白線截?cái)嗔似溆覀?cè)activation的分布,第三個(gè)圖右為截?cái)嗪蟮姆植紙D。圖中的綠點(diǎn)即為截?cái)嗖糠钟成渲罥NT8的極大值所占比例,可以看到綠點(diǎn)在整體分布的所占比例并不大,因此損失的信息仍然是可以接受的,校準(zhǔn)也極大的保留的FP32的activation的分布信息。
人工智能 AI
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。