pytorch多卡训练模型

DP方法

基本原理

也即是:数据拆分,模型不拆分的思路。

输入数据自动分割成若干小批量,并将模型复制到指定的多个 GPU 上。所有 GPU 计算得到的梯度会在主设备(device_ids 列表中的第一个 GPU)进行汇总后更新模型参数。这时的batch size应该是单块显卡上的batch size乘以显卡数量。

适用场景

适用于模型较小的场景。 但会造成主设备负载过高。

使用方法

#------------------------- 初始化device变量------------------------- 
device = torch.device('cuda:1' if torch.cuda.is_available() else "cpu")

#-------------- 修改batch size为所有显卡训练的batch size总和 --------------
train_dataloader = DataLoader(train_dataset, 8, True)

# ------------------------- 模型初始化、数据并行 -------------------------
model = model(num_class=3)

#调用DataParallel类,传参数。第二个参数为一个list,为参与并行计算的显卡的id,从0开始
#要注意list的第一个数字要和初始化device的显卡号对应一致,否则会报错。
model = model.to(device)  # 先移到主GPU
model = torch.nn.DataParallel(module=model, device_ids=[1, 0, 2, 3])  # 然后包装

主要是上面三个部分要做改动。整体比较简单。

错误记录

1. 调用DataParallel类,传参数。

unet = torch.nn.DataParallel(module=unet, device_ids=[1, 0, 2, 3])。

第二个参数为一个list,为参与并行计算的显卡的id,id从0开始。要注意list的第一个数字要和

device = torch.device('cuda:1' if torch.cuda.is_available() else "cpu")

的显卡号对应一致,否则会报错。

2. train_dataloader = DataLoader(train_dataset, batch size = 8, True)

这里的batch size 应该是所有参加训练的显卡的batch size的总和。因为DataParallel 会将输入 batch 按照设备数量进行切分。如果太小会导致并不是所有的指定的显卡都会参与训练。

DDP方法

目前实验室配置以满足需求,暂不考虑DDP方法。DP方法已经能够完成日常学习。后期若要训练大模型会再学习该方法。

### PyTorch GPU分布式训练:数据并行与模型并行 #### 数据并行 在PyTorch中,数据并行是一种常见的GPU训练方法。它通过将输入的数据划分为个子集,并将其分布到不同的GPU上进行处理来加速训练过程。具体来说,`torch.nn.DataParallel` 是一种简单的方法用于实现数据并行[^4]。 然而,在现代实践中,推荐使用 `DistributedDataParallel (DDP)` 而不是 `DataParallel`,因为 DDP 提供更高的性能和更好的扩展性[^2]。以下是基于 DDP 的数据并行实现的关键步骤: 1. **初始化进程组** 使用 `torch.distributed.init_process_group` 初始化分布式环境。 2. **封装模型** 将模型用 `torch.nn.parallel.DistributedDataParallel` 进行封装。 3. **分发数据** 利用 `torch.utils.data.distributed.DistributedSampler` 对数据进行划分,确保每个 GPU 训练的是不同的数据子集[^3]。 下面是一个简单的代码示例展示如何设置数据并行: ```python import torch import torch.distributed as dist from torch.nn.parallel import DistributedDataParallel as DDP from torch.utils.data import DataLoader, DistributedSampler from torchvision.datasets import CIFAR10 from torchvision.transforms import ToTensor def setup_distributed(rank, world_size): dist.init_process_group( backend='nccl', # 或者 'gloo' 如果没有 NCCL 支持 init_method='env://', world_size=world_size, rank=rank ) train_dataset = CIFAR10(root='./data', train=True, download=True, transform=ToTensor()) sampler = DistributedSampler(train_dataset) dataloader = DataLoader(dataset=train_dataset, batch_size=64, sampler=sampler) model = YourModel().to(rank) ddp_model = DDP(model, device_ids=[rank]) criterion = torch.nn.CrossEntropyLoss() optimizer = torch.optim.SGD(ddp_model.parameters(), lr=0.01) for epoch in range(num_epochs): for data, labels in dataloader: outputs = ddp_model(data) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() setup_distributed(rank=torch.cuda.current_device(), world_size=torch.cuda.device_count()) ``` #### 模型并行 模型并行是指将模型的不同部分分布在不同的设备上运行。这种方法适用于当单个模型过大以至于无法放入单一 GPU 的内存时的情况。相比于数据并行,模型并行更复杂,因为它需要手动指定哪些层应该放置在哪台设备上[^1]。 以下是如何实现基本的模型并行的一个例子: ```python class ModelPartition(torch.nn.Module): def __init__(self): super(ModelPartition, self).__init__() self.part_one = torch.nn.Linear(10, 20).cuda(0) self.relu = torch.nn.ReLU() self.part_two = torch.nn.Linear(20, 5).cuda(1) def forward(self, x): x = x.to('cuda:0') out = self.relu(self.part_one(x)) out = out.to('cuda:1') # 移动张量至第二个GPU return self.part_two(out) model = ModelPartition() input_data = torch.randn(10, 10) output = model(input_data) ``` 上述代码展示了如何将线性变换分成两步分别放在两个 GPU 上执行。 --- #### 性能对比 - **数据并行**适合于模型较小而数据较大的场景,能够有效利用个 GPU 并行计算能力。 - **模型并行**则更适合超大规模模型(如某些 NLP 模型),这些模型可能超出单个 GPU 的显存容量限制。 两者各有优劣,实际应用需根据硬件资源以及任务需求选择合适的策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值