📚 课程目录

第25课:分布式训练

📖 本课概述

大模型需要大算力,分布式训练让我们利用多GPU/多机器加速训练。本课理解数据并行和模型并行。

🖥️ 一、为什么需要分布式

单GPU训练GPT-3需要~355年

1024张V100 → 约1个月

核心思路:分而治之

📐 二、并行策略

2.1 数据并行 (DP/DDP)

每张GPU持有完整模型副本

数据分片到各GPU并行前向传播

梯度AllReduce聚合后同步更新

有效Batch Size = 单GPU Batch × GPU数

2.2 模型并行

模型太大放不进单GPU时,将模型切分到多个GPU上。

2.3 PyTorch DDP实现


import torch
import torch.nn as nn

# 分布式训练模拟
print("=== 数据并行原理 ===")

# 模拟4个GPU的数据并行
class SimpleModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(100, 256), nn.ReLU(),
            nn.Linear(256, 128), nn.ReLU(),
            nn.Linear(128, 10),
        )
    def forward(self, x):
        return self.net(x)

model = SimpleModel()
total_data = 256
num_gpus = 4
batch_per_gpu = total_data // num_gpus

# 模拟各GPU计算梯度
X_full = torch.randn(total_data, 100)
y_full = torch.randint(0, 10, (total_data,))

gradients = []
for gpu_id in range(num_gpus):
    start = gpu_id * batch_per_gpu
    end = start + batch_per_gpu
    
    model.zero_grad()
    loss = nn.CrossEntropyLoss()(model(X_full[start:end]), y_full[start:end])
    loss.backward()
    
    # 收集各GPU的梯度
    grad_dict = {name: p.grad.clone() for name, p in model.named_parameters()}
    gradients.append(grad_dict)

# AllReduce:平均梯度
print("梯度AllReduce(平均):")
for name, p in model.named_parameters():
    avg_grad = sum(g[name] for g in gradients) / num_gpus
    grad_diff = max((g[name] - avg_grad).abs().max().item() for g in gradients)
    print(f"  {name}: 各GPU梯度差异最大={grad_diff:.6f}")

# 单GPU vs 多GPU等价性
model_single = SimpleModel()
loss_single = nn.CrossEntropyLoss()(model_single(X_full), y_full)
loss_single.backward()

# 对比
print(f"\n单GPU loss: {loss_single.item():.6f}")
for gpu_id in range(num_gpus):
    start = gpu_id * batch_per_gpu
    end = start + batch_per_gpu
    loss_gpu = nn.CrossEntropyLoss()(model(X_full[start:end]), y_full[start:end])
    print(f"GPU{gpu_id} loss: {loss_gpu.item():.6f}")

