Pytorch原生AMP支援使用方法 1 6版本

2022-06-05 22:12:08 字數 3297 閱讀 4971

amp:automatic mixed precision,自動混合精度,可以在神經網路推理過程中,針對不同的層,採用不同的資料精度進行計算,從而實現節省視訊記憶體和加快速度的目的。

在pytorch 1.5版本及以前,通過nvidia出品的外掛程式apex,可以實現amp功能。

從pytorch 1.6版本以後,pytorch將amp的功能吸收入官方庫,位於torch.cuda.amp模組下。

本文為針對官方文件主要內容的簡要翻譯和自己的理解。

torch.cuda.amp提供了對混合精度的支援。為實現自動混合精度訓練,需要結合使用如下兩個模組:

乙個典型的amp應用示例如下:

# 定義模型和優化器

model = net().cuda()

optimizer = optim.sgd(model.parameters(), ...)

# 在訓練最開始定義gradscalar的例項

scaler = gradscaler()

for epoch in epochs:

for input, target in data:

optimizer.zero_grad()

# 利用with語句,在autocast例項的上下文範圍內,進行模型的前向推理和loss計算

with autocast():

output = model(input)

loss = loss_fn(output, target)

# 對loss進行縮放,針對縮放後的loss進行反向傳播

# (此部分計算在autocast()作用範圍以外)

scaler.scale(loss).backward()

# 將梯度值縮放回原尺度後,優化器進行一步優化

scaler.step(optimizer)

# 更新scalar的縮放資訊

scaler.update()

待更新

待更新如果模型的loss計算部分輸出多個loss,需要對每乙個loss值執行scaler.scale

如果網路具有多個優化器,對任乙個優化器執行scaler.unscale_,並對每乙個優化器執行scaler.step

scaler.update只在最後執行一次。

應用示例如下:

scaler = torch.cuda.amp.gradscaler()

for epoch in epochs:

for input, target in data:

optimizer0.zero_grad()

optimizer1.zero_grad()

with autocast():

output0 = model0(input)

output1 = model1(input)

loss0 = loss_fn(2 * output0 + 3 * output1, target)

loss1 = loss_fn(3 * output0 - 5 * output1, target)

scaler.scale(loss0).backward(retain_graph=true)

scaler.scale(loss1).backward()

# 選擇其中乙個優化器執行顯式的unscaling

scaler.unscale_(optimizer0)

# 對每乙個優化器執行scaler.step

scaler.step(optimizer0)

scaler.step(optimizer1)

# 完成所有梯度更新後,執行一次scaler.update

scaler.update()

針對多卡訓練的情況,只影響autocast的使用方法,gradscaler的用法與之前一致。

在每乙個不同的cuda裝置上,torch.nn.dataparallel在不同的程序中執行前向推理,而autocast只在當前程序中生效,因此,如下方式的呼叫是不生效的:

model = mymodel()

dp_model = nn.dataparallel(model)

# 在主程序中設定autocast

with autocast():

# dp_model的內部程序並不會對autocast生效

output = dp_model(input)

# loss的計算在主程序中執行,autocast可以生效,但由於前面執行推理時已經失效,因此整體上是不正確的

loss = loss_fn(output)

有效的呼叫方式如下所示:

# 方法1:在模型構建中,定義forwar函式時,採用裝飾器方式

mymodel(nn.module):

...@autocast()

def forward(self, input):

...# 方法2:在模型構建中,定義forwar函式時,採用上下文管理器方式

mymodel(nn.module):

...def forward(self, input):

with autocast():

...# dataparallel的使用方式不變

model = mymodel().cuda()

dp_model = nn.dataparallel(model)

# 在模型執行推理時,由於前面模型定義時的修改,在各cuda裝置上的子程序中autocast生效

# 在執行loss計算是,在主程序中,autocast生效

with autocast():

output = dp_model(input)

loss = loss_fn(output)

torch.nn.parallel.distributeddataparallel在官方文件中推薦每個gpu執行乙個例項的方法,以達到最好的效能表現。

在這種模式下,distributeddataparallel內部並不會再啟動子程序,因此對於autocastgradscaler的使用都沒有影響,與典型示例保持一致。

dataparallel的使用相同,在模型構建時,對forward函式的定義方式進行修改,保證autocast在程序內部生效。

pytorch之ImageFolder使用詳解

pytorch之imagefolder使用詳解 pytorch之imagefolder torchvision已經預先實現了常用的dataset,包括前面使用過的cifar 10,以及imagenet coco mnist lsun等資料集,可通過諸如torchvision.datasets.cif...

pytorch之ImageFolder使用詳解

pytorch之imagefolder torchvision已經預先實現了常用的dataset,包括前面使用過的cifar 10,以及imagenet coco mnist lsun等資料集,可通過諸如torchvision.datasets.cifar10來呼叫。在這裡介紹乙個會經常使用到的da...

使SQLServer資料支援

學習如何用的xml特徵為你的提供新的功能。如果你在it業工作,那麼你很可能聽說過xml 但如果你的工作主要與sqlserver有關,那麼你可能並沒有直接運用過xml。xml已經是web環境中的普遍的資料格式了,而且它也是中主要的底層技術之一。sqlserver以兩種方式來支援xml 通過sqlser...