减少梯度数据量一半
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
for data in dataloader:
with autocast():
loss = model(data)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()✅ FP16 梯度通信
✅ 对 AllReduce 非常友好
减少通信频率
accum_steps = 4
optimizer.zero_grad()
for i, data in enumerate(dataloader):
loss = model(data) / accum_steps
loss.backward()
if (i + 1) % accum_steps == 0:
optimizer.step()
optimizer.zero_grad()✅ 每 N 步才同步一次梯度
for p in model.parameters():
grad = p.grad
threshold = grad.abs().max() * 0.01
mask = grad.abs() > threshold
p.grad = grad * mask⚠️ PyTorch 原生对稀疏 AllReduce 支持有限,通常需要自定义或第三方库。
通信次数 ∝ step 数
| 方法 | 说明 |
|---|---|
| 增大 batch size | 减少 step |
| LAMB / LARS | 大 batch 优化器 |
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)减少 梯度 + 参数 + 优化器状态 的通信
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
model = FSDP(model)✅ 比 DDP 更少通信
export NCCL_IB_DISABLE=0 # 使用 InfiniBand
export NCCL_SOCKET_IFNAME=eth0| 后端 | 适用 |
|---|---|
| nccl | GPU(强烈推荐) |
| gloo | CPU |
| mpi | HPC |
PyTorch DDP 默认开启梯度 bucket 通信
DistributedDataParallel(
model,
bucket_cap_mb=25 # 默认 25
)✅ 反向传播时边算边通信
.item() / .cpu(),会打断同步local_rank| 场景 | 推荐 |
|---|---|
| 小模型、多卡 | DDP |
| 大模型(>10 亿) | FSDP / ZeRO |
| 超大模型 | Pipeline + Tensor Parallel |
| 多机带宽差 | 增大 batch + 梯度累积 |
❌ 每次 step 都 .item() / print(loss)
❌ 使用 Python 控制流打断图
❌ 在 DDP 中手动 AllReduce
✅ 首选方案组合:
✅ 进阶:
如果你愿意,我可以:
你可以直接贴你的:
模型大小 / GPU 数量 / batch size / 是否跨机