Pytorch 基於混和精度的模型加速

2021-09-26 22:46:47 字數 3283 閱讀 9928

這篇部落格是在pytorch中基於apex使用混合精度加速的乙個偏工程的描述,原理層面的解釋並不是這篇部落格的目的,不過在參考部分提供了非常有價值的資料,可以進一步研究。

乙個關鍵原則:「僅僅在權重更新的時候使用fp32,耗時的前向和後向運算都使用fp16」。其中的乙個技巧是:在反向計算開始前,將dloss乘上乙個scale,人為變大;權重更新前,除去scale,恢復正常值。目的是為了減小啟用gradient下溢位的風險。

apex是nvidia的乙個pytorch擴充套件,用於支援混合精度訓練和分布式訓練。在之前的部落格中,神經網路的low-memory技術梳理了一些low-memory技術,其中提到半精度,比如fp16。apex中混合精度訓練可以通過簡單的方式開啟自動化實現,組裡同學交流的結果是:一般情況下,自動混合精度訓練的效果不如手動修改。分布式訓練中,有社群同學心心念念的syncbn的支援。關於syncbn,在去年做cv的時候,我們就有一些來自民間的嘗試,不過具體提公升還是要考慮具體任務場景。

那麼問題來了,如何在pytorch中使用fp16混合精度訓練呢?

parser.add_argument('--fp16',

action='store_true',

help="whether to use 16-bit float precision instead of 32-bit")

parser.add_argument('--loss_scale',

type=float, default=0,

help="loss scaling to improve fp16 numeric stability. only used when fp16 set to true.\n"

"0 (default value): dynamic loss scaling.\n"

"positive power of 2: static loss scaling value.\n")

第一:模型引數轉換為fp16

nn.module中的half()方法將模型中的float32轉化為float16,實現的原理是遍歷所有tensor,而float32和float16都是tensor的屬性。也就是說,一行**解決,如下:

model.half()

第二:修改優化器

在pytorch下,當使用fp16時,需要修改optimizer。類似**如下(**參考這裡):

# prepare optimizer

if args.do_train:

param_optimizer = list(model.named_parameters())

no_decay = ['bias', 'layernorm.bias', 'layernorm.weight']

optimizer_grouped_parameters = [,]

if args.fp16:

try:

from apex.optimizers import fp16_optimizer

from apex.optimizers import fusedadam

except importerror:

raise importerror("please install apex from to use distributed and fp16 training.")

optimizer = fusedadam(optimizer_grouped_parameters,

lr=args.learning_rate,

bias_correction=false,

max_grad_norm=1.0)

if args.loss_scale == 0:

optimizer = fp16_optimizer(optimizer, dynamic_loss_scale=true)

else:

optimizer = fp16_optimizer(optimizer, static_loss_scale=args.loss_scale)

warmup_linear = warmuplinearschedule(warmup=args.warmup_proportion,

t_total=num_train_optimization_steps)

else:

optimizer = bertadam(optimizer_grouped_parameters,

lr=args.learning_rate,

warmup=args.warmup_proportion,

t_total=num_train_optimization_steps)

第三:backward時做對應修改

if args.fp16:

optimizer.backward(loss)

else:

loss.backward()

第四:學習率修改

if args.fp16:

# modify learning rate with special warm up bert uses

# if args.fp16 is false, bertadam is used that handles this automatically

lr_this_step = args.learning_rate * warmup_linear.get_lr(global_step, args.warmup_proportion)

for param_group in optimizer.param_groups:

param_group['lr'] = lr_this_step

optimizer.step()

optimizer.zero_grad()

(1)深度學習訓練使用16bit表示/運算正逐漸成為主流。

(2)低精度帶來了效能、功耗優勢,但需要解決量化誤差(溢位、捨入)。

(3)常見的避免量化誤差的方法:為權重保持高精度(fp32)備份;損失放大,避免梯度的下溢位;一些特殊層(如batchnorm)仍使用fp32運算。

pytorch中的transforms模組例項詳解

pytorch中的transforms模組中包含了很多種對影象資料進行變換的函式,這些都是在我們進行影象資料讀入步驟中必不可少的,下面我們講解幾種最常用的函式,詳細的內容還請參考pytorch官方文件 放在文末 data transforms transforms.compose transform...

基於pytorch的SSD復現筆記

復現的過程按照github的步驟進行 但注意有幾個坑 sudo apt install curl兩個命令的使用參考 2.cv2的安裝 詳細參考我的另一篇部落格 cv2的安裝包名字不叫cv2,而是叫opencv python 3.pytorch版本需要為0.4.1,python版本為python3.6...

基於Windows平台的PyTorch版本安裝

安裝平台 windows pytorch安裝 pytorch build 選擇的stable 作業系統 選擇的windows 根據自己的伺服器系統選擇 安裝方式 選擇的pip 第一次安裝使用conda方式,沒有安裝成功 語言 python cuda 要帶gpu加速的話,可以選擇。需要nvidia顯示...