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
內部並不會再啟動子程序,因此對於autocast
和gradscaler
的使用都沒有影響,與典型示例保持一致。
與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...