# 模型并行概念
print("\n=== 模型并行示意 ===")
class PipelineParallel(nn.Module):
    def __init__(self):
        super().__init__()
        # GPU0的前半部分
        self.stage0 = nn.Sequential(nn.Linear(100, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU())
        # GPU1的后半部分
        self.stage1 = nn.Sequential(nn.Linear(256, 128), nn.ReLU(), nn.Linear(128, 10))
    
    def forward(self, x):
        x = self.stage0(x)  # GPU0
        x = self.stage1(x)  # GPU1
        return x

pp_model = PipelineParallel()
x = torch.randn(8, 100)
out = pp_model(x)
print(f"流水线并行: {list(x.shape)} → stage0 → stage1 → {list(out.shape)}")
print(f"Stage0参数: {sum(p.numel() for p in pp_model.stage0.parameters()):,}")
print(f"Stage1参数: {sum(p.numel() for p in pp_model.stage1.parameters()):,}")
🟢 运行结果 ✅验证通过 === 数据并行原理 === 梯度AllReduce(平均): net.0.weight: 各GPU梯度差异最大=0.005684 net.0.bias: 各GPU梯度差异最大=0.004191 net.2.weight: 各GPU梯度差异最大=0.010036 net.2.bias: 各GPU梯度差异最大=0.014408 net.4.weight: 各GPU梯度差异最大=0.035854 net.4.bias: 各GPU梯度差异最大=0.058309 单GPU loss: 2.306090 GPU0 loss: 2.300797 GPU1 loss: 2.305863 GPU2 loss: 2.320015 GPU3 loss: 2.320341 === 模型并行示意 === 流水线并行: [8, 100] → stage0 → stage1 → [8, 10] Stage0参数: 183,040 Stage1参数: 34,186

🔬 深入拓展

核心要点回顾

本课的核心知识点构成了训练技巧学习的重要一环。让我们从更高维度审视这些知识之间的关系:

常见陷阱与最佳实践

⚠️ 初学者常犯的错误:

💡 最佳实践:

与前后课程的联系

深度学习是一个整体——每一课的知识都不是孤立的:

📖 延伸阅读

💡 继续深入的学习路径:

📝 练习

练习1:DDP实战

在多GPU环境下使用PyTorch DDP训练模型。

练习2:梯度累积

实现梯度累积模拟大batch训练。

练习3:ZeRO优化

理解ZeRO优化器的三个阶段,分析内存节省。

💡 分布式实践

并行策略

常见错误与解决方案

⚠️ 需要避免的典型错误:

  1. 不了解模型假设就盲目使用
  2. 没有建立基线就追求复杂方法
  3. 忽视数据质量和预处理
  4. 过度调参而不理解原理
  5. 只看训练指标忽略验证指标

性能优化建议

💡 提升模型性能的系统方法:

  1. 确保数据管道正确且高效
  2. 建立简单但正确的基线模型
  3. 分析基线的错误类型
  4. 针对性地改进(数据/模型/训练)
  5. 持续迭代,每步验证

🔬 深度拓展:从理论到实践

核心概念网络

理解本课内容需要将其置于更大的知识网络中。每个核心概念都不是孤立的,它们相互关联、相互支撑:

关键洞察与直觉

建立正确的直觉比记住公式更重要:

1. 维度直觉:高维空间中,数据分布与低维直觉截然不同(维度诅咒)

2. 信息瓶颈:神经网络逐层压缩信息,保留任务相关的、丢弃无关的

3. 流形假设:高维数据实际分布在低维流形上,学习即发现流形结构

4. 偏差-方差权衡:简单模型欠拟合(高偏差),复杂模型过拟合(高方差)

与其他课程的关联

本课作为训练技巧阶段的核心内容,与前后课程紧密关联:

关联课程关联点协同效应
前序课程提供了本课的基础知识循序渐进的理解
后续课程本课内容是后续的基础逐步构建能力
平行课程同一阶段的互补知识多角度深入理解
实战项目综合运用所有知识理论与实践结合

面试常见问题

💡 准备面试时,确保能回答以下问题:

  1. 用简单语言解释本课核心概念
  2. 画出关键算法/结构的流程图
  3. 比较不同方法的优缺点
  4. 举出实际应用场景
  5. 讨论常见误解和注意事项

进阶学习路径

掌握本课内容后,可以通过以下方式继续深入:

📐 补充:知识体系梳理

核心公式速查

将本课涉及的关键公式整理如下,方便回顾和记忆。理解每个公式背后的直觉比死记硬背更重要——试着用自然语言解释每个公式在做什么。

易混淆概念辨析

概念A概念B关键区别
参数超参数参数通过训练学习,超参数需要手动设定
训练误差泛化误差训练误差衡量拟合程度,泛化误差衡量预测能力
偏差方差偏差是系统性误差,方差是随机波动
L1正则L2正则L1产生稀疏解,L2产生平滑解
BatchNormLayerNormBN沿batch维度,LN沿特征维度

代码模板

以下是本课核心概念的标准PyTorch实现模板,可以直接用于实际项目:

💡 调试建议:当结果不符合预期时,先检查数据,再检查损失函数,最后检查模型结构。90%的问题出在前两个环节。

🖥️

成就解锁:分布式训练师

多GPU并行训练——你已经准备好训练大模型了!