將高精度運算轉化到低精度上運算,例如float32轉化為int8資料上運算。
那就要說說量化的好處了,一般量化有以下好處:
但是其也有一些缺點:
雖然量化方法很多,但並無本質區別。記住一點就可以了:將高精度資料對映到低精度表達,在低精度上運算,然後再反量化回去,因為最終的輸出我們還是要高精度的資料的。
當然只支援cpu。目前支援qnnpack 和 fbgemm 兩個後端,都是來自自家的facebook
權重轉為int8資料型別儲存;
模型融合的conv+bn+relu;
儲存每層的量化引數: 量化縮放因子和zero-point;
對模型進行量化;
對於乙個已經訓練好的模型,post-training 量化的基本步驟如下:
1 ,準備模型:
插入量化和反量化的模組:在需要 quantize 和 dequantize 操作的 module 中插入 quantstub 和dequantstub。
def __init__(self):
self.quant = quantstub()
self.dequant = dequantstub()
def forward(self, x):
x = self.quant(x)
# ------ # # 網路forward # ------ #
x = self.dequant(x)
return x
轉換:非 module 物件表示的運算元不能轉換成 quantized module。比如 "+" 算術運算子無法直接轉成 quantize module。 "+=" 是乙個無狀態的運算子,需要替換成 nn.quantized.floatfunctional()。這點非常需要注意。
self.skip_add = nn.quantized.floatfunctional()
z = self.skip_add.add(x, y) # 原來的是: z = x + y
2,模組融合
為了提高精度和效能,一般將 conv + relu, conv + batchnorm + relu, linear + relu 等類似的操作 fuse 成乙個操作。
resnet18_fused = torch.quantization.fuse_modules( resnet18,
[['conv1', 'bn1', 'relu'],
['layer1.0.conv1', 'layer1.0.bn1'], # , 'layer1.0.relu'],
['layer1.0.conv2', 'layer1.0.bn2'],
['layer1.1.conv1', 'layer1.1.bn1'], # , 'layer1.1.relu'],
['layer1.1.conv2', 'layer1.1.bn2']])
3,量化演算法
為 activations/weights 指定量化演算法 比如 symmtric/asymmtric/minmax 等等。pytorch 採用 qconfig 來封裝量化演算法,一般通過將 qconfig 作為 module 的屬性來指定量化演算法。常用的 qconfig 有default_per_channel_qconfig, default_qconfig等。
q_backend = 'qnnpack' # "qnnpack"
qconfig = torch.quantization.get_default_qconfig(q_backend)
torch.backends.quantized.engine = q_backend
resnet18_fused.qconfig = qconfig
torch.quantization.prepare(resnet18_fused, inplace=true)
4,傳播 qconfig 和插入 observer
通過 torch.quantization.prepare() 向子 module 傳播 qconfig,並為子 module 插入 observer。 observer 可以在獲取 fp32 activations/weights 的動態範圍。
5, calibration 校準標定
利用torch.quantization.prepare() 插入將在校準期間觀察啟用張量的模組,然後將校準資料集灌入模型,利用校準策略得到每層activation的scale和zero_point並儲存;執行 calibration 推理程式蒐集 fp32 activations 的動態範圍。
with torch.no_grad():
for image, target in data_loader:
output = model(image)
6,module 轉化
通過 torch.quantization.convert 函式可以將 fp32 module 轉化成 int8 module. 這個過程會量化 weights, 計算並儲存 activation 的 scale 和 zero_point。
resnet18_fused = resnet18.cpu()
torch.quantization.convert(resnet18_fused, inplace=true)
列印儲存的權重, 可以看出, 網路的每一層都額外儲存了scale 和 zero_point:
1,直接儲存jit, 有些模型load進來,無法使用,待查詢原因。
2,每次初始化,都量化一下 convert之後再, load 權重,這裡要注意一定要顯式呼叫.eval()。
格式為 torch.quint8 , 內容為量化後的值(雖然是int形, 但以float形式儲存)
features.0.0.weight
features.0.0.scale
features.0.0.zero_point
features.0.0.bias
features.1.conv.0.0.weight
features.1.conv.0.0.scale features.1.conv.0.0.zero_point ...
pytorch優化之量化
思考 pytorch的eager模式,是怎樣支援開發模式支援序列執行斷點除錯,生產模式支援生成可併發執行 的,可以拉原始碼除錯分析。這裡會涉及到圖程式設計模式 編譯原理,執行優化等技術。什麼是量化?量化是指用於執行計算並以低於浮點精度的位寬儲存張量的技術。量化模型對張量使用整數而不是浮點值執行部分或...
量化 量化研究框架
1.庫存指標體系構建及因子定義 首先,我們對上市的各品種現有庫存指標進行歸類整理,發現庫存指標類別主要可分為社會庫存 交易所庫存及 庫存三大類。其中社會庫存涵蓋的庫存統計面最大,反映真實庫存水平的能力也最強,交易所庫存僅統計存放在交易所的那部分顯性庫存,合理性次之,而 庫存作為交易所庫存中的一部分 ...
模型量化 對稱量化和非對稱量化
本文的模型量化是優化深度學習模型推理過程的記憶體容量和記憶體頻寬問題的概念,通過將模型引數的浮點數型別轉換稱整型儲存的一種模型壓縮技術。以可以接受的精度損失換取更少的儲存開銷和頻寬需求,更快的計算速度,更低的能耗與占用面積。比如int8量化,就是讓原來32bit儲存的數字對映到8bit儲存。int8...