使用 DataParallel 进行多 GPU 训练
nn.DataParallel、GPU 内存均衡、带宽瓶颈,以及 DDP 何时更合适。
使用 DataParallel 进行多 GPU 训练 是 CoddyKit 上的免费 Learn AI with Python 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn AI with Python 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn AI with Python 课程共包含 4 节课。
为什么需要多个 GPU
现代模型和批次的规模已经超出单个 GPU 的内存和计算能力。使用多个 GPU可以让您训练更大的模型或处理更大的批次,并缩短实际耗时。PyTorch 提供了多种实现方式,其中最简单的是 DataParallel。
数据并行
数据并行会在每个 GPU 上复制模型,并将每个输入批次拆分到这些 GPU 上。每个 GPU 对分配到的数据分片进行计算,然后合并梯度,使所有副本保持同步。
nn.DataParallel
nn.DataParallel只需一行代码即可包装模型。您传入要使用的 GPU 编号,PyTorch 会自动处理输入分发和输出汇总。
import torch
import torch.nn as nn
model = MyModel().cuda()
model = nn.DataParallel(model, device_ids=[0, 1])自动拆分批次
在前向传播期间,DataParallel 会沿第 0 维将批次拆分到列出的 GPU 上。两个 GPU 上大小为 64 的批次会变成两个大小为 32 的子批次。每个 GPU 会并行地使用同一个模型处理自己的子批次。
# batch of 64 with device_ids=[0, 1]
# GPU 0 processes samples 0..31
# GPU 1 processes samples 32..63梯度平均
在反向传播期间,每个 GPU 的梯度会被汇总到主 device,并进行平均(实际上是先求和再缩放),使模型 update 能够反映整个批次。随后会重新同步各个副本,以准备下一次 step。
常规训练循环
最方便的是:您的训练循环几乎不需要改变。您只需将数据移动到主 GPU,然后像往常一样调用包装后的模型;DataParallel 会在底层完成分发。
for x, y in loader:
x, y = x.cuda(), y.cuda()
optimizer.zero_grad()
out = model(x) # auto-split across GPUs
loss = criterion(out, y)
loss.backward() # gradients averaged
optimizer.step()GPU 0 的负载不均衡
DataParallel 有一个众所周知的缺点:主 GPU(通常是GPU 0)会汇总所有输出并计算损失,因此需要承担额外的内存和计算负载。使用许多 GPU 时,GPU 0 会成为瓶颈,可能比其他 GPU 更早耗尽内存。
单进程,多线程
DataParallel 在单个 Python 进程中运行,并使用线程驱动各个 GPU。Python 全局解释器锁以及分发和汇总的额外开销会限制扩展效率,尤其是在 GPU 数量超过 2 到 4 个时。
为什么首选 DDP
基于这些原因,对于严肃的多 GPU 工作,建议使用 DistributedDataParallel(DDP)。DDP 为每个 GPU 运行一个进程,使用高效的全归约同步梯度,并避免 GPU 0 瓶颈,从而实现接近线性的扩展。
DataParallel 何时仍然适用
如果是在一台配有 2 个 GPU 的机器上进行快速实验,DataParallel 仍然可以接受,因为它只需一行代码的简单性足以抵消效率损失。对于多节点训练或许多 GPU,请改用 DDP。
常见问题:保存
包装后的模型状态字典带有 module. 前缀。要保存干净的检查点,请保存 model.module.state_dict(),这样之后就能将其正确加载到未包装的模型中。
torch.save(model.module.state_dict(), "model.pt")快速检查
请测试您对 DataParallel 的掌握情况。
回顾
您已经学习了使用 DataParallel 进行多 GPU 训练:
nn.DataParallel(model, device_ids=[0, 1])会复制模型并拆分批次- 每个 step 都会在各个 GPU 之间平均梯度
- GPU 0 负载不均衡以及单进程设计会限制扩展能力
- 对于许多 GPU 或多节点训练,优先使用 DDP
常见问题解答
「使用 DataParallel 进行多 GPU 训练」课时是免费的吗?
是的 — 「使用 DataParallel 进行多 GPU 训练」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn AI with Python 课程的其余内容,请升级到 CoddyKit PRO。 Learn AI with Python 课程共包含 4 节课。
「使用 DataParallel 进行多 GPU 训练」这节课中我会学到什么?
nn.DataParallel、GPU 内存均衡、带宽瓶颈,以及 DDP 何时更合适。 你通过在浏览器中直接运行的动手代码来练习 Learn AI with Python,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn AI with Python 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn AI with Python 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「使用 DataParallel 进行多 GPU 训练」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn AI with Python 课中编写并运行代码吗?
能。每节 Learn AI with Python 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 DataParallel 进行多 GPU 训练
- DistributedDataParallel(DDP)
- 使用 AMP 进行混合精度训练
- 使用 Hugging Face Accelerate 高效训练