网站内文章标题格式,系统管理包括哪些内容,网站设计项目,做网站交互目录 一、几个比较常见的概念#xff1a;二、踩坑记录2.1 dist.init_process_group初始化2.2 spawn启动#xff08;rank怎么来的#xff09;2.3 loss backward2.4 model cuda设置2.5 数据加载 一、几个比较常见的概念#xff1a;
rank: 多机多卡时代表某一台机器#xff… 目录 一、几个比较常见的概念二、踩坑记录2.1 dist.init_process_group初始化2.2 spawn启动rank怎么来的2.3 loss backward2.4 model cuda设置2.5 数据加载 一、几个比较常见的概念
rank: 多机多卡时代表某一台机器单机多卡时代表某一块GPUworld_size: 多机多卡时代表有几台机器单机多卡时代表有几块GPUworld_size torch.cuda.device_count()local_rank: 多机多卡时代表某一块GPU 单机多卡时代表某一块GPU 单机多卡的情况要比多机多卡的情况常见的多。DP适用于单机多卡多进程训练。算是旧版本的DDPDDP适用于单机多卡训练、多机多卡。
二、踩坑记录
2.1 dist.init_process_group初始化
这一步就是设定一个组这个组里面设定你有几个进程world_size现在是卡几rank。让pycharm知道你要跑几个进程包装在组内进行通讯这样模型参数会自己同步不需要额外操作了。
import os
import torch.distributed as distdef ddp_setup(rank,world_size):os.environ[MASTER_ADDR] localhost #rank0 对应的地址os.environ[MASTER_PORT] 6666 #任何空闲的端口dist.init_process_group(backendnccl, #nccl Gloo #nvidia显卡的选择ncclworld_sizeworld_size, init_methodenv://,rankrank) #初始化默认的分布进程组dist.barrier() #等到每块GPU运行到这再继续往下走2.2 spawn启动rank怎么来的
rank是自动分配的。怎么分配呢?这里用的是spawn也就一行代码。
import torch.multiprocessing as mp
def main (rank:int,world_size:int,args):pass#训练代码 主函数mp.spawn(main,args(args.world_size,args), nprocsargs.world_size)注意调用spawn的时候没有输入main的其中一个参数rankrank由代码自动分配。将代码复制两份在两张卡上同时跑你可以print(rank)会发现输出 0 1。两份代码并行跑。
另外nprocsargs.world_size。如果不这么写代码会卡死在这既不报错也不停止。
2.3 loss backward
one of the variables needed for gradient computation has been modified by an inplace operationRuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [2048]] is at version 4; expected version 3 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).经过调试发现当使用nn.DataParallel并行训练或者单卡训练均可正常运行另外如果将两次模型调用集成到model中即通过out1, out2 model(input0, input1) 的方式在分布式训练下也不会报错。
在分布式训练中如果对同一模型进行多次调用则会触发以上报错即nn.parallel.DistributedDataParallel方法封装的模型forword()函数和backward()函数必须交替执行如果执行多个次forward()然后执行一次backward()则会报错。
解决此问题可以聚焦到nn.parallel.DistributedDataParallel接口上通过查询PyTorch官方文档发现此接口下的两个参数
find_unused_parameters: 如果模型的输出有不需要进行反向传播的此参数需要设置为True若你的代码运行后卡住不动基本上就是该参数的问题。broadcast_buffers: 该参数默认为True设置为True时在模型执行forward之前gpu0会把buffer中的参数值全部覆盖到别的gpu上。
model nn.parallel.DistributedDataParallel(model, device_ids[args.local_rank], broadcast_buffersFalse, find_unused_parametersTrue)2.4 model cuda设置
RuntimeError: NCCL error in: ../torch/lib/c10d/ProcessGroupNCCL.cpp:859, invalid usage, NCCL version 21.1.1
ncclInvalidUsage: This usually reflects invalid usage of NCCL library (such as too many async ops, too many collectives at once, mixing streams in a group, etc).*这是因为model和local_rank所指定device不一致引起的错误。
model.cuda(args.local_rank)
model torch.nn.parallel.DistributedDataParallel(model, device_ids[args.local_rank],broadcast_buffersFalse,find_unused_parametersTrue)2.5 数据加载
使用distributed加载数据集需要使用DistributedSampler自动为每个gpu分配数据但需要注意的是sampler和shuffleTrue不能并存。
train_sampler DistributedSampler(trainset)
train_loader torch.utils.data.DataLoader(trainset,batch_sizeargs.train_batch_size,num_workersargs.train_workers,samplertrain_sampler)