单机多卡训练-DDP
DDP原理:
为什么快?
DDP通过Ring-Reduce(梯度合并)的数据交换方法提高了通讯效率,并通过启动多个进程的方式减轻Python GIL的限制,从而提高训练速度。
神经网络中的并行有以下三种形式:
- Data Parallelism
- 这是最常见的形式,通俗来讲,就是增大batch size提高并行度。
- 平时我们看到的多卡并行就属于这种。比如DP、DDP都是。这能让我们方便地利用多卡计算资源。
- 能加速。
- 这是最常见的形式,通俗来讲,就是增大batch size提高并行度。
- Model Parallelism
- 把模型放在不同GPU上,计算是并行的。
- 有可能是加速的,看通讯效率。
- Workload Partitioning
- 把模型放在不同GPU上,但计算是串行的。
- 不能加速。
参考:[原创][深度][PyTorch] DDP系列第一篇:入门教程 - 知乎 (zhihu.com)?
[原创][深度][PyTorch] DDP系列第一篇:入门教程 - 知乎 (zhihu.com)
注意点:
1. 保存模型
考虑到以后可能需要单卡加载你多卡训练的模型,建议在保存模型时,去除模型参数字典里面的module,如何去除呢,使用model.module.state_dict()代替model.state_dict()
2.??每一个epoch里面真正的打乱数据
for epoch in range(args.num_epochs):
train_sampler.set_epoch(epoch) # shuffle数据
3. 设置多个gpu的BN同步(下面第一句代码)
# 设置模型并行
model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model) # 多个gpu的BN同步
model = torch.nn.parallel.DistributedDataParallel(model.cuda())
SyncBatchNorm 是一个 PyTorch 模块,可对小批量数据执行批量标准化,但会同步分布式训练环境中所有 GPU 的平均值和标准差统计数据。这与标准 PyTorch BatchNorm 模块形成对比,后者在每个 GPU 上独立计算平均值和标准差统计数据。
4. 固定随机种子
单卡时:
import random
import numpy as np
import torch
def init_seeds(seed=0, cuda_deterministic=True):
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
# Speed-reproducibility tradeoff https://pytorch.org/docs/stable/notes/randomness.html
if cuda_deterministic: # slower, more reproducible
cudnn.deterministic = True
cudnn.benchmark = False
else: # faster, less reproducible
cudnn.deterministic = False
cudnn.benchmark = True
def main():
# 一般都直接用0作为固定的随机数种子。
init_seeds(0)
单机多卡时,需要给不同的进程分配不同的、固定的随机数种子::
def main():
rank = torch.distributed.get_rank()
# 问题完美解决!
init_seeds(1 + rank)
注意自己在写代码时只写了torch.manual_seed(seed),这不够全面,最好按照以上init_seed函数,使用?random.seed、np.random.seed、torch.manual_seed 分别初始化 Python 内置的 random 模块、NumPy 库、以及 PyTorch 库的随机数生成器。根据 cuda_deterministic 的设置,可能会设置 cudnn.deterministic 为 True,从而使得使用 CUDA 的部分更加确定性。这通常会导致训练速度稍微变慢,但提高了可重现性。
写的很完整的一篇文章:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!