01 概論:PTQ 基礎
目前在 GPU 上訓練的模型大部分都是浮點模型,即引數使用的是 float 型別儲存。而地平線 BPU 架構的計算平臺使用的是 int8 的計算精度(業內計算平臺的通用精度),能執行定點量化模型。
地平線征程 6 演算法工具鏈(以下簡稱工具鏈)作為專業量化工具,是一套完整的邊緣計算平臺演算法落地解決方案,可以幫助您把浮點模型量化為定點模型,並在地平線計算平臺上快速部署自研演算法模型。當需要對量化後的引數進行調整時,又可以將量化方法分為訓練後量化(PTQ)和量化感知訓練(QAT)。
其中訓練後量化 PTQ 是使用一批校準資料對訓練好的模型進行校準,將訓練過的FP32模型直接轉換為定點計算的模型,過程中無需對原始模型進行任何訓練。只對幾個超引數調整就可完成量化過程,過程簡單快速,無需訓練,此方法已被廣泛應用於大量的端側和雲側部署場景,我們優先推薦您嘗試 PTQ 方法來檢視是否滿足您的部署精度和效能要求 。如下即為 PTQ 流程所需資料和基本步驟:
本文章聚焦訓練後量化(PTQ),展示 **PTQ **基本流程以及和上一代計算平臺工具鏈之間的使用差異。
02 PTQ量化&編譯
征程 6 PTQ 的使用方式、yaml 配置引數等均和征程 5 保持一致,詳細說明可見使用者手冊《6.2 PTQ 轉換工具》,下文將對其中部分功能點的使用方式做具體說明。
2.1 校準資料
當前版本已支援在 yaml 檔案中配置 色彩轉換(如 nv12—>bgr
)和 歸一化(mean & scale
),同時在資料儲存上,也支援複用征程 5 上使用的 bin
格式(np.tofile
)。
與征程 5 不同的是,征程 6 的 PTQ 需要手動對校準資料做歸一化。
另外,征程 6 也支援使用 np.save
將資料儲存為 npy
格式。
2.2 前處理節點
征程 6 PTQ 前處理節點的配置方式和征程 5 保持一致,可以完全複用。需要注意的是:
-
征程 5 的前處理節點在
*_original_float.onnx
階段就已經插入; -
征程 6 只在
*_quantized.bc
和*.hbm
模型上插入,各階段onnx 模型
推理時的輸入資料則完全一致。另外,征程 6 也提供HBRuntime 推理庫
,使用同一套介面推理各階段onnx 模型
以及HBIR(*.bc)
模型,詳細說明可參考使用者手冊的HBRuntime推理庫章節。
2.2.1 input_type_rt
當前版本已支援配置 input_type_rt: nv12
:
input_parameters:
以單輸入 nv12
模型為例,在 X86
環境使用 hb_model_info
工具檢視 *_quantized.bc
的模型資訊,其輸入節點已經被拆分成 y
和 uv
兩個分量;進一步在 qemu 環境使用 hrt_model_exec model_info
工具檢視 *.hbm
的模型資訊,其 input_source
為 pyramid
型別。
*_quantized.bc | *.hbm |
hb_model_info *_quantized.bc -v
可以生成其視覺化 onnx
,如下圖所示,已插入前處理節點
2.2.2 資料歸一化
目前 PTQ 已支援配置歸一化引數,其使用方式和征程 5 保持一致,值得注意的是:校準資料準備時手動在程式碼中加入了歸一化操作,如果此處配置了歸一化引數,為推理準備資料如果參考校準資料準備流程是要移除校準資料準備中的重複操作:
input_parameters:
2.3 Resizer輸入
目前 PTQ 已支援配置 input_source 來指定是否為 resizer 輸入,參考如下:
input_parameters:
環境列印模型資訊,確認已成功編譯為 resizer 模型:
2.4 Batch輸入拆分
當前 Alpha 版本在部署端,暫不支援 Batch>1
的 Pyramid/Resizer模型
以連續地址輸入資料進行推理,因此需要將 batch
輸入顯式地拆分成 batch
份並提供獨立地址。當前 PTQ 鏈路拆分模型 batch
輸入的方式包含如下幾種:
拆分方式一:
-
適用場景:適用於任何模型
-
正常轉換模型,並基於生成的
ptq_model.onnx
,呼叫 hbdk python api 進行batch
拆分後重新編譯模型,參考程式碼如下:
import onnx
拆分方式二:
- 適用場景:當前版本僅適用於 單輸入 模型,暫不支援多輸入模型
直接使用separate_batch
拆分batch
(要求原始模型為單輸入且batch=1
,並配合使用input_batch
配置batch
數):
input_parameters:
拆分方式三:
- 適用場景:在 DL 框架內拆分
batch
輸入後重新匯出ONNX 模型
2.5 刪除指定節點
當前版本已支援刪除指定名稱/型別的節點,其支援刪除的運算元型別和 yaml 配置方式和征程 5 保持一致。
需要注意:與征程 5 不同,征程 6 沒有提供 ******hb_model_modifier**
工具用於修改模型節點。
model_parameters:
03 效能評估
效能測試可以分為靜態測試和動態測試兩種模式或階段。
3.1 靜態評估
靜態評估是編譯器根據模型的結構和計算平臺架構透過靜態的分析預估出的模型BPU部分的效能情況。需要注意因為評估需要計算平臺深層的架構資訊做支撐,目前靜態評估的結果僅BPU部分,不含CPU/DSP等效能情況。如果想獲取全面的效能資料還需要透過動態評估。
靜態評估是透過地平線提供的 hb_compile
工具進行的,該工具整合了模型編譯與效能分析的功能。在模型轉換編譯完成後,會在yaml檔案配置的 working_dir 路徑下生成編譯器預估的模型BPU部分的模型靜態評估檔案:model.html(可讀性更好)
和model.json
。使用者可透過他們瞭解模型的靜態評估結果。
另外,如果使用者需要,也可以透過python元件的hbdk4.compiler
主動進行效能評估,參考程式碼如下:
from hbdk4.compiler import hbm_perf
3.2 動態測試
動態評估是透過測試工具hrt_model_exec
實際在板端執行被測試模型最終獲取效能結果的過程。因為測試過程就是模型推理過程的真實線上,因此是對模型推理過程所需的系統依賴的一個全面評估,該過程有效彌補了靜態評估僅針對BPU部分測評的不足。
hrt_model_exec
工具的具體使用方法可以參考使用者使用手冊 和 部署部分的文章,這裡不單獨贅述。
04 精度評測
精度評測是透過一批測試資料集(包含真值)、推理指令碼以及結果後處理程式獲取最佳化前後模型的精度資訊,進而瞭解模型從浮點模型量化為定點模型過程中帶來的精度損失情況。需要使用者瞭解的是後量化方式是基於幾十或上百張校準資料實現的模型從浮點到定點轉換過程,無論是資料的規模還是模型引數的表達寬度都與原始模型訓練過程有很大的差距,精度損失在一定程度上是不可避免地。地平線轉換工具經過大量實際生產經驗驗證和最佳化,在大部分情況下可以將精度損失保持在1%以內,這在業界已經是很牛的存在。
透過模型編譯過程我們瞭解*_quantized_model.bc
是過程的產物之一,雖然最後的hbm模型
才是將部署到計算平臺的模型,考慮到方便在Ubuntu
開發機上完成精度評測,我們一般透過bc模型檔案來進行精度評測過程。模型推理參考程式碼如下:
下方示例程式碼不僅適用於quantized模型
,對original
和optimized
等onnx模型
同樣適用(替換模型檔案即可),根據模型的輸入型別和layout
要求準備資料即可。
import numpy as np
當然,這裡主要描述了模型精度分析基本流程和推理程式碼,如果評估發現結果不符合預期,可以參考使用者手冊中的 PTQ模型精度調優 章節的內容嘗試調優,其中PTQ精度debug工具征程6 與征程 5 使用方式一致,精度分析推薦流程也一致,具體請參考社群文章 精度驗證及調優建議流程。主要區別就是征程 6 平臺的效能評估過程是透過(*_quantized_model.bc
)hbir格式的定點模型進行的。最後,實在無法解決可尋求地平線的技術支援。
宣告: 該文章內容為學習過程對學習資料的整理和歸納