深度學習之模型量化


深度學習之模型量化

 

深度學習之模型量化

各位小伙伴,大家好。深度學習具體工作你有沒有碰到模型占用空間偏大、PC 平台與移植到板子上的運行效率差距偏大,進而無法滿足高幀率、實時性的要求?AI 奶油小生也碰到上述問題,以下是小生針對訓練后深度學習模型量化的處理理論,詳細介紹模型壓縮領域中的量化實操,希望對您的有所幫助。

  • 模型量化理論

1.1 需求背景   

為了滿足各種 AI 應用對檢測精度的要求,深度神經網絡結構的寬度、層數、深度以及各類參數等數量急速上升,導致深度學習模型需要更大的空間需求,更低的推理效率;同時商業對模型應用越來越傾向於從雲端部署到邊緣側,受限於邊緣側設備的計算資源,我們不得不考慮設備存儲、內存、功耗及時延性等問題,特別是在移動終端和嵌入式設備等應用場景更加需要優化。作為通用的深度學習優化的手段之一,模型量化將深度學習模型量化為更小的定點模型和更快的推理速度,而且幾乎不會有精度損失,其適用於絕大數模型和使用場景。

1.2 模型量化可行性

模型量化以損失推理精度為代價,將網絡中連續取值或離散取值的浮點型參數( 權重或張量)線性映射為定點近似(int8 / uint8)的離散值,取代原有的 float32 格式數據,同時保持輸入輸出為浮點型,從而達到減少模型尺寸大小、減少模型內存消耗及加快模型推理速度等目標。定點量化近似表示如圖 1.1 所示。

圖 1.1 定點量化近似表示

1.3 模型量化原理

模型量化為定點與浮點等數據之間建立一種數據映射關系,詳細如下:

R 表示真實的浮點值,Q 表示量化后的定點值,Z 表示0 浮點值對應的量化定點值,S 則為定點量化后可表示的最小刻度。由浮點到定點的量化公式如下:

由定點到浮點反量化公式如下:

同時,S 和Z 的求值公式如下:

    量化后的 Q 還是反推求得的浮點值 R,若它們超出各自可表示的最大范圍,則需進行截斷處理。

    特別說明:一是浮點值 0 在神經網絡里有着舉足輕重的意義,比如 padding 就是用的 0,因而必須有精確的整型值來對應浮點值 0。二是以往一般使用 uint8 進行定點量化,而目前有提供 float16 和 int8 等定點量化方法,而 int8 定點量化針對不同的數據有不同的范圍定義:

1.4 模型量化內部流程

深度模型的前向推導通過量化實現 8-bit 版本運算符(包括卷積、矩陣乘、激活函數、下采樣和拼接)運行;同時,量化對象包含實數與矩陣乘法等類型。則以激活函數 Relu 為例,傳統、實數量化、矩陣乘法量化等三種前向推導流程如圖 1.2 所示。

圖 1.2 三種量化前向推導流程

  • Tensorflow 量化實操

Tensorflow 模型量化分為訓練量化、訓練時量化。上述兩者詳細介紹如下:

2.1 訓練后量化( post training quantization )

此處處理對象是訓練好的模型,借用 tensorflow 量化工具通過壓縮權重或量化權重和激活輸出等方式縮減模型大小,進而加速預測速度。僅對權重量化即為實數量化,只需將權重精度從浮點型映射為 8 bit 整型,此類型方便傳輸和存儲(本文主要實現模型權重的量化進行實操);量化權重和激活輸出即為矩陣乘法量化,除了對大量參數進行量化,也需要標定數據與激活輸出的動態范圍共同輔助后者的量化。權重量化實操詳細如下:

2.1.1 環境配置

    量化訓練后的模型需借助 bazel 對 Tensorflow 編譯和移植。首先,bazel 與 Tensorflow 需要進行版本匹配,部分內容如圖 2.1 所示。其次,根據模型訓練時使用的 tensorflow 版本(本文使用 tensorflow 1.13.1),下載與之對應的 bazel 安裝軟件(對應版本為 0.19.2),下載鏈接為 https://github.com/bazelbuild/bazel/releases,本次下載 bazel-0.19.2-installer-linux-x86_64.sh,如圖 2.2 所示。再次,擴展內存,即構建內存交換空間 swap,解決后期物理內存不足問題。本次采用文件構建 swap,如圖 2.3 所示。最后,配置與安裝 bazel 及其環境,詳細內容如下:

