分布式训练深度解析:Data / Tensor / Pipeline / Sequence Parallelism

6694 字
33 分钟
分布式训练深度解析:Data / Tensor / Pipeline / Sequence Parallelism

1. 引言:为什么需要分布式训练#

1.1 模型规模的增长#

┌─────────────────────────────────────────────────────────────┐
│ LLM 参数规模增长趋势 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 2018: ELMo ~ 94M 参数 │
│ 2018: BERT-Large ~ 340M 参数 │
│ 2019: GPT-2 ~ 1.5B 参数 │
│ 2020: GPT-3 ~ 175B 参数 │
│ 2021: PaLM ~ 540B 参数 │
│ 2023: GPT-4 ~ 1.8T 参数 (估计) │
│ 2024: Gemini Ultra ~ 1.5T 参数 │
│ │
│ 内存需求(FP16): │
│ ───────────────────────────────────────────────────────── │
│ 1B 参数 → 2 GB │
│ 7B 参数 → 14 GB │
│ 70B 参数 → 140 GB │
│ 175B 参数 → 350 GB │
│ 1T 参数 → 2 TB │
│ │
│ 单卡 A100 80GB:仅能放下 ~35B 参数的模型 │
│ │
└─────────────────────────────────────────────────────────────┘

1.2 计算需求#

class ComputeRequirements:
"""
计算需求分析
"""
def flops_estimation(self):
"""
训练 LLM 的 FLOPs 估算
对于 decoder-only transformer:
FLOPs ≈ 2 × N × D × G
其中:
- N: 模型参数量
- D: 训练 tokens 数
- G: 训练轮数
"""
return {
"gpt3_175b": {
"params": "175B",
"tokens": "300B",
"flops": "~3.1 × 10^23 FLOPs",
"a100_petaflops": "~3.1 × 10^5 PF",
"a100_8x_90_days": "~1.5 × 10^6 PF-days",
},
"llama2_70b": {
"params": "70B",
"tokens": "2T (预训练)",
"flops": "~1.4 × 10^24 FLOPs",
},
}
def time_estimation(self):
"""
训练时间估算
"""
return """
单卡 A100 (312 TFLOPS BF16):
LLaMA-2 70B, 2T tokens:
Theoretical time = FLOPs / FLOPS
= 1.4 × 10^24 / 3.12 × 10^14
= 4.5 × 10^9 seconds
= ~144 years
结论: 单卡训练不现实
需要的 GPU 数量:
1000 GPUs → ~53 天
4000 GPUs → ~13 天
"""

1.3 并行策略全景#

┌─────────────────────────────────────────────────────────────┐
│ 分布式训练并行策略 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Data Parallelism (DP) │
│ ───────────────────────────────────────────────────────── │
│ → 复制模型,并行处理不同数据分片 │
│ → 最简单,提升吞吐量 │
│ → 通信: AllReduce (梯度) │
│ │
│ Tensor Parallelism (TP) │
│ ───────────────────────────────────────────────────────── │
│ → 切分单个层的权重到多卡 │
│ → 用于超大型单层 (如 LLM 的 FFN/Attention) │
│ → 通信: AllReduce / AllGather │
│ │
│ Pipeline Parallelism (PP) │
│ ───────────────────────────────────────────────────────── │
│ → 按层切分模型到多卡 │
│ → 减少单卡显存需求 │
│ → 通信: P2P (点对点) │
│ │
│ Sequence Parallelism (SP) │
│ ───────────────────────────────────────────────────────── │
│ → 按序列维度切分 │
│ → 配合 TP 处理超长上下文 │
│ → 通信: AllReduce │
│ │
│ 组合: 2D / 3D Parallelism │
│ → TP × PP × DP │
│ → 千卡级别训练的必备 │
│ │
└─────────────────────────────────────────────────────────────┘

1.4 本系列文章关联#

文章关联
PEFT/LoRA 深度解析高效微调减少计算需求
模型量化深度解析训练后量化减少显存
vLLM 深度解析分布式推理技术

2. Data Parallelism#

2.1 核心原理#

class DataParallelism:
"""
Data Parallelism
"""
def basic_idea(self):
"""
核心思想
将训练数据分成多个 shard,每个 GPU 持有完整模型副本,
并行处理不同数据,最后同步梯度。
"""
return """
Data Parallelism 示意:
GPU 0: [Model Copy] → Batch 0 → Forward → Backward → Grad 0
GPU 1: [Model Copy] → Batch 1 → Forward → Backward → Grad 1
GPU 2: [Model Copy] → Batch 2 → Forward → Backward → Grad 2
GPU 3: [Model Copy] → Batch 3 → Forward → Backward → Grad 3
↓ Gradient AllReduce ↓
Avg(Grad 0, Grad 1, Grad 2, Grad 3)
↓ 每个 GPU 用平均梯度更新 ↓
特点:
→ 每个 GPU 有完整模型
→ 只通信梯度
→ 增加 GPU 数量可线性提升吞吐量
"""
def gradient_synchronization(self):
"""
梯度同步
"""
return '''
class DataParallelGradientSync:
"""梯度同步实现"""
def allreduce_sync(self, gradients, world_size):
"""
同步 SGD (所有 GPU 同步等待)
每个 GPU 计算梯度
→ AllReduce 同步梯度
→ 所有 GPU 都得到相同的平均梯度
→ 各自更新
优点: 收敛行为与单卡相同
缺点: 最慢的 GPU 拖慢整体
"""
import torch.distributed as dist
# 对每个参数梯度执行 AllReduce
for param in model.parameters():
dist.all_reduce(param.grad, op=dist.ReduceOp.SUM)
param.grad /= world_size
def distributed_sampler(self, dataset, num_gpus):
"""数据分片"""
return torch.utils.data.DistributedSampler(
dataset,
num_replicas=num_gpus,
rank=self.rank,
)
'''
def memory_analysis(self):
"""
显存分析
"""
return {
"model_weights": "N GB (完整副本)",
"optimizer_states": "2N GB (Adam: m + v, FP32)",
"gradients": "2N GB (FP32)",
"activations": "取决于 batch size",
"total_per_gpu": "~6N GB + activations",
"example_7b_fp16": {
"model": "14 GB",
"optimizer": "28 GB",
"gradients": "28 GB",
"activations_8": "16 GB (batch=8)",
"total": "~86 GB per GPU",
"a100_80gb": "不够,需要进一步优化",
},
}

