必须先调用 torch.distributed.init_process_group 初始化进程组,否则 DistributedDataParallel 会因默认进程组未初始化而报错;且需确保模型、loss、保存加载等各环节严格匹配多卡分布式规范。

为什么直接用 DistributedDataParallel 会报错 RuntimeError: Default process group is not initialized
因为 DistributedDataParallel 不是开箱即用的封装,它依赖 PyTorch 的分布式后端(如 NCCL)和已初始化的进程组。没调用 torch.distributed.init_process_group 就直接包装模型,必然触发这个错误。
实操要点:
- 必须在每个 GPU 进程中单独调用
init_process_group,且rank和world_size要严格匹配实际启动的进程数 - 推荐用
torchrun启动(不用手动写mp.spawn),它自动设置MASTER_ADDR、MASTER_PORT、RANK、WORLD_SIZE - NCCL 是多卡训练首选后端,启动前建议加环境变量:
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1,2,3'(与实际卡序一致)
DistributedDataParallel 包装模型时常见的设备错位问题
典型现象:模型在 CPU 上定义,或 .cuda() 调用位置不对,导致 DDP 内部张量设备不一致,报错类似 Expected all tensors to be on the same device。
正确做法:
- 先用
model.to(device)把模型移到当前进程对应的 GPU(例如device = torch.device(f'cuda:{local_rank}')) - 再传入
DistributedDataParallel(model, device_ids=[local_rank])—— 注意device_ids必须是单元素列表,不是整数 - 别用
model.cuda()后再传device_ids=[0]:如果当前进程跑在 GPU 2 上,这会导致数据搬运失败
训练循环里 loss.backward() 前为什么必须调用 loss.mean()
因为 DistributedDataParallel 默认对每个 GPU 的 batch 独立计算 loss,而 DDP 不会自动跨卡平均 loss 值。如果不手动取均值,反向传播时梯度会被放大 world_size 倍,等效于用了更大的 batch size 却没调学习率,极易发散。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
关键细节:
- 不是所有 loss 都需要
.mean():比如nn.CrossEntropyLoss(reduction='mean')默认已均值化,但若设成'none',就必须手动.mean() - 验证/测试阶段也要注意:
torch.no_grad()下同样要对每卡输出做 gather 或 avg,否则指标虚高 - 避免在 loss 计算里引入非标量操作(如
.sum()后不除batch_size),这会让梯度 scale 失控
保存和加载 DistributedDataParallel 模型的正确姿势
直接保存 model.state_dict() 会存带 module. 前缀的 key(因为 DDP 包装后所有参数名自动加了前缀),导致单卡加载时报 Missing key 或 Unexpected key。
稳妥方案:
- 保存时用
model.module.state_dict()(只在 rank 0 进程保存,避免多卡重复写) - 加载时不管是否用 DDP,都统一用
model.load_state_dict(...),但需确保模型结构一致;如果加载的是单卡训练的 checkpoint,key 没有module.前缀,可加一层映射:{k.replace('module.', ''): v for k, v in sd.items()} - 不要用
torch.save(model, ...)保存整个对象——序列化 DDP 实例不可靠,且体积大
最易被忽略的一点:不同卡上的 model.module 是同一份权重副本,但 optimizer 状态不是同步的;所以 resume 时,optimizer 应该在所有进程上用相同初始化方式重建,并加载其 state_dict(同样只从 rank 0 加载)。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










