PTQ 精度 Debug 工具
使用 PTQ 后量化的模型量化方案,可以幫助用戶(hù)非常簡(jiǎn)單便捷地完成從浮點(diǎn)模型到地平線混合異構(gòu)模型的轉(zhuǎn)換,模型轉(zhuǎn)換工具會(huì)基于用戶(hù)提供的校準(zhǔn)樣本對(duì)模型進(jìn)行校準(zhǔn)量化并保障模型高效地部署在地平線計(jì)算平臺(tái)上。
但是在模型轉(zhuǎn)換的過(guò)程中,不可避免地會(huì)因?yàn)楦↑c(diǎn)高精度到定點(diǎn)低精度的量化過(guò)程而引入精度損失,因此為了幫助用戶(hù)準(zhǔn)確快速地定位模型精度損失的主要原因,地平線工具鏈提供了一套 PTQ 精度 Debug 工具。
本文將基于 征程5 工具鏈 1.1.62 版本的 OpenExplorer 開(kāi)發(fā)包來(lái)詳細(xì)介紹這些工具的使用方法和使用流程,以及對(duì)輸出結(jié)果進(jìn)行解讀,來(lái)幫助用戶(hù)快速上手。
對(duì)于 XJ3 工具鏈,PTQ 精度 Debug 工具的使用方法一致,但是暫不支持命令行配置和 runall 功能。
在本文開(kāi)始之前,需要用戶(hù)參考文章圖片校準(zhǔn)數(shù)據(jù)準(zhǔn)備問(wèn)題介紹與處理和模型精度驗(yàn)證及調(diào)優(yōu)建議,掌握正確處理校準(zhǔn)數(shù)據(jù)以及評(píng)測(cè)模型精度的方法,并且排除因輸入數(shù)據(jù)預(yù)處理不當(dāng)和欠佳的推理結(jié)果后處理等非模型自身造成的精度問(wèn)題。
在 PTQ 模型后量化過(guò)程中,通常情況下造成精度損失的主要原因可能有以下幾點(diǎn):
敏感節(jié)點(diǎn)量化問(wèn)題。模型中的一部分節(jié)點(diǎn)對(duì)量化比較敏感會(huì)引入較大誤差;
節(jié)點(diǎn)量化誤差累積問(wèn)題。模型中各個(gè)節(jié)點(diǎn)的量化誤差累積導(dǎo)致模型整體出現(xiàn)較大的校準(zhǔn)誤差,主要包含:權(quán)重量化導(dǎo)致的誤差累積、激活量化導(dǎo)致的誤差累積以及全量量化導(dǎo)致的誤差累積。
針對(duì)上述情況,地平線工具鏈提供的精度 Debug 工具將協(xié)助用戶(hù)自主定位模型量化過(guò)程中產(chǎn)生的精度問(wèn)題,對(duì)校準(zhǔn)模型進(jìn)行節(jié)點(diǎn)粒度的量化誤差分析并快速定位出現(xiàn)精度異常的節(jié)點(diǎn)。
PTQ 精度 Debug 工具提供的功能包括:
獲取節(jié)點(diǎn)量化敏感度;
獲取模型累積誤差曲線;
獲取指定節(jié)點(diǎn)的數(shù)據(jù)分布;
獲取指定節(jié)點(diǎn)輸入數(shù)據(jù)通道間數(shù)據(jù)分布箱線圖等。
使用精度 Debug 工具進(jìn)行精度 Debug 的基本流程為:
1.校準(zhǔn)模型和校準(zhǔn)數(shù)據(jù)的準(zhǔn)備。校準(zhǔn)模型在模型轉(zhuǎn)換過(guò)程中為常態(tài)化保存,無(wú)需用戶(hù)額外操作,為模型轉(zhuǎn)換的輸出目錄model_output下的calibrated_model;校準(zhǔn)數(shù)據(jù)的保存需要用戶(hù)在 Yaml 文件中的模型參數(shù)組中增加如下參數(shù)配置(配置后精度 Debug 功能同時(shí)開(kāi)啟,但需要用戶(hù)重新編譯一次模型,編譯等級(jí)可以配置為 O0 以減少編譯時(shí)間):
model_parameters:
debug_mode: "dump_calibration_data"
2.通過(guò)import horizon_nn.debug as dbg導(dǎo)入 Debug 模塊(使用命令行則無(wú)需導(dǎo)入),加載校準(zhǔn)模型和校準(zhǔn)數(shù)據(jù);
3.通過(guò)精度 Debug 工具提供的 API 或者命令行,對(duì)精度損失明顯的模型進(jìn)行分析。(詳細(xì)的流程以及分析見(jiàn)后文。)
校準(zhǔn)數(shù)據(jù)(calibration_data)在模型轉(zhuǎn)換的校準(zhǔn)階段使用,模型通過(guò)對(duì)這些數(shù)據(jù)進(jìn)行前向推理來(lái)獲取每個(gè)被量化節(jié)點(diǎn)的量化參數(shù),量化參數(shù)包括:縮放因子(Scale)和閾值(Threshold)。
值得注意的是,此處保存的校準(zhǔn)數(shù)據(jù)是經(jīng)過(guò)顏色空間轉(zhuǎn)換以及預(yù)處理之后的 npy 格式的數(shù)據(jù),該數(shù)據(jù)可以通過(guò)np.load()直接送入校準(zhǔn)模型進(jìn)行推理,不同于在模型轉(zhuǎn)換前數(shù)據(jù)準(zhǔn)備階段使用02_preprocess.sh腳本生成的校準(zhǔn)數(shù)據(jù)。
使用腳本生成的校準(zhǔn)數(shù)據(jù)是 bgr 顏色空間的數(shù)據(jù),在工具鏈內(nèi)部會(huì)將數(shù)據(jù)從 bgr 轉(zhuǎn)換到 yuv444/gray 等模型實(shí)際輸入的格式。
按照上述精度 Debug 流程中提到的操作保存校準(zhǔn)數(shù)據(jù)后,自動(dòng)在model_output目錄下生成的calibration_data文件夾結(jié)構(gòu)如下所示:
|-- calibration_data #校準(zhǔn)數(shù)據(jù)
|---- input1 #文件夾名為模型的輸入節(jié)點(diǎn)并保存對(duì)應(yīng)的輸入數(shù)據(jù)
|-------- 0.npy
|-------- 1.npy
|-------- ...
|---- input2 #對(duì)于多輸入模型將保存多個(gè)文件夾
|-------- 0.npy
|-------- 1.npy
|-------- ...
|---- ...
校準(zhǔn)模型(calibrated_model.onnx)是將在校準(zhǔn)階段計(jì)算得到的每個(gè)被量化節(jié)點(diǎn)的量化參數(shù)保存在校準(zhǔn)節(jié)點(diǎn)中,從而得到的模型。
模型轉(zhuǎn)換過(guò)程中,模型轉(zhuǎn)換工具將浮點(diǎn)模型進(jìn)行結(jié)構(gòu)優(yōu)化后,通過(guò)校準(zhǔn)數(shù)據(jù)計(jì)算得到每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的量化參數(shù)并將其保存在校準(zhǔn)節(jié)點(diǎn)中,形成了校準(zhǔn)模型。
因此校準(zhǔn)模型是一種中間產(chǎn)物,主要特點(diǎn)是模型中包含校準(zhǔn)節(jié)點(diǎn),校準(zhǔn)節(jié)點(diǎn)的節(jié)點(diǎn)類(lèi)型為 HzCalibration。
校準(zhǔn)節(jié)點(diǎn)主要分為兩類(lèi):
激活(activation)校準(zhǔn)節(jié)點(diǎn)。激活校準(zhǔn)節(jié)點(diǎn)的輸入是當(dāng)前節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)的輸出,并基于當(dāng)前激活校準(zhǔn)節(jié)點(diǎn)中保存的量化參數(shù)對(duì)輸入數(shù)據(jù)進(jìn)行量化和反量化后輸出;
權(quán)重(weight)校準(zhǔn)節(jié)點(diǎn)。權(quán)重校準(zhǔn)節(jié)點(diǎn)的輸入是模型的原始浮點(diǎn)權(quán)重,并基于當(dāng)前權(quán)重校準(zhǔn)節(jié)點(diǎn)中保存的量化參數(shù)對(duì)輸入的原始浮點(diǎn)權(quán)重進(jìn)行量化和反量化后輸出。
除了上述的校準(zhǔn)節(jié)點(diǎn),校準(zhǔn)模型中的其他節(jié)點(diǎn)稱(chēng)為普通節(jié)點(diǎn)(node),普通節(jié)點(diǎn)的類(lèi)型包括:Conv、Mul 和 Add 等。
下圖直觀地展示了校準(zhǔn)節(jié)點(diǎn)和普通節(jié)點(diǎn)在校準(zhǔn)模型中扮演的角色:
為了方便用戶(hù)快速獲取 PTQ Debug 工具的結(jié)果,這里推薦使用一鍵運(yùn)行功能,可以一鍵運(yùn)行 PTQ Debug 工具中的全部功能。每個(gè)功能的詳細(xì)解讀可以參考第三部分功能詳解。
根據(jù)經(jīng)驗(yàn),校準(zhǔn)數(shù)據(jù)的數(shù)量對(duì) PTQ Debug 的結(jié)果不會(huì)有太大影響,為了加速工具運(yùn)行,建議用戶(hù)使用一份校準(zhǔn)數(shù)據(jù)即可,配置詳見(jiàn)參數(shù)介紹。
此外 PTQ 精度 Debug 工具可以使用 GPU 進(jìn)行計(jì)算加速,用戶(hù)需要進(jìn)入 GPU Docker 中先卸載預(yù)安裝的 CPU 版本horizon-nn,再安裝對(duì)應(yīng)版本的horizon-nn-gpu,安裝所需的 wheel 文件在路徑ddk/package/host/ai_toolchain下,這樣可以保證完整覆蓋。
注意:因涉及 ONNXRuntime 版本問(wèn)題,使用 GPU 加速計(jì)算僅作為嘗試,如遇報(bào)錯(cuò),建議回退 CPU 進(jìn)行計(jì)算。
# 導(dǎo)入debug模塊
import horizon_nn.debug as dbg
dbg.runall(model_or_file='./calibrated_model.onnx',
calibrated_data='./calibration_data',)
# 例如
hmct-debugger runall calibrated_model.onnx calibration_data
3. 參數(shù)介紹可通過(guò)hmct-debugger runall -h/--help查看相關(guān)參數(shù)。
詳細(xì)的 API 和命令行參數(shù)說(shuō)明以及配置介紹,閱讀原文后至社區(qū)搜索《 J5 算法工具鏈—PTQ Debug 工具使用》。
4. 執(zhí)行順序PTQ Debug 工具各個(gè)功能的運(yùn)行順序如下:
分別獲取權(quán)重校準(zhǔn)節(jié)點(diǎn)和激活校準(zhǔn)節(jié)點(diǎn)的量化敏感度;
根據(jù) step1 的結(jié)果,分別取權(quán)重校準(zhǔn)節(jié)點(diǎn)的 top5 和激活校準(zhǔn)節(jié)點(diǎn)的 top5 繪制其數(shù)據(jù)分布;
針對(duì) step2 獲取的節(jié)點(diǎn),分別繪制其通道間數(shù)據(jù)分布的箱線圖;
繪制分別只量化權(quán)重和只量化激活的累積誤差曲線。
注:當(dāng)指定node_type='node'時(shí),工具會(huì)獲取 top5 節(jié)點(diǎn),并分別找到每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的校準(zhǔn)節(jié)點(diǎn),并獲取其校準(zhǔn)節(jié)點(diǎn)的數(shù)據(jù)分布和箱線圖。
PTQ Debug 分析的流程如下所示:
首先根據(jù)累積誤差曲線判斷模型量化掉點(diǎn)是由激活量化導(dǎo)致的還是由權(quán)重量化導(dǎo)致的,確定是激活量化問(wèn)題還是權(quán)重量化問(wèn)題。如果激活和權(quán)重的單獨(dú)量化誤差不明顯,可以判斷是兩者共同作用導(dǎo)致的。
對(duì)于激活量化問(wèn)題,根據(jù)激活節(jié)點(diǎn)的量化敏感度排序確定敏感節(jié)點(diǎn);對(duì)于權(quán)重量化問(wèn)題,根據(jù)權(quán)重節(jié)點(diǎn)的量化敏感度排序確定敏感節(jié)點(diǎn);對(duì)于激活和權(quán)重量化問(wèn)題,計(jì)算普通節(jié)點(diǎn)的量化敏感度并排序,確定敏感節(jié)點(diǎn)。
獲取量化敏感節(jié)點(diǎn)后,進(jìn)行部分節(jié)點(diǎn)以較高精度量化或部分節(jié)點(diǎn)不量化測(cè)試。在 J5 工具鏈上,可以對(duì)敏感節(jié)點(diǎn)設(shè)置 Int16 量化,Int16 量化調(diào)優(yōu)工具的使用參考社區(qū)文章 PTQ 精度調(diào)優(yōu)手段—設(shè)置 Int16 量化,同時(shí)也可以讓敏感節(jié)點(diǎn)run_on_cpu。XJ3 工具鏈暫不支持用戶(hù)手動(dòng)設(shè)置節(jié)點(diǎn)以 Int16 精度量化,可以讓敏感節(jié)點(diǎn)run_on_cpu。
同時(shí)還可以根據(jù)敏感節(jié)點(diǎn)數(shù)據(jù)分布直方圖以及通道間數(shù)據(jù)分布的箱線圖來(lái)明確優(yōu)化方向,例如激活敏感節(jié)點(diǎn)數(shù)據(jù)分布不均勻則可以通過(guò)優(yōu)化模型結(jié)構(gòu)來(lái)改善,權(quán)重敏感節(jié)點(diǎn)數(shù)據(jù)分布不均勻則建議使用 QAT 等。
接下來(lái)將針對(duì) PTQ 精度 Debug 工具提供的功能和對(duì)應(yīng)的 API 或命令行使用方法,逐一進(jìn)行詳解。
通過(guò)只量化浮點(diǎn)模型中的某一個(gè)節(jié)點(diǎn),并依次計(jì)算該模型中每個(gè)節(jié)點(diǎn)與浮點(diǎn)模型中節(jié)點(diǎn)輸出的誤差,獲得累積誤差曲線。
API 使用方法:# 導(dǎo)入debug模塊
import horizon_nn.debug as dbg
dbg.plot_acc_error(
save_dir='./',
calibrated_data='./calibration_data/',
model_or_file='./calibrated_model.onnx',
quantize_node=['weight', 'activation'],
metric='cosine-similarity',
average_mode=False)
# 例如
hmct-debugger plot-acc-error calibrated_model.onnx calibration_data -q ['weight', 'activation']
可通過(guò)hmct-debugger plot-acc-error -h/--help查看相關(guān)參數(shù)。
詳細(xì)的 API 和命令行參數(shù)說(shuō)明以及配置介紹,閱讀原文后到社區(qū)搜索《 J5 算法工具鏈—PTQ Debug 工具使用》。
指定單節(jié)點(diǎn)量化/不量化:
如下配置意為分別只量化Conv_2和Conv_90并保持其他節(jié)點(diǎn)不量化,計(jì)算累積誤差曲線;或分別解除量化Conv_2和Conv_90并保持其他節(jié)點(diǎn)量化,計(jì)算累積誤差曲線。
API 配置方式為:
quantize_node=['Conv_2', 'Conv_90']/non_quantize_node=['Conv_2', 'Conv_90']
命令行配置方式為:
-q ['Conv_2', 'Conv_90']/-nq ['Conv_2', 'Conv_90']
指定多個(gè)節(jié)點(diǎn)量化/不量化:如下配置意為分別只量化Conv_2以及只量化Conv_2和Conv_90并保持其他節(jié)點(diǎn)不量化,計(jì)算累積誤差曲線;或分別解除量化Conv_2以及解除量化Conv_2和Conv_90并保持其他節(jié)點(diǎn)量化,計(jì)算累積誤差曲線。
API 配置方式為:
quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']]/non_quantize_node=[['Conv_2'], ['Conv_2', 'Conv_90']]
命令行配置方式為:
-q [['Conv_2'], ['Conv_2', 'Conv_90']]/-nq [['Conv_2'], ['Conv_2', 'Conv_90']]
按照量化敏感度排序選擇節(jié)點(diǎn)量化/不量化:
注:non_quantize_node設(shè)置不量化的節(jié)點(diǎn)等價(jià)于讓其運(yùn)行在 CPU 上。
測(cè)試部分量化精度時(shí),可以按照量化敏感度排序進(jìn)行多組量化策略的精度對(duì)比,此時(shí)可以參考以下用法:
# 導(dǎo)入debug模塊
import horizon_nn.debug as dbg
# 首先使用量化敏感度排序函數(shù)獲取模型中節(jié)點(diǎn)的量化敏感度排序,或者可以直接加載保存的量化敏感度
node_message = dbg.get_sensitivity_of_nodes(
model_or_file='./calibrated_model.onnx',
metrics='cosine-similarity',
calibrated_data='./calibration_data/',
output_node=None,
node_type='node',
verbose=False,
interested_nodes=None)
# node_message為字典類(lèi)型,其key值為節(jié)點(diǎn)名稱(chēng)
nodes = list(node_message.keys())
# 通過(guò)nodes來(lái)指定不量化節(jié)點(diǎn),可以方便使用
dbg.plot_acc_error(
save_dir='./',
calibrated_data='./calibration_data/',
model_or_file='./calibrated_model.onnx',
non_quantize_node=[nodes[:1],nodes[:2]], #分別解除量化敏感度排序靠前的節(jié)點(diǎn)
metric='cosine-similarity',
average_mode=True)
針對(duì)部分量化精度分析的累積誤差曲線圖,在分析時(shí),用戶(hù)應(yīng)當(dāng)更關(guān)注模型輸出位置(曲線尾部)的量化相似度,例如下圖,qmodel_1 模型的精度要好于 qmodel_0:
指定激活節(jié)點(diǎn)/權(quán)重節(jié)點(diǎn)分別量化:
如下配置意為分別只量化權(quán)重節(jié)點(diǎn)和激活節(jié)點(diǎn)并保持其他節(jié)點(diǎn)不量化,計(jì)算累積誤差曲線。
API 配置方式為:quantize_node=['weight', 'activation']
命令行配置方式為:-q ['weight', 'activation']
可視化結(jié)果:通過(guò)下圖可以分析出激活節(jié)點(diǎn)量化引入了大量的量化累積誤差,而權(quán)重節(jié)點(diǎn)量化對(duì)模型精度無(wú)負(fù)面影響。
##
4.2 獲取節(jié)點(diǎn)量化敏感度# 導(dǎo)入debug模塊
import horizon_nn.debug as dbg
# 導(dǎo)入log日志模塊
import logging
# 若verbose=True時(shí),需要先設(shè)置log level為INFO
logging.getLogger().setLevel(logging.INFO)
# 獲取節(jié)點(diǎn)量化敏感度
node_message = dbg.get_sensitivity_of_nodes(
model_or_file='./calibrated_model.onnx',
metrics=['cosine-similarity', 'mse'],
calibrated_data='./calibration_data/',
output_node=None,
node_type='node',
data_num=None,
verbose=True,
interested_nodes=None)
# 例如
hmct-debugger get-sensitivity-of-nodes calibrated_model.onnx calibration_data -m ['cosine-similarity','mse']
可通過(guò)hmct-debugger get-sensitivity-of-nodes -h/--help查看相關(guān)參數(shù)
詳細(xì)的 API 和命令行參數(shù)說(shuō)明以及配置介紹,見(jiàn) J5 算法工具鏈—PTQ Debug 工具使用。
首先您通過(guò)node_type設(shè)置需要計(jì)算敏感度的節(jié)點(diǎn)類(lèi)型,然后工具獲取校準(zhǔn)模型中所有符合node_type的節(jié)點(diǎn),并獲取這些節(jié)點(diǎn)的量化敏感度。當(dāng)verbose設(shè)置為 True 時(shí),工具會(huì)將節(jié)點(diǎn)量化敏感度進(jìn)行排序后打印在終端,排序越靠前,說(shuō)明該節(jié)點(diǎn)量化引入的量化誤差越大。
同時(shí)對(duì)于不同的node_type,工具會(huì)顯示不同的節(jié)點(diǎn)量化敏感度信息,設(shè)置verbose=True,結(jié)果如下:
# node_type='node'
=================node sensitivity=================
node cosine-similarity mse
---------------------------------------------------
Conv_60 0.77795 68.02103
...
# node_type='weight'
# weight:權(quán)重校準(zhǔn)節(jié)點(diǎn)名
# node:權(quán)重校準(zhǔn)節(jié)點(diǎn)對(duì)應(yīng)的普通節(jié)點(diǎn)名,即權(quán)重校準(zhǔn)節(jié)點(diǎn)的輸出為其輸入
====================================node sensitivity====================================
weight node cosine-similarity mse
-----------------------------------------------------------------------------------------
471_HzCalibration Conv_2 0.99978 0.07519
...
# node_type='activation'
# activation:激活校準(zhǔn)節(jié)點(diǎn)名
# node:激活校準(zhǔn)節(jié)點(diǎn)后的普通節(jié)點(diǎn),即激活校準(zhǔn)節(jié)點(diǎn)的輸出為其輸入
# threshold:校準(zhǔn)閾值,若有多個(gè)閾值則取最大值
# bit:量化比特
===================================node sensitivity===================================
activation node threshold bit cosine-similarity mse
---------------------------------------------------------------------------------------
406_HzCalibration Conv_60 0.91501 8 0.77851 67.82422
...
此外,調(diào)用 API 時(shí),API 還將以字典格式(Key 為節(jié)點(diǎn)名稱(chēng),Value 為節(jié)點(diǎn)的量化敏感度信息)返回節(jié)點(diǎn)量化敏感度信息,以供用戶(hù)后續(xù)使用,返回格式如下:
node_message:
{'Conv_60': {'cosine-similarity': 0.77795, 'mse': 68.02103},
'Conv_48': {'cosine-similarity': 0.78428, 'mse': 64.36318},
...
}
由于模型的量化敏感度在 PTQ 精度 Debug 過(guò)程中扮演著重要的角色,累積誤差曲線的計(jì)算分析中會(huì)用到,因此建議用戶(hù)及時(shí)保存模型量化敏感度,直接加載以節(jié)省時(shí)間,可以參考如下代碼進(jìn)行量化敏感度的保存與加載:
注意:命令行暫時(shí)無(wú)法手動(dòng)保存量化敏感度。
# node_message保存為text文件
filename = open('sensitivity_of_nodes.txt', 'w')
for node, sensitivity in node_message.items():
filename.write(str(node) + ':' + str(sensitivity))
filename.write('\n')
filename.close()
# 加載保存的text文件
node_message = {}
filename = open('sensitivity_of_nodes.txt')
for line in filename:
line_split = line.split(':', 1) #按照第一個(gè)出現(xiàn)的':'進(jìn)行分割
node_message[line_split[0]] = line_split[1] #{str: str,...}
filename.close()
# node_message保存為json文件(推薦)
import json
save_json = json.dumps(node_message, sort_keys=False, indent=4, separators=(',', ': '))
filename = open('sensitivity_of_nodes.json', 'w')
filename.write(save_json)
filename.close()
# 加載保存的json文件
filename = open('sensitivity_of_nodes.json', 'r')
node_message = json.load(filename)
filename.close()
指定節(jié)點(diǎn),分別獲取該節(jié)點(diǎn)在浮點(diǎn)模型和校準(zhǔn)模型中的輸出,得到輸出數(shù)據(jù)分布。另外,將兩個(gè)輸出結(jié)果做差,獲取兩個(gè)輸出之間的誤差分布。
# 導(dǎo)入debug模塊
import horizon_nn.debug as dbg
dbg.plot_distribution(
save_dir='./',
model_or_file='./calibrated_model.onnx',
calibrated_data='./calibration_data',
nodes_list=['317_HzCalibration', #激活節(jié)點(diǎn)
'471_HzCalibration', #權(quán)重節(jié)點(diǎn)
'Conv_2']) #普通節(jié)點(diǎn)
hmct-debugger plot-distribution calibrated_model.onnx calibration_data -n ['317_HzCalibration','471_HzCalibration','Conv_2']
可通過(guò)hmct-debugger plot-distribution -h/--help查看相關(guān)參數(shù)。
詳細(xì)的 API 和命令行參數(shù)說(shuō)明以及配置介紹,閱讀原文后至社區(qū)搜索《 J5 算法工具鏈—PTQ Debug 工具使用》。
可視化結(jié)果:
注:藍(lán)色三角表示數(shù)據(jù)絕對(duì)值的最大值;紅色虛線表示最大的校準(zhǔn)閾值。
數(shù)據(jù)分布結(jié)果的分析標(biāo)準(zhǔn)為是否滿足對(duì)量化友好的正態(tài)分布,只要分布中有一個(gè)很明顯的單峰就認(rèn)為滿足正態(tài)分布,不需要嚴(yán)格滿足正態(tài)分布公式,例如可視化結(jié)果中的第一張圖,輸入數(shù)據(jù)分布相對(duì)比較集中,對(duì)于激活節(jié)點(diǎn)而言輸入數(shù)據(jù)分布是友好的;同理第二張圖校準(zhǔn)前后權(quán)重節(jié)點(diǎn)的數(shù)據(jù)分布也是友好的。
第三張圖是普通節(jié)點(diǎn)校準(zhǔn)前后的輸出數(shù)據(jù)分布以及量化誤差分布,也符合正態(tài)分布,當(dāng)節(jié)點(diǎn)輸出不符合正態(tài)分布時(shí),用戶(hù)可以嘗試在模型中增加 BatchNorm 層并重新訓(xùn)練,然后再進(jìn)行 PTQ 量化。
繪制指定校準(zhǔn)節(jié)點(diǎn)輸入數(shù)據(jù)通道間數(shù)據(jù)分布的箱線圖。
# 導(dǎo)入debug模塊
import horizon_nn.debug as dbg
dbg.get_channelwise_data_distribution(
save_dir='./',
model_or_file='./calibrated_model.onnx',
calibrated_data='./calibration_data',
nodes_list=['317_HzCalibration'],
axis=None)
hmct-debugger get-channelwise-data-distribution calibrated_model.onnx calibration_data -n ['317_HzCalibration']
可通過(guò)hmct-debugger get-channelwise-data-distribution -h/--help查看相關(guān)參數(shù)。
詳細(xì)的API和命令行參數(shù)說(shuō)明以及配置介紹,見(jiàn)。
可視化結(jié)果:
注:橫坐標(biāo)表示節(jié)點(diǎn)輸入數(shù)據(jù)的通道數(shù);縱坐標(biāo)表示每個(gè) channel 的數(shù)據(jù)分布范圍,其中紅色實(shí)線表示該 channel 數(shù)據(jù)的中位數(shù),藍(lán)色虛線表示均值。
通過(guò)箱線圖可以直觀地了解當(dāng)前數(shù)據(jù)每個(gè)通道之間的數(shù)據(jù)分布情況。通過(guò)觀察箱線圖縱坐標(biāo)確認(rèn)數(shù)據(jù)分布范圍,當(dāng)某一個(gè)通道有異常值時(shí)(即數(shù)值極大或極小,例如上圖中第 21 通道),認(rèn)為當(dāng)前節(jié)點(diǎn)采用 per-tensor 量化會(huì)有較大的量化風(fēng)險(xiǎn),需要嘗試使用 per-channel 量化去減少量化誤差。箱線圖的閱讀可以參考下圖:
我們還提供了三篇社區(qū)文章,來(lái)展示如何在具體模型上使用 PTQ Debug 工具進(jìn)行分析:
【PTQ 精度 debug 示例】mnasnet_1.0_96 精度問(wèn)題分析
【PTQ 精度 debug 示例】repvgg_b2_deploy 精度問(wèn)題分析
【PTQ 精度 debug 示例】MobileVit_s 精度問(wèn)題分析
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。