2.2 DistributedDataParallel (DDP)#

class DDPImplementation:
"""
PyTorch DDP 实现
"""
def basic_usage(self):
"""
基本用法
"""
return '''
import torch
import torch.distributed as dist
import torch.multiprocessing as mp
from torch.nn.parallel import DistributedDataParallel as DDP
def setup(rank, world_size):
os.environ["MASTER_ADDR"] = "localhost"
os.environ["MASTER_PORT"] = "12355"
dist.init_process_group("nccl", rank=rank, world_size=world_size)
torch.cuda.set_device(rank)
def train(rank, world_size):
setup(rank, world_size)
# 创建模型
model = MyModel().cuda()
# 包装为 DDP
model = DDP(model, device_ids=[rank])
# 数据
dataset = MyDataset()
sampler = DistributedSampler(dataset)
dataloader = DataLoader(dataset, sampler=sampler)
# 训练循环
for epoch in range(num_epochs):
for batch in dataloader:
loss = model(batch).sum()
loss.backward()
optimizer.step()
optimizer.zero_grad()
dist.destroy_process_group()
# 启动
mp.spawn(train, args=(world_size,), nprocs=world_size)
'''
def gradient_bucket(self):
"""
Gradient Bucketing 优化
DDP 使用 bucket 机制减少通信开销
"""
return """
问题:
→ 逐参数同步梯度效率低
→ 每个小梯度都需要完整的 AllReduce 通信
解决: Gradient Bucketing
┌─────────────────────────────────────────────────────┐
│ Gradients │
│ [g1][g2][g3][g4][g5][g6][g7][g8]... │
└─────────────────────────────────────────────────────┘
↓ 分桶
┌─────────────────────────────────────────────────────┐
│ Bucket 0: [g1][g2][g3][g4] (size = 4 params) │
│ Bucket 1: [g5][g6][g7][g8] (size = 4 params) │
│ ... │
└─────────────────────────────────────────────────────┘
↓ 异步 AllReduce
┌─────────────────────────────────────────────────────┐
│ Bucket 0: AllReduce 完成 │
│ Bucket 1: AllReduce 进行中... │
│ ... │
└─────────────────────────────────────────────────────┘
效果:
→ 减少通信次数 (从 N 次到 N/bucket_size 次)
→ 重叠计算和通信
→ 带宽利用率更高
"""
def broadcast_buffers(self):
"""
Buffer 广播
"""
return """
DDP 的 Buffer 处理:
1. 同步 Buffers
- BatchNorm 的 running_mean/std
- 使用 AllReduce 同步
- 每个 GPU 广播自己的 buffers
2. 非同步 Buffers
- Dropout 的随机状态
- 不需要同步
3. 注册 Hook
- 可以在梯度同步时执行自定义操作
- 用途: gradient clipping, monitoring
"""

2.3 ZeRO 优化#

class ZeROOptimization:
"""
ZeRO (Zero Redundancy Optimizer)
切分优化器状态以减少显存冗余
"""
def stages(self):
"""
ZeRO 三个阶段
"""
return {
"ZeRO-1": {
"name": "分片优化器状态",
"description": "将 Adam optimizer states (m, v) 分片到各 GPU",
"memory_reduction": "4x (75% reduction)",
"communication": "与 DDP 相同",
},
"ZeRO-2": {
"name": "分片优化器状态 + 梯度",
"description": "ZeRO-1 + 梯度也分片",
"memory_reduction": "8x (~87.5% reduction)",
"communication": "略增 (allreduce 变成reduce-scatter + allgather)",
},
"ZeRO-3": {
"name": "分片所有状态",
"description": "ZeRO-2 + 模型参数也分片",
"memory_reduction": "线性减少 (N 倍)",
"communication": "显著增加 (需要动态 gather 参数)",
},
}
def zero_stage1(self):
"""
ZeRO-1 实现
"""
return '''
# ZeRO-1: 只分片优化器状态
# 优化器状态 (Adam):
# m (first moment) - FP32
# v (second moment) - FP32
# 每个参数 p 的优化器状态:
# p_fp32, m, v = 4 + 4 + 4 = 12 bytes per param
# 原来 (DDP): 每个 GPU 持有完整的 m, v
# ZeRO-1: 每个 GPU 只持有 1/N 的 m, v
class ZeRO1Optimizer:
def __init__(self, model, world_size, rank):
self.world_size = world_size
self.rank = rank
self.param_partitions = {} # rank → params
# 将参数均匀分配到各 GPU
all_params = list(model.parameters())
for i, param in enumerate(all_params):
target_rank = i % world_size
self.param_partitions[target_rank].append(param)
def step(self):
# 只更新本地 partition 的参数
for param in self.param_partitions[self.rank]:
# 更新 m, v (只存储本地部分)
self._update_adam_state(param)
'''
def zero_vs_ddp_memory(self):
"""
显存对比
"""
return """
70B 参数模型,FP16 权重,Adam 优化器:
DDP (完全副本):
┌──────────────────────────────────────────────────┐
│ 权重 (FP16): 140 GB │
│ 梯度 (FP32): 280 GB │
│ 优化器状态 (FP32): 280 GB │
│ 激活值: ~50 GB │
│ ───────────────────────────────────────────── │
│ 总计: ~750 GB │
│ 需要: A100 80GB × 10 │
└──────────────────────────────────────────────────┘
ZeRO-3 + 8 GPUs:
┌──────────────────────────────────────────────────┐
│ 权重分片: 140 / 8 = 17.5 GB │
│ 梯度分片: 280 / 8 = 35 GB │
│ 优化器状态分片: 280 / 8 = 35 GB │
│ 激活值: ~50 GB │
│ ───────────────────────────────────────────── │
│ 总计: ~137.5 GB per GPU │
│ 需要: A100 80GB × 8 + Offload │
└──────────────────────────────────────────────────┘
"""

3. Tensor Parallelism#

3.1 原理与动机#