************************************ 部分參照 google **********************************************

Step 1: Install the JDK      #Install JDK 8:

sudo apt-get install openjdk-8-jdk      #On Ubuntu 14.04 LTS you must use a PPA:

sudo add-apt-repository ppa:webupd8team/java

sudo apt-get update && sudo apt-get install oracle-java8-installer

Step 2: Add Bazel distribution URI as a package source      #Note: This is a one-time setup step.

echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list

curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -    #If you want to install the #testing version of Bazel, replace stable with testing.

Step 3: sudo apt update && sudo apt install bazel-0.19.2      # Install and update Bazel

或者 sudo bash bazel-0.19.2-installer-linux-x86_64.sh

Step 4: bazel version      #查看 bazel 版本

**************************************** OVER ****************************************************

圖 2.1 bazel 與 tensorflow 版本列表

圖 2.2 bazel 下載示例

圖 2.3 構建 swap 流程

2.1.2 構建與量化

此處分別執行 tensorflow 量化模塊的構建、指定模型的量化操作等。首先,在 tensorflow 文件目錄下,終端執行命令:bazel build tensorflow/tools/graph_transforms:transform_graph ,執行示例與效果如圖 2.4 所示。其次,同一個終端執行模型量化命令如下:

bazel-bin/tensorflow/tools/graph_transforms/transform_graph --in_graph=./tmp/frozen_inference_graph20200315.pb    --outputs='output_weights_name'   --out_graph=./tmp/quantized_frozen_inference_graphV6.pb   --transforms='quantize_weights'

其中,in_graph 為模型及其輸入路徑,out_graph 為量化模型及其輸出路徑,transforms 為 模型權重由 32 bit 轉化為 8 bit,執行效果如圖 2.5 所示:生成的量化模型大小約為原始模型的 32%。

 

圖 2.4 編譯 tensorflow 與效果示例

圖 2.5 模型量化與效果示例

2.2 訓練時量化( Quantization Aware Training )

訓練時量化方法相比於訓練后量化,能夠得到更高的精度。訓練時量化方案可以利用 tensorflow 的量化庫,在訓練和預測時在模型圖中自動插入模擬量化操作來實現。鑒於篇幅有限,本文暫且不做實操,后期將針對此量化類型進行詳細講解,敬請期待。如需了解此類型量化步驟,請查閱參考資料(3)。

2.3 tensorflow 量化感知訓練

作為一種偽量化手段,tensorflow 量化感知訓練是在可識別的某些操作內嵌入偽量化節點( fake quantization nodes ),用以統計訓練時流經該節點數據的最大最小值,同時參與前向傳播提升精確度(不參與反向傳播中梯度更新部分);但其在 TOCO 工具轉換為 tflite 格式的量化模型后,其工作原理還是與訓練后量化方式一致的,relu 激活函數原理如圖 2.6 所示。鑒於篇幅有限,本文暫且不做實操,后期將針對此量化類型進行詳細講解,敬請期待。如需了解此類型量化步驟,請查閱參考資料(1)。

圖 2.6 relu 偽量化原理圖

  • 總結

   本文分別對模型量化的理論與實際操作進行詳細介紹,並補充訓練中量化、tensorflow 量化感知訓練等量化理論。除上述三種量化方法外,模型量化還包括全整型量化(群眾和激活值量化)、float32 轉 float16 的半精度量化等等,而具體的實現途徑不僅僅不含 bazel 編譯和移植 tensorflow ,還包含了模型中代碼修改、實時量化等,鑒於篇幅限制,后續將依需補充相關內容,敬請期待。歡迎在大大通上關注我(花名:AI 奶油小生),給我留言。

 

  • lonlon ago—— TensorFlow 模型 Quantization 離散化或量化

鏈接:https://zhuanlan.zhihu.com/p/33535898

  • wxquare—— tensorflow模型權重量化(weight quantization)實踐

鏈接:https://zhuanlan.zhihu.com/p/86440423?from_voters_page=true

  • ChrisZZ—— 安裝和配置bazel

鏈接:https://www.cnblogs.com/zjutzz/p/10182099.html

  • 雨天的小尾巴—— 虛擬機無法分配內存 virtual memory exhausted: Cannot allocate memory

鏈接:https://www.cnblogs.com/ettie999/p/8143712.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM