詳解如何使用Pytorch進行多卡訓練
Python PyTorch深度學習框架
PyTorch是一個基于Python的深度學習框架,它支持使用CPU和GPU進行高效的神經(jīng)網(wǎng)絡(luò)訓練。
在大規(guī)模任務(wù)中,需要使用多個GPU來加速訓練過程。
數(shù)據(jù)并行
“數(shù)據(jù)并行”是一種常見的使用多卡訓練的方法,它將完整的數(shù)據(jù)集拆分成多份,每個GPU負責處理其中一份,在完成前向傳播和反向傳播后,把所有GPU的誤差累積起來進行更新。數(shù)據(jù)并行的代碼結(jié)構(gòu)如下:
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as data
import torch.distributed as dist
import torch.multiprocessing as mp
# 定義網(wǎng)絡(luò)模型
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=5)
self.relu = nn.ReLU()
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(4608, 64)
self.fc2 = nn.Linear(64, 10)
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool(x)
x = x.view(-1, 4608)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 定義訓練函數(shù)
def train(gpu, args):
rank = gpu
dist.init_process_group(backend='nccl', init_method='env://', world_size=args.world_size, rank=rank)
torch.cuda.set_device(gpu)
train_loader = data.DataLoader(...)
model = Net()
model = nn.parallel.DistributedDataParallel(model, device_ids=[gpu])
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
for epoch in range(args.epochs):
epoch_loss = 0.0
for i, (inputs, labels) in enumerate(train_loader):
inputs, labels = inputs.cuda(), labels.cuda()
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
epoch_loss += loss.item()
print('GPU %d Loss: %.3f' % (gpu, epoch_loss))
# 主函數(shù)
if __name__ == '__main__':
mp.set_start_method('spawn')
args = parser.parse_args()
args.world_size = args.num_gpus * args.nodes
mp.spawn(train, args=(args,), nprocs=args.num_gpus, join=True)
首先,我們需要在主進程中使用torch.distributed.launch啟動多個子進程。每個子進程被分配一個GPU,并調(diào)用train函數(shù)進行訓練。
在train函數(shù)中,我們初始化進程組,并將模型以及優(yōu)化器包裝成DistributedDataParallel對象,然后像CPU上一樣訓練模型即可。在數(shù)據(jù)并行的過程中,模型和優(yōu)化器都會被復制到每個GPU上,每個GPU只負責處理一部分的數(shù)據(jù)。所有GPU上的模型都參與誤差累積和梯度更新。
模型并行
“模型并行”是另一種使用多卡訓練的方法,它將同一個網(wǎng)絡(luò)分成多段,不同段分布在不同的GPU上。每個GPU只運行其中的一段網(wǎng)絡(luò),并利用前后傳播相互連接起來進行訓練。代碼結(jié)構(gòu)如下:
import torch.nn as nn
import torch.optim as optim
import torch.multiprocessing as mp
import torch.distributed as dist
# 定義模型段
class SubNet(nn.Module):
def __init__(self, in_features, out_features):
super(SubNet, self).__init__()
self.linear = nn.Linear(in_features, out_features)
def forward(self, x):
return self.linear(x)
# 定義整個模型
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.subnets = nn.ModuleList([
SubNet(1024, 512),
SubNet(512, 256),
SubNet(256, 100)
])
def forward(self, x):
for subnet in self.subnets:
x = subnet(x)
return x
# 定義訓練函數(shù)
def train(subnet_id, args):
dist.init_process_group(backend='nccl', init_method='env://', world_size=args.world_size, rank=subnet_id)
torch.cuda.set_device(subnet_id)
train_loader = data.DataLoader(...)
model = Net().cuda()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
for epoch in range(args.epochs):
epoch_loss = 0.0
for i, (inputs, labels) in enumerate(train_loader):
inputs, labels = inputs.cuda(), labels.cuda()
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward(retain_graph=True) # 梯度保留,用于后續(xù)誤差傳播
optimizer.step()
epoch_loss += loss.item()
if subnet_id == 0:
print('Epoch %d Loss: %.3f' % (epoch, epoch_loss))
# 主函數(shù)
if __name__ == '__main__':
mp.set_start_method('spawn')
args = parser.parse_args()
args.world_size = args.num_gpus * args.subnets
tasks = []
for i in range(args.subnets):
tasks.append(mp.Process(target=train, args=(i, args)))
for task in tasks:
task.start()
for task in tasks:
task.join()
在模型并行中,網(wǎng)絡(luò)被分成多個子網(wǎng)絡(luò),并且每個GPU運行一個子網(wǎng)絡(luò)。在訓練期間,每個子網(wǎng)絡(luò)的輸出會作為下一個子網(wǎng)絡(luò)的輸入。這需要在誤差反向傳播時,將不同GPU上計算出來的梯度加起來,并再次分發(fā)到各個GPU上。
在代碼實現(xiàn)中,我們定義了三個子網(wǎng)(SubNet),每個子網(wǎng)有不同的輸入輸出規(guī)模。在train函數(shù)中,我們初始化進程組和模型,然后像CPU上一樣進行多次迭代訓練即可。在反向傳播時,將梯度保留并設(shè)置retain_graph為True,用于后續(xù)誤差傳播。
以上就是詳解如何使用Pytorch進行多卡訓練的詳細內(nèi)容,更多關(guān)于Pytorch進行多卡訓練的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python實現(xiàn)向PPT中插入表格與圖片的方法詳解
這篇文章將帶大家學習一下如何在PPT中插入表格與圖片以及在表格中插入內(nèi)容,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2022-05-05
一篇文章搞懂Python Unittest測試方法的執(zhí)行順序
unittest是Python標準庫自帶的單元測試框架,是Python版本的JUnit,下面這篇文章主要給大家介紹了如何通過一篇文章搞懂Python Unittest測試方法的執(zhí)行順序,需要的朋友可以參考下2021-09-09
PyQt5實現(xiàn)界面(頁面)跳轉(zhuǎn)的示例代碼
這篇文章主要介紹了PyQt5實現(xiàn)界面跳轉(zhuǎn)的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04