class TensorParallelism:
"""
Tensor Parallelism
将单层权重矩阵沿某个维度切分到多个 GPU
"""
def why_tensor_parallel(self):
"""
为什么需要 Tensor Parallelism
对于 LLaMA-2 70B:
"""
return {
"embedding": "4096 × 32000 = 131M",
"attention": {
"q_proj": "4096 × 4096 = 16.8M × 3 = 50.4M",
"k_proj": "4096 × 4096",
"v_proj": "4096 × 4096",
"o_proj": "4096 × 4096 = 16.8M",
"total_attention": "67.2M per layer × 80 layers",
},
"ffn": {
"gate_proj": "11008 × 4096 = 45M",
"up_proj": "4096 × 11008 = 45M",
"down_proj": "11008 × 4096 = 45M",
"total_ffn": "135M per layer × 80 layers",
},
"largest_layer": "FFN up_proj: 45M params = 90 GB FP16",
"problem": "单层 FFN 比单卡显存还大!",
"solution": "切分到多卡",
}
def matrix_partitioning(self):
"""
矩阵分块策略
"""
return """
矩阵乘法 Y = XW
W: (M, N)
X: (B, M)
Y: (B, N)
┌─────────────────────────────────────────────────┐
│ W (M×N) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ W0 │ │ W1 │ │ W2 │ │
│ │(M, N/3) │ │(M, N/3) │ │(M, N/3) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ GPU 0 GPU 1 GPU 2 │
└─────────────────────────────────────────────────┘
X: (B, M) 复制到所有 GPU
Y0 = X @ W0 (B, N/3) → GPU 0
Y1 = X @ W1 (B, N/3) → GPU 1
Y2 = X @ W2 (B, N/3) → GPU 2
输出拼接: Y = [Y0, Y1, Y2]
"""

3.2 Column Parallel 与 Row Parallel#

class ParallelismTypes:
"""
列并行与行并行
"""
def column_parallel(self):
"""
Column Parallel
切分权重矩阵的列维度
"""
return """
用于 Linear 层的 QKV 投影:
W_qkv: (d_model, 3 * d_hidden)
Column Parallel (切分 3*d_hidden):
GPU 0: W_q0 (d_model, d_hidden)
GPU 1: W_k0 (d_model, d_hidden)
GPU 2: W_v0 (d_model, d_hidden)
...
前向:
X: (B, d_model) 复制
X @ W_q0 = Q0 (B, d_hidden)
X @ W_k0 = K0 (B, d_hidden)
X @ W_v0 = V0 (B, d_hidden)
通信: 无 (输出已经是分片的)
注意: 需要 AllGather 合并 Q/K/V 以进行 Attention
"""
def row_parallel(self):
"""
Row Parallel
切分权重矩阵的行维度
"""
return """
用于 Linear 层的输出投影:
W_o: (d_hidden, d_model)
Row Parallel (切分 d_hidden):
GPU 0: W_o0 (d_hidden/2, d_model)
GPU 1: W_o1 (d_hidden/2, d_model)
前向:
X0: (B, d_hidden/2) ← 从 Attention 来
X1: (B, d_hidden/2) ← 从 Attention 来
X0 @ W_o0 = Y0 (B, d_model)
X1 @ W_o1 = Y1 (B, d_model)
Y = Y0 + Y1 ← AllReduce (求和)
通信: AllReduce
"""
def attention_parallel(self):
"""
Attention 中的 Tensor Parallelism
"""
return """
Attention 层并行化:
┌─────────────────────────────────────────────────────────┐
│ Attention Layer │
├─────────────────────────────────────────────────────────┤
│ │
│ Input X │
│ ↓ │
│ ┌─────────────────┐ │
│ │ QKV Projection │ Column Parallel (每个 GPU 3 heads) │
│ └─────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Q 分布到所有 GPU │ │
│ │ K, V 需要 AllGather 收集 │ │
│ │ 各自计算部分 attention │ │
│ │ Output 经过 AllReduce │ │
│ └─────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────┐ │
│ │ Output Proj │ Row Parallel │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Megatron-LM 风格: 将 heads 分组,每组分配给不同 GPU
"""

3.3 通信分析#

class TPCommunication:
"""
Tensor Parallelism 通信分析
"""
def communication_pattern(self):
"""
通信模式
"""
return """
Transformer 层的 TP 通信:
┌──────────────────────────────────────────────────────────┐
│ Layer N │
├──────────────────────────────────────────────────────────┤
│ │
│ Input X │
│ ↓ │
│ QKV: Column Parallel → 无通信 │
│ ↓ │
│ Q AllGather (all TP ranks) → N-1 次广播 │
│ K AllGather (all TP ranks) → N-1 次广播 │
│ V AllGather (all TP ranks) → N-1 次广播 │
│ ↓ │
│ Attention Score (本地) │
│ ↓ │
│ Softmax → 无通信 │
│ ↓ │
│ Attention × V → AllReduce (求和输出) │
│ ↓ │
│ Output Proj: Row Parallel → AllReduce │
│ ↓ │
│ FFN Gate: Column Parallel → 无通信 │
│ ↓ │
│ FFN Up: Column Parallel → 无通信 │
│ ↓ │
│ FFN AllGather → AllGather │
│ ↓ │
│ FFN Down: Row Parallel → AllReduce │
│ ↓ │
│ Output X │
│ │
└──────────────────────────────────────────────────────────┘
每层通信: 4 AllGather + 2 AllReduce
"""
def bandwidth_requirement(self):
"""
带宽需求
"""
return {
"per_layer_per_gpu": "2 × seq_len × hidden_size × tp_size (bytes)",
"for_70b_seq_4096": "~128 MB per layer per forward",
"forward_per_epoch": "~128 MB × 80 layers × 1M steps",
"backward": "2x forward",
"bandwidth_analysis": {
"A100_NVLink": "900 GB/s bidirectional",
"Gen1_InfiniBand": "25 GB/s",
"Gen2_InfiniBand": "50 GB/s",
"Gen4_InfiniBand": "200 GB/s",
},
"recommendation": "TP 需要 NVLink 或高速互联",
}

4. Pipeline Parallelism#

4.1 基本原理#

class PipelineParallelism:
"""
Pipeline Parallelism
将模型按层切分到多个 GPU
"""
def layer_distribution(self):
"""
层分布
"""
return """
32 层模型,4-GPU Pipeline Parallel:
GPU 0: Layers 0-7 (embedding + first 8 layers)
GPU 1: Layers 8-15 (middle layers)
GPU 2: Layers 16-23 (middle layers)
GPU 3: Layers 24-31 (last 8 layers + output)
Forward:
┌─────────────────────────────────────────────────────────┐
│ GPU 0: [L0][L1][L2][L3][L4][L5][L6][L7] → hidden_7 │
│ ↓ │
│ GPU 1: [L8][L9][L10][L11][L12][L13][L14][L15]→hidd_15│
│ ↓ │
│ GPU 2: [L16]...[L23] → hidden_23 │
│ ↓ │
│ GPU 3: [L24]...[L31] → output │
└─────────────────────────────────────────────────────────┘
"""
def pipeline_bubble(self):
"""
Pipeline Bubble 问题
"""
return """
Naive Pipeline (无 interleaving):
时间 →→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
Microbatch 1: [GPU0][GPU1][GPU2][GPU3]
Microbatch 2: [GPU0][GPU1][GPU2][GPU3]
Microbatch 3: [GPU0][GPU1][GPU2][GPU3]
Microbatch 4: [GPU0][GPU1][GPU2][GPU3]
Bubble (空闲):
[ ][ ][ ][GPU0][ ][ ][ ][GPU1][ ][ ][ ][GPU2][ ][ ][ ][GPU3]
问题:
→ Bubble 数量 ≈ (P-1) / num_microbatches
→ P=4, microbatches=4 → 75% bubble!
→ GPU 利用率极低
"""
def interleaving(self):
"""
Interleaving 减少 Bubble
"""
return """
Interleaving (degree=4):
每个 GPU 处理多个 chunks:
GPU 0: [c0_0][c1_0][c2_0][c3_0][c4_0][c5_0]...
GPU 1: [c0_1][c1_1][c2_1][c3_1][c4_1][c5_1]...
GPU 2: [c0_2][c1_2][c2_2][c3_2][c4_2][c5_2]...
GPU 3: [c0_3][c1_3][c2_3][c3_3][c4_3][c5_3]...
每个 microbatch 在不同 GPU 上轮流执行
Bubble 大幅减少
Bubble 比例 ≈ 1 / (num_microbatches × degree)
"""

4.2 调度策略#

class ScheduleStrategies:
"""
调度策略
"""
def forward_backward(self):
"""
Forward-Backward-Pipeline
"""
return """
GPipe 调度 (Channeh et al., 2019):
1F1B 模式 (One Forward, One Backward):
Forward: [F0][F1][F2][F3]
Backward: [B3][B2][B1][B0]
完整调度 ( microbatches=8 ):
Stage 0: [F0][F1][F2][F3][B3][B2][B1][B0]
Stage 1: [F0][F1][F2][F3][B3][B2][B1][B0]
Stage 2: [F0][F1][F2][F3][B3][B2][B1][B0]
Stage 3: [F0][F1][F2][F3][B3][B2][B1][B0]
特点:
→ Forward 完成后立即开始 Backward
→ 稳定状态时每个 GPU 只做一个操作
→ Bubble 只出现在开始和结束
"""
def interleaved_schedule(self):
"""
Interleaved Schedule
"""
return """
Interleaved 1F1B:
每个 stage 被分成多个 sub-stages:
GPU 0: [S0_0][S0_1]...[S0_k] (layers 0..k, k+1..2k)
GPU 1: [S1_0][S1_1]...[S1_k] (layers 2k..3k, ...)
调度:
F0_0, F0_1, F1_0, F0_2, F1_1, F1_2, ...
优势:
→ 减少通信等待
→ 更好利用计算和通信重叠
"""
def async_pipeline(self):
"""
异步 Pipeline (实验性)
"""
return """
Chimera / PipeDream 风格:
思想: Forward 和 Backward 可以异步
GPU 0: [F0][F1][F2][F3]...[F0][F1][F2][F3]... (连续 forward)
GPU 1: [F0][F1][F2][F3]...[B0][B1][B2][B3]... (backward 滞后)
权衡:
→ 更高 GPU 利用率
→ 收敛性可能受影响
→ 需要 careful weight versioning
"""

4.3 PipeDream 实现#

class PipeDreamImplementation:
"""
PipeDream 风格实现
"""
def weight_stashing(self):
"""
Weight Stashing
保存每个 microbatch 对应的权重版本
"""
return '''
class PipeDreamModel:
"""PipeDream 实现"""
def __init__(self, stages, num_microbatches):
self.stages = stages
self.num_microbatches = num_microbatches
self.weights = {} # microb_id → weights
self.optimizer = Adam(self.stages.parameters())
def forward_backward(self, input_batch, microb_ids):
"""
1F1B 调度
"""
# Forward
for mb_id in microb_ids:
self.stages[mb_id % len(self.stages)].forward(
self.weights[mb_id] # 使用对应版本的权重
)
# Backward
for mb_id in reversed(microb_ids):
self.stages[mb_id % len(self.stages)].backward(
self.weights[mb_id] # 梯度累积到正确版本
)
# Update (每隔一段时间)
self.optimizer.step()
self.optimizer.zero_grad()
'''
def microbatch_vs_pipeline(self):
"""
Microbatch 与 Pipeline 对比
"""
return {
"small_microbatch": {
"pros": "更好的负载均衡,减少 bubble",
"cons": "更多通信开销,更多 activation 显存",
},
"large_microbatch": {
"pros": "减少通信,简化调度",
"cons": "bubble 比例增加",
},
"recommendation": {
"global_batch_size": "根据 GPU 数量调整",
"microbatch_size": "尽量让 pipeline 填满",
"num_microbatches": "P × 4 ~ P × 10",
},
}

5. Sequence Parallelism#

5.1 动机与场景#

class SequenceParallelism:
"""
Sequence Parallelism
沿序列维度切分
"""
def why_sequence_parallel(self):
"""
为什么需要 Sequence Parallelism
当 TP 处理超长序列时:
"""
return """
场景: 100K tokens 序列, TP=8
问题:
1. Attention 计算: O(N²) 显存
→ 即使 TP 切分 Q/K/V,单个 head 仍需处理 N/8 tokens
2. LayerNorm / Dropout
→ 需要看到完整序列
→ 成为瓶颈
3. 显存分布不均
→ embedding / output 层: 参数量大
→ attention / ffn: 激活值大
解决: Sequence Parallelism
沿序列维度切分:
seq_len = 100K
SP = 8
每个 GPU 处理 12.5K tokens
"""
def layerwise_operations(self):
"""
需要跨序列通信的操作
"""
return {
"attention": "需要 AllGather Q/K/V,然后 AllReduce 输出",
"layernorm": "需要 AllReduce 计算 mean/variance",
"dropout": "可以在本地处理",
"embedding": "需要 AllGather (输入) 和 AllReduce (输出)",
"loss": "需要 AllReduce",
}

5.2 环形通信#

class RingCommunication:
"""
环形通信实现
"""
def ring_allreduce(self):
"""
Ring AllReduce
"""
return """
Ring AllReduce 用于 Sequence Parallelism:
4 GPUs, 每个持有 N/4 tokens 的部分和
Step 1: Reduce Scatter
┌─────────────────────────────────────────────────────┐
│ GPU 0: [a0] → [a0+b0+c0+d0] │
│ GPU 1: [b0] → [b0+c0+d0+a0] │
│ GPU 2: [c0] → [c0+d0+a0+b0] │
│ GPU 3: [d0] → [d0+a0+b0+c0] │
└─────────────────────────────────────────────────────┘
Step 2: AllGather
┌─────────────────────────────────────────────────────┐
│ GPU 0: [sum] → [sum, sum, sum, sum] │
│ GPU 1: [sum] → [sum, sum, sum, sum] │
│ GPU 2: [sum] → [sum, sum, sum, sum] │
│ GPU 3: [sum] → [sum, sum, sum, sum] │
└─────────────────────────────────────────────────────┘
通信量: 2 × (N-1) / num_gpus
"""
def ring_attention(self):
"""
Ring Attention
"""
return """
Ring Attention 实现:
4 GPUs, 序列长度 N, 每个 GPU 处理 N/4 tokens
Q[i]: 本地查询
K[i], V[i]: 本地键值
1. Q 保持在本地
2. K, V 通过环形传递:
GPU 0: Q0 + [K0,V0] → 计算 [K0,V0] 的 attention
GPU 0: Q0 + [K1,V1] → 计算 [K1,V1] 的 attention (接收自 GPU 1)
GPU 0: Q0 + [K2,V2] → 计算 [K2,V2] 的 attention (接收自 GPU 2)
GPU 0: Q0 + [K3,V3] → 计算 [K3,V3] 的 attention (接收自 GPU 3)
3. 累加所有 attention 结果
通信: 每个 GPU 接收 K,V N-1 次
"""

6. 混合并行策略#

6.1 2D / 3D Parallelism#

class HybridParallelism:
"""
混合并行策略
"""
def tensor_pipeline_2d(self):
"""
TP × PP (2D Parallelism)
"""
return """
2D Parallelism: TP × PP
例子: 70B 模型, 16 GPUs
TP = 4, PP = 4:
GPU Layout:
┌─────────┬─────────┬─────────┬─────────┐
│ Stage 0 │ Stage 1 │ Stage 2 │ Stage 3 │
│ (TP=4) │ (TP=4) │ (TP=4) │ (TP=4) │
└─────────┴─────────┴─────────┴─────────┘
每个 Stage 有 4 GPUs (TP group)
4 个 Stages (Pipeline)
通信:
- TP 内部: AllReduce (NVLink)
- PP 跨 stage: P2P (IB)
"""
def dp_tp_pp_3d(self):
"""
DP × TP × PP (3D Parallelism)
"""
return """
3D Parallelism: DP × TP × PP
例子: 175B 模型, 64 GPUs
DP = 8, TP = 4, PP = 2:
总计: 8 × 4 × 2 = 64 GPUs
结构:
┌─────────────────────────────────────────────────────┐
│ DP Groups (8) │
│ ┌──────────┬──────────┬──────────┬──────────┐ │
│ │ PP 0 │ PP 1 │ PP 0 │ PP 1 │ ... │
│ │ (TP=4) │ (TP=4) │ (TP=4) │ (TP=4) │ │
│ └──────────┴──────────┴──────────┴──────────┘ │
│ ↑ │
│ Pipeline Communication │
└─────────────────────────────────────────────────────┘
内存估算 (175B FP16):
- TP=4: 每个 GPU 持有 1/4 的单层权重
- PP=2: 每 GPU 持有 1/2 的层数
- DP=8: 每个 DP replica 独立
每 GPU: 175B / (4 × 2) × 2 bytes = ~44 GB
+ activations + optimizer
"""
def communication_topology(self):
"""
通信拓扑感知
"""
return """
现代 GPU 集群的拓扑:
Node 0: [GPU 0] [GPU 1] [GPU 2] [GPU 3]
Node 1: [GPU 4] [GPU 5] [GPU 6] [GPU 7]
...
带宽层次:
┌─────────────────────────────────────────────────────┐
│ NVLink (within node): ~900 GB/s │
│ PCIe (within node): ~64 GB/s │
│ InfiniBand (cross node): ~50 GB/s │
└─────────────────────────────────────────────────────┘
最佳并行策略:
┌─────────────────────────────────────────────────────┐
│ TP: within node (NVLink) │
│ PP: across nodes (IB) │
│ DP: across all (梯度同步相对较小) │
└─────────────────────────────────────────────────────┘
"""

6.2 Megatron-LM 架构#

class MegatronArchitecture:
"""
Megatron-LM 架构
"""
def parallel_layout(self):
"""
并行布局
"""
return '''
# Megatron-LM 3D Parallel
# 配置:
# tensor_model_parallel_size = 4 (TP)
# pipeline_model_parallel_size = 4 (PP)
# data_parallel_size = N / (TP × PP)
# 模型构建
model = TransformerBlock(
tensor_parallel=TensorParallel,
pipeline_parallel=PipelineParallel,
)
# Forward 流程:
# 1. TP group 内广播输入
# 2. Pipeline 调度
# 3. 各 GPU 计算本地层
# 4. PP 跨 GPU 传递 hidden states
'''
def memory_estimation(self):
"""
显存估算
"""
return """
LLaMA-2 70B, 4096 sequence, batch=1, BF16:
单 GPU (无并行):
- 模型: 140 GB
- 激活值: ~50 GB
- 优化器: 280 GB
- 总计: ~470 GB
TP=8, PP=4:
- TP: 每层权重 / 8
- PP: 层数 / 4
- 每 GPU 权重: 140 / 32 = 4.4 GB
- 每 GPU 激活: 50 / 8 = 6.25 GB (SP 配合)
- 每 GPU 优化器: 280 / 32 = 8.75 GB
- 总计: ~19.4 GB per GPU
结论: 可以在 A100 80GB 上训练
"""

7. 主流框架实战#

7.1 PyTorch FSDP#

class FSDPImplementation:
"""
FSDP (Fully Sharded Data Parallel)
"""
def basic_usage(self):
"""
FSDP 基本用法
"""
return '''
import torch
from torch.distributed.fsdp import (
FullyShardedDataParallel as FSDP,
ShardingStrategy,
MixedPrecision,
BackwardPrefetch,
)
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
# 混合精度
fp16_policy = MixedPrecision(
param_dtype=torch.float16,
reduce_dtype=torch.float16,
buffer_dtype=torch.float16,
)
# 定义模型
model = Transformer()
# FSDP 包装
fsdp_model = FSDP(
model,
sharding_strategy=ShardingStrategy.FULL_SHARD, # ZeRO-3
mixed_precision=fp16_policy,
auto_wrap_policy=transformer_auto_wrap_policy,
backward_prefetch=BackwardPrefetch.BACKWARD_PRE,
device_id=torch.cuda.current_device(),
)
# 训练
for batch in dataloader:
loss = fsdp_model(batch)
loss.backward() # FSDP 自动分片梯度
fsdp_model.optimize_step()
'''
def sharding_strategies(self):
"""
分片策略
"""
return {
"FULL_SHARD": "参数 + 梯度 + 优化器状态全分片 (ZeRO-3)",
"SHARD_GRAD_OP": "梯度 + 优化器状态分片 (ZeRO-2)",
"NO_SHARD": "不分片,类似 DDP",
"HYBRID_SHARD": "本地分片 + 跨节点通信",
"recommendation": {
"small_model": "SHARD_GRAD_OP (低通信开销)",
"large_model": "FULL_SHARD (最低显存)",
"multi_node": "HYBRID_SHARD (减少跨节点通信)",
},
}
def cpu_offload(self):
"""
CPU Offload
"""
return '''
# CPU Offload 配置
from torch.distributed.fsdp import CPUOffload
fsdp_model = FSDP(
model,
sharding_strategy=ShardingStrategy.FULL_SHARD,
cpu_offload=CPUOffload(
offload_params=True, # 将参数卸载到 CPU
pin_memory=True,
),
)
# 效果:
# → 进一步减少 GPU 显存
# → 但增加 CPU-GPU 传输开销
# → 适合超大型模型
'''

7.2 DeepSpeed#

class DeepSpeedImplementation:
"""
DeepSpeed 实现
"""
def basic_config(self):
"""
DeepSpeed 配置
"""
return '''
# ds_config.json
{
"train_batch_size": 32,
"gradient_accumulation_steps": 4,
"fp16": {
"enabled": true
},
"zero_optimization": {
"stage": 3,
"offload_optimizer": {
"device": "cpu",
"pin_memory": true
},
"offload_param": {
"device": "cpu"
},
"overlap_comm": true,
"contiguous_gradients": true,
"sub_group_size": 1e9
},
"gradient_clipping": 1.0,
"wall_clock_breakdown": false
}
'''
def training_loop(self):
"""
训练循环
"""
return '''
import deepspeed
# 初始化 DeepSpeed
model, optimizer, _, _ = deepspeed.initialize(
model=model,
optimizer=optimizer,
config=ds_config,
dist_init_required=True,
)
# 训练
for batch in dataloader:
loss = model(batch)
model.backward(loss)
model.step()
'''
def pipeline_parallel(self):
"""
DeepSpeed Pipeline Parallelism
"""
return '''
# Pipeline 配置
{
"pipeline": {
"pipeline_parallel_size": 4,
"num_stages": 4,
"pipeline_checkpoint": true
},
"zero_optimization": {
"stage": 1, # ZeRO-1 (配合 PP 使用)
"reduce_bucket_size": 5e8,
"allgather_bucket_size": 5e8
}
}
# 注意: PP 和 ZeRO-1/2 配合效果最好
# ZeRO-3 会增加 PP 的通信量
'''

7.3 ColossalAI#

class ColossalAIImplementation:
"""
ColossalAI 实现
"""
def hybrid_parallel(self):
"""
混合并行配置
"""
return '''
from colossalai.booster import Booster
from colossalai.booster.plugin import HybridParallelPlugin
from colossalai.cluster import DistCoordinator
# 插件配置
plugin = HybridParallelPlugin(
tp_size=4, # Tensor Parallelism
pp_size=2, # Pipeline Parallelism
zero_stage=1, # ZeRO-1
num_microbatches=8, # Pipeline microbatches
)
# 启动 Booster
booster = Booster(plugin=plugin)
model, optimizer, dataloader, criterion = booster.enable(
model=model,
optimizer=optimizer,
dataloader=dataloader,
criterion=criterion,
)
# 训练循环
for batch in dataloader:
outputs = model(batch)
loss = criterion(outputs, batch["labels"])
booster.backward(loss, optimizer)
booster.optimize_step(optimizer)
'''

8. 通信优化#

8.1 通信计算重叠#

class CommunicationComputationOverlap:
"""
通信与计算重叠
"""
def gradient_computation_overlap(self):
"""
梯度计算与 AllReduce 重叠
"""
return """
异步梯度同步:
传统 (同步):
┌─────────────────────────────────────────────────────┐
│ [Forward] [AllReduce Grad] [Backward] [Optimizer] │
└─────────────────────────────────────────────────────┘
重叠 (异步):
┌─────────────────────────────────────────────────────┐
│ [F] [B1] [AR1] [B2] [AR2] [B3] [AR3] ... │
│ ↑ │
│ Backward 和 AllReduce 并行 │
└─────────────────────────────────────────────────────┘
实现:
- 使用梯度 bucket
- 前一个 bucket 的 AllReduce 和后一个 bucket 的 backward 并行
- DDP 默认启用
"""
def pp_communication_overlap(self):
"""
Pipeline Parallelism 通信重叠
"""
return """
P2P 通信与计算重叠:
┌─────────────────────────────────────────────────────┐
│ GPU 0: [F0][B0][F1][B1]... │
│ ↕ P2P │
│ GPU 1: [F0][B0][F1][B1]... │
│ ↕ P2P │
│ GPU 2: [F0][B0][F1][B1]... │
└─────────────────────────────────────────────────────┘
关键: 使用 CUDA 流并行执行计算和通信
# CUDA 流
compute_stream = torch.cuda.Stream()
comm_stream = torch.cuda.Stream()
with torch.cuda.stream(compute_stream):
compute()
# 异步发送
dist.isend(data, comm_stream)
"""

8.2 通信原语#

class CommunicationPrimitives:
"""
通信原语
"""
def allreduce(self):
"""
AllReduce
"""
return """
AllReduce: 所有 GPU 获得相同的归约结果
X = [x0, x1, x2, x3]
AllReduce(SUM):
→ [x0+x1+x2+x3, x0+x1+x2+x3, x0+x1+x2+x3, x0+x1+x2+x3]
用途:
- DDP 梯度同步
- TP Row Parallel 输出求和
"""
def allgather(self):
"""
AllGather
"""
return """
AllGather: 收集所有 GPU 的数据
X = [x0, x1, x2, x3]
AllGather:
→ [x0, x1, x2, x3, x0, x1, x2, x3, x0, x1, x2, x3, x0, x1, x2, x3]
用途:
- TP QKV 合并
- Sequence Parallel 中收集完整张量
"""
def reducescatter(self):
"""
ReduceScatter
"""
return """
ReduceScatter: 归约后分散
X = [x0, x0, x0, x0,
x1, x1, x1, x1,
x2, x2, x2, x2,
x3, x3, x3, x3]
ReduceScatter(SUM):
→ [sum(x0), sum(x1), sum(x2), sum(x3)]
用途:
- ZeRO 梯度分片
"""

8.3 NCCL 优化#

class NCCLOptimization:
"""
NCCL 优化
"""
def nccl_tuning(self):
"""
NCCL 调优
"""
return {
"NCCL_IB_CUDA": "使用 CUDA 加速 IB 传输",
"NCCL_SHM_DISABLE": "禁用共享内存 (可能导致问题)",
"NCCL_NVLS_ENABLE": "启用 NVLink 优化",
"NCCL_MIN_NCHANNELS": "最小化 channel 数",
"best_practices": [
"使用 NCCL 2.12+",
"启用 CUDA 加速",
"配置合适的 PXN (NVSwitch)",
],
}
def topology_aware(self):
"""
拓扑感知通信
"""
return '''
# PyTorch 拓扑感知
import torch.distributed as dist
# 检测 GPU 拓扑
if torch.cuda.is_available():
# 使用 NVLink/PCIe 拓扑
dist.init_process_group(
backend="nccl",
init_method="env://",
timeout=timedelta(seconds=1800),
)
# NCCL 自动检测拓扑
# 优化 GPU 对等连接
'''

9. 显存优化技术#

9.1 激活值重计算#

class ActivationRecomputation:
"""
激活值重计算 (Activation Checkpointing)
"""
def concept(self):
"""
概念
"""
return """
激活值重计算: 用计算换显存
Forward: 保存部分激活值
Backward: 重新计算未保存的激活值
例子:
┌─────────────────────────────────────────────────────┐
│ Forward: │
│ x1 = Layer1(input) │
│ x2 = Layer2(x1) ← 保存 │
│ x3 = Layer3(x2) ← 保存 │
│ x4 = Layer4(x3) ← 保存 │
│ x5 = Layer5(x4) ← 保存 │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Backward without recompute: │
│ grad_x4 = softmax(x5) ← 需要 x4, x3, x2 的激活值 │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Backward with recompute: │
│ x2 = recompute(Layer2, input) ← 重新计算 │
│ grad_x4 = softmax(x5) │
└─────────────────────────────────────────────────────┘
"""
def memory_savings(self):
"""
显存节省
"""
return {
"full_activations": "~40% 显存用于激活值",
"with_checkpointing": "节省 ~60-70% 激活值显存",
"cost": "增加 ~20-30% 计算量",
"selective_checkpointing": {
"recommendation": "只对大层启用",
"effect": "平衡显存和计算",
},
}
def implementation(self):
"""
实现
"""
return '''
# PyTorch 实现
from torch.utils.checkpoint import checkpoint
# 全量重计算
model = Transformer()
model = torch.utils.checkpoint.checkpoint_sequential(
model.layers,
chunks=4,
)
# 选择性重计算
class MyLayer(nn.Module):
def forward(self, x):
return checkpoint(self.heavy_op, x)
# FSDP 中的重计算
fsdp_model = FSDP(
model,
activation_checkpointing=checkpoint,
)
'''

9.2 混合精度训练#

class MixedPrecisionTraining:
"""
混合精度训练
"""
def bf16_training(self):
"""
BF16 训练
"""
return """
BF16 vs FP16:
FP16:
- 1 sign, 5 exponent, 10 mantissa
- 动态范围: ~6×10^4
- 精度较高但可能溢出
BF16:
- 1 sign, 8 exponent, 7 mantissa
- 动态范围: ~3×10^38
- 动态范围与 FP32 相同
- 训练更稳定
推荐:
→ Ampere 架构 (A100, RTX 3090+) 支持 BF16
→ H100 原生支持 BF16
→ 大模型训练优先使用 BF16
"""
def loss_scaling(self):
"""
Loss Scaling
"""
return '''
# FP16 训练需要 Loss Scaling
# PyTorch 自动管理
scaler = torch.cuda.amp.GradScaler()
for batch in dataloader:
with torch.cuda.amp.autocast():
outputs = model(batch)
loss = criterion(outputs, labels)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
# BF16 通常不需要 loss scaling
with torch.cuda.amp.autocast(dtype=torch.bfloat16):
outputs = model(batch)
'''

10. 实践指南#

10.1 配置选择#

class ConfigurationGuide:
"""
配置选择指南
"""
def model_size_to_config(self):
"""
根据模型大小选择配置
"""
return {
"7b_model": {
"single_node_8x_a100": {
"strategy": "ZeRO-2 or ZeRO-3",
"tp": 1,
"pp": 1,
"dp": 8,
"notes": "可以直接用 FSDP",
},
},
"13b_model": {
"single_node_8x_a100": {
"strategy": "ZeRO-2 + TP=2",
"tp": 2,
"pp": 1,
"dp": 4,
"notes": "PP 可能引入 bubble",
},
},
"70b_model": {
"single_node_8x_a100_80gb": {
"strategy": "ZeRO-3 + TP=4 + PP=2",
"tp": 4,
"pp": 2,
"dp": 1,
"notes": "需要仔细调优",
},
"multi_node": {
"strategy": "ZeRO-3 + TP=8",
"tp": 8,
"pp": 1,
"dp": "根据节点数",
"notes": "8节点训练",
},
},
"175b_model": {
"strategy": "3D Parallel: TP × PP × DP",
"tp": 8,
"pp": 8,
"dp": "根据 GPU 总数",
"notes": "需要数百 GPU",
},
}
def batch_size_recommendation(self):
"""
Batch Size 建议
"""
return """
Global Batch Size (GBS):
GBS = micro_batch_size × gradient_accumulation_steps × dp_size
经验公式:
- 小模型 (<10B): GBS ≈ 500K - 1M tokens
- 中模型 (10-70B): GBS ≈ 1M - 4M tokens
- 大模型 (>70B): GBS ≈ 4M+ tokens
示例:
模型: LLaMA-2 70B
GPU: 32 × A100
目标 GBS: 4M tokens
micro_batch_size: 1 (GPU 显存限制)
gradient_accumulation: 128
dp_size: 32
GBS = 1 × 128 × 32 = 4096 tokens
(需要调整)
调整:
micro_batch_size: 4
gradient_accumulation: 256
dp_size: 8 (TP=4, PP=2)
GBS = 4 × 256 × 8 = 8192 tokens
"""

10.2 性能调优清单#

class TuningChecklist:
"""
性能调优清单
"""
def pre_training(self):
"""
训练前检查
"""
return """
□ 验证模型正确性
- 单 GPU 测试 small model
- 对比参考实现 loss
□ 验证并行策略
- TP=2 验证正确性
- PP=2 验证流水线
- ZeRO 验证梯度同步
□ 性能基准
- MFU (Model FLOP Utilization)
- 通信带宽利用率
- GPU 利用率
"""
def during_training(self):
"""
训练中监控
"""
return """
□ 监控指标
- Loss 收敛曲线
- Gradient norm (检查梯度爆炸)
- Learning rate schedule
□ 资源利用
- GPU 利用率 (nvidia-smi)
- 通信带宽 (NCCL debug)
- CPU-GPU 数据传输
□ 异常检测
- Loss NaN/Inf
- GPU OOM
- 通信超时
"""

11. 核心公式汇总#

11.1 计算 FLOPs#

FLOPsforward=2×N×S\text{FLOPs}_{\text{forward}} = 2 \times N \times SFLOPsbackward=4×N×S\text{FLOPs}_{\text{backward}} = 4 \times N \times S

其中 NN 是参数量,SS 是 tokens 数。

11.2 MFU 计算#

MFU=实际 FLOPs峰值 FLOPs×100%\text{MFU} = \frac{\text{实际 FLOPs}}{\text{峰值 FLOPs}} \times 100\%

11.3 通信量#

操作通信量
DDP AllReduce2×grad_size2 \times \text{grad\_size}
TP AllReduce2×layer_output2 \times \text{layer\_output}
PP P2Phidden_size×S\text{hidden\_size} \times S

12. 总结#

12.1 策略对比#

┌─────────────────────────────────────────────────────────────┐
│ 并行策略对比 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Data Parallelism │
│ ───────────────────────────────────────────────────────── │
│ 显存减少: 1x (不变) │
│ 通信量: 中 (梯度) │
│ 通信模式: AllReduce │
│ 适用: 增加吞吐 │
│ │
│ Tensor Parallelism │
│ ───────────────────────────────────────────────────────── │
│ 显存减少: TPx │
│ 通信量: 高 (每层多次) │
│ 通信模式: AllReduce/AllGather │
│ 适用: 超大单层 │
│ │
│ Pipeline Parallelism │
│ ───────────────────────────────────────────────────────── │
│ 显存减少: PPx │
│ 通信量: 低 (P2P) │
│ 通信模式: 点对点 │
│ 适用: 减少层数 │
│ │
│ Sequence Parallelism │
│ ───────────────────────────────────────────────────────── │
│ 显存减少: SPx │
│ 通信量: 中 (attention) │
│ 通信模式: Ring AllReduce │
│ 适用: 超长序列 │
│ │
└─────────────────────────────────────────────────────────────┘

12.2 最佳实践#

分布式训练最佳实践:
1. 从简单开始
→ 先用 DDP/ZeRO 验证
→ 再加入 TP/PP
2. 通信拓扑感知
→ TP 在节点内 (NVLink)
→ PP 跨节点 (InfiniBand)
→ DP 可跨节点
3. 显存优化
→ 启用混合精度 (BF16)
→ 使用激活值重计算
→ ZeRO-3 配合 PP 时注意通信
4. 性能监控
→ MFU 目标 > 50%
→ 监控 GPU 利用率和通信
→ 识别瓶颈 (计算 vs 通信)
5. 故障恢复
→ 保存 checkpoint
→ 支持从 checkpoint 恢复
→ 处理 GPU 故障
推荐阅读
  1. Megatron-LM Paper—— Tensor Parallelism 经典实现
  2. GPipe Paper—— Pipeline Parallelism
  3. ZeRO Paper—— 显存优化
  4. ColossalAI Docs—— 混合并行框架

参考资料#

  1. Shoeybi, M., et al. (2020). “Megatron-LM: Training Multi-Billion Parameter Language Models Using Model Parallelism.” arXiv.
  2. Huang, Y., et al. (2019). “GPipe: Efficient Training of Giant Neural Networks with Pipeline Parallelism.” NeurIPS.
  3. Rajbhandari, S., et al. (2020). “ZeRO: Memory Optimizations Toward Training Trillion Parameter Models.” SC20.
  4. Narayanan, D., et al. (2021). “Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM.” SC21.
  5. Li, S., et al. (2021). “Megatron-CM3: Multi-Context Prompted Training.” arXiv.
  6. Zhao, J., et al. (2023). “PipeDream: Balanced Pipeline Parallelism for DNN Training.” SOSP.
  7. Narayanan, D., et al. (2019). “Pipedream: Weight-Aware Pipeline Parallelism.” MLSys.
  8. Rasley, J., et al. (2020). “DeepSpeed: System Optimizations for Training and Inference.” Blog.
  9. Dao, T., et al. (2022). “FlashAttention: Fast and Memory-Efficient Exact Attention.” NeurIPS.
  10. Chen, K., et al. (2023). “ColossalAI: A Unified Training Engine for Large-Scale Models.” GitHub.

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

分布式训练深度解析:Data / Tensor / Pipeline / Sequence Parallelism
https://aiattnstudio.link/posts/distributed-training/
作者
Federico
发布于
2026-07-16
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author

Federico

AI Research Lab

Hello, I'm Federico.

关于实验室 / About
公告

欢迎来到Federico的个人博客

分类
标签
站点统计
57文章
7分类
404标签