可以用“watch -n 0.1 nvidia-smi”来查看gpu状态,我用的是3块12G的GPU进行实验

本实验将使用一个简单的瞎写的网络进行,网络训练一个分类任务,当然这个不重要,我们也不关心效果,这里希望用一个简单的网络来说明如何使用GPU训练,这个网络是可以直接跑起来的,xdm可以动手尝试一下

在第0部分是CPU上训练的代码,第一部分使用了单张GPU,第二部分是单机多卡的任务

目录

0、CPU代码

1、单机单卡

2、单机多卡

2.1 DataParaller(DP)(不建议用)

2.2DistributedSampler(DDP)


0、CPU代码

#样例 准备数据,加载数据,准备模型,设置损失函数,设置优化器,开始训练,最后验证,结果聚合展示import torch
import torchvision
from torch.nn import Sequential
from torch.utils.data import DataLoader
from torch import nn#搭建神经网络
class MyModule(nn.Module):def __init__(self):super(MyModule, self).__init__()self.model1=Sequential(nn.Conv2d(3,32,5,1,2),nn.Conv2d(32,64,5,1,2),nn.Conv2d(64,512,5,1,2),nn.MaxPool2d(2),nn.Conv2d(512, 1024, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(1024, 2048, 5, 1, 2),nn.Conv2d(2048, 4096, 5, 1, 2),nn.MaxPool2d(2))self.model2=Sequential(nn.Flatten(),nn.Linear(4096*4*4,8000),nn.Linear(8000,64),nn.Linear(64,10))def forward(self, x):x=self.model1(x)x=self.model2(x)return xif __name__=="__main__":"""准备数据集"""#训练train_data=torchvision.datasets.CIFAR10(root="./DataSet",train=True,transform=torchvision.transforms.ToTensor(),download=True)train_data_size=len(train_data)print("训练数据集的长度为{}".format(train_data_size))#50000#利用DataLoader加载数据集train_dataloader=DataLoader(train_data,batch_size=64)#初始化#创建模型myModule=MyModule()#损失函数loss_fn=nn.CrossEntropyLoss()#定义优化器learning_rate=0.01optimize=torch.optim.SGD(myModule.parameters() ,lr=learning_rate )#训练次数train_step=0#测试次数test_step=0#训练轮数epoch=10#开始训练#训练迭代几次for i in range(epoch):print("------第 {} 轮训练开始------".format(i+1))#每一次的训练myModule.train()for data in train_dataloader:imgs,targets=dataoutputs=myModule(imgs)#计算损失loss=loss_fn(outputs,targets)# 利用优化器对参数优化,调优optimize.zero_grad()loss.backward()optimize.step()train_step=train_step+1#一张图片加一次if train_step%10==0:print("训练次数:{},Loss:{}".format(train_step,loss.item()))#加item将tensor转化为数字#保存每一轮训练后的模型torch.save(myModule.state_dict(),"myModule_{}.pth".format(i))print("模型已保存")

1、单机单卡

使用的函数:

#1、判断GPU是否可用:
torch.cuda.is_availabel()#2、使用0号GPU
os.environ["CUDA_VISIBLE_DEVICES"]="0"#3、数据拷贝到GPU
model.cuda()#不用赋值
data = data.cuda()#4、模型保存与加载
torch.save
torch.load(file_name,mao_location=torch.device("cuda"/"cpu"))

在任务1的基础上改变的代码均使用注释标记了

#样例 准备数据,加载数据,准备模型,设置损失函数,设置优化器,开始训练,最后验证,结果聚合展示import torch
import torchvision
import os
from torch.nn import Sequential
from torch.utils.data import DataLoader
from torch import nnclass MyModule(nn.Module):def __init__(self):super(MyModule, self).__init__()self.model1=Sequential(nn.Conv2d(3,32,5,1,2),nn.Conv2d(32,64,5,1,2),nn.Conv2d(64,512,5,1,2),nn.MaxPool2d(2),nn.Conv2d(512, 1024, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(1024, 2048, 5, 1, 2),nn.Conv2d(2048, 4096, 5, 1, 2),nn.MaxPool2d(2))self.model2=Sequential(nn.Flatten(),nn.Linear(4096*4*4,5000),nn.Linear(5000,64),nn.Linear(64,10))def forward(self, x):x=self.model1(x)x=self.model2(x)return xif __name__=="__main__":#检验GPU是否可用if torch.cuda.is_available():print("Use one GPU")#使用的GPUos.environ["CUDA_VISIBLE_DEVICES"] = "0"else:print("can't use GPU")raise Exception("can't use GPU")train_data=torchvision.datasets.CIFAR10(root="./DataSet",train=True,transform=torchvision.transforms.ToTensor(),download=True)train_data_size=len(train_data)print("训练数据集的长度为{}".format(train_data_size))#50000train_dataloader=DataLoader(train_data,batch_size=64)myModule=MyModule()#模型拷贝到cuda()myModule.cuda()loss_fn=nn.CrossEntropyLoss()learning_rate=0.01optimize=torch.optim.SGD(myModule.parameters() ,lr=learning_rate )train_step=0test_step=0epoch=10for i in range(epoch):print("------第 {} 轮训练开始------".format(i+1))myModule.train()for data in train_dataloader:imgs,targets=data#将数据赋值到gpuimgs = imgs.cuda()targets = targets.cuda()outputs=myModule(imgs)loss=loss_fn(outputs,targets)optimize.zero_grad()loss.backward()optimize.step()train_step=train_step+1if train_step%1==0:print("训练次数:{},Loss:{}".format(train_step,loss.item()))torch.save(myModule.state_dict(),"myModule_{}.pth".format(i))print("模型已保存")

2、单机多卡

这里有两种方案,一种是使用torch.nn.DataParaller,这种方案会慢但改动的代码量较少,但巨慢。另一种是nn.parallerl.DistributedDataParallel,这种方案改动会比较大,但是最终的代码多进程效率会高。

注意这边的小坑:后面采取的cuda标号都是按os.environ["CUDA_VISIBLE_DEVICES"]="0,1,2"中的顺序

2.1 DataParaller(DP)(不建议用)

锐评:改是真的好改,慢是真的慢

#将模型放到多个GPU上
#只用改一句
model = DataParallerl(model.cuda,device_ids = [0,1,2])

代码:

import torch
import torchvision
import os
from torch.nn import Sequential
from torch.utils.data import DataLoader
from torch import nnclass MyModule(nn.Module):def __init__(self):super(MyModule, self).__init__()self.model1=Sequential(nn.Conv2d(3,32,5,1,2),nn.Conv2d(32,64,5,1,2),nn.Conv2d(64,512,5,1,2),nn.MaxPool2d(2),nn.Conv2d(512, 1024, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(1024, 2048, 5, 1, 2),nn.Conv2d(2048, 4096, 5, 1, 2),nn.MaxPool2d(2))self.model2=Sequential(nn.Flatten(),nn.Linear(4096*4*4,5000),nn.Linear(5000,64),nn.Linear(64,10))def forward(self, x):x=self.model1(x)x=self.model2(x)return xif __name__=="__main__":#检验GPU是否可用if torch.cuda.is_available():print(torch.cuda.device_count())print("Use GPU")#使用的GPUos.environ["CUDA_VISIBLE_DEVICES"] = "0,1,2"else:print("can't use GPU")raise Exception("can't use GPU")train_data=torchvision.datasets.CIFAR10(root="./DataSet",train=True,transform=torchvision.transforms.ToTensor(),download=True)train_data_size=len(train_data)print("训练数据集的长度为{}".format(train_data_size))#50000train_dataloader=DataLoader(train_data,batch_size=64)myModule=MyModule()#模型拷贝到cuda()myModule = nn.DataParallel(myModule.cuda(), device_ids = [0,1,2])loss_fn=nn.CrossEntropyLoss()learning_rate=0.01optimize=torch.optim.SGD(myModule.parameters() ,lr=learning_rate )train_step=0test_step=0epoch=10for i in range(epoch):print("------第 {} 轮训练开始------".format(i+1))myModule.train()for data in train_dataloader:imgs,targets=data#将数据赋值到gpuimgs = imgs.cuda()targets = targets.cuda()outputs=myModule(imgs)loss=loss_fn(outputs,targets)optimize.zero_grad()loss.backward()optimize.step()train_step=train_step+1if train_step%1==0:print("训练次数:{},Loss:{}".format(train_step,loss.item()))torch.save(myModule.state_dict(),"myModule_{}.pth".format(i))print("模型已保存")

2.2DistributedSampler(DDP)

这个方法的最大不同在于gpu自动分配为args.local_rank

注意模型文件只在args.local_rank == 0时保存就可以

注意启动方式特殊

python -m torch.distributed.launch --nproc_per_node=n_gpus test.py

#执行命令n_gpus 是gpu数目,torch.distributed.launch自动分配从0到n_gpus-1
python -m torch.distributed.launch --nproc_per_node=n_gpus test.py
在写代码时要用parser来接住'--local_rank'#初始化:
torch.distributed.init_process_group("nccl", world_size = n_gpus, rank = args.local_rank)
#参数分别是:gpu通信方式,gpu数量,一个环境变量#
torch.cuda.set_device(arg.local_rank)#模型载入
model = DistributeDataParallel(model.cuda(arg.local_rank),device_ids = [args.local_rank])#数据集操作
#分配数据集
train_sampler = DistributedSampler(train_dataset)
#为增加随机性。要注意在每个批次训练之前需要调用
train_sampler.set_epoch(epoch)
#DataLoader中传入sampler,注意sampler和shuffle互斥
train_dataloader = DataLoader(..., sampler=train_sampler)
#数据拷贝到相应的卡上
data = data.cuda(args.local_rank)

代码:

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"
import torch
import torchvision
from torch.nn import Sequential
from torch.utils.data import DataLoader
from torch.utils.data.distributed import DistributedSampler#导入包
from torch import nn
import argparse
import timeclass MyModule(nn.Module):def __init__(self):super(MyModule, self).__init__()self.model1=Sequential(nn.Conv2d(3,32,5,1,2),nn.Conv2d(32,64,5,1,2),nn.Conv2d(64,512,5,1,2),nn.MaxPool2d(2),nn.Conv2d(512, 1024, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(1024, 2048, 5, 1, 2),nn.Conv2d(2048, 4096, 5, 1, 2),nn.MaxPool2d(2))self.model2=Sequential(nn.Flatten(),nn.Linear(4096*4*4,5000),nn.Linear(5000,64),nn.Linear(64,10))def forward(self, x):x=self.model1(x)x=self.model2(x)return xif __name__=="__main__":#设置参数args.local_rankparser = argparse.ArgumentParser()parser.add_argument("--local_rank", help = "local device id on current node", type = int)args = parser.parse_args()if torch.cuda.is_available():print(torch.cuda.device_count())print("Use GPU")else:print("can't use GPU")raise Exception("can't use GPU")#初始化n_gpus = 2torch.distributed.init_process_group("nccl", world_size = n_gpus, rank = args.local_rank)torch.cuda.set_device(args.local_rank)#修改环境变量train_data=torchvision.datasets.CIFAR10(root="./DataSet",train=True,transform=torchvision.transforms.ToTensor(),download=True)train_data_size=len(train_data)print("训练数据集的长度为{}".format(train_data_size))#50000#数据集划分后载入train_sampler = DistributedSampler(train_data)train_dataloader=DataLoader(train_data,batch_size=64, sampler = train_sampler)#batch_size会变小myModule=MyModule()#模型载入args.local_rankmyModule.cuda()myModule = nn.parallel.DistributedDataParallel(myModule.cuda(args.local_rank), device_ids = [args.local_rank])loss_fn=nn.CrossEntropyLoss()learning_rate=0.01optimize=torch.optim.SGD(myModule.parameters() ,lr=learning_rate )train_step=0test_step=0epoch=10for i in range(epoch):print("------第 {} 轮训练开始------".format(i+1))train_sampler.set_epoch(epoch)#每张卡在每个周期上的值是随机的myModule.train()for data in train_dataloader:imgs,targets=data#将数据赋值到args.local_rankimgs = imgs.cuda(args.local_rank)targets = targets.cuda(args.local_rank)starttime = time.time()outputs=myModule(imgs)loss=loss_fn(outputs,targets)optimize.zero_grad()loss.backward()optimize.step()endtime = time.time()train_step=train_step+1if train_step%1==0:print("训练次数:{},Loss:{},time:{}".format(train_step,loss.item(),endtime-starttime))#仅在args.local_rank == 0时保存if args.local_rank ==0:torch.save(myModule.state_dict(),"myModule_{}.pth".format(i))print("模型已保存")

pytorch GPU分布式训练 单机单卡、单机多卡相关推荐

  1. pytorch多GPU分布式训练代码编写

    本文主要讲述单机单卡.单机多卡的简单使用方法: 文章目录 单机单卡 单机多卡 DP DDP 单机单卡 单机单卡就是一台机器上只有一张卡,是最简单的训练方式 对于单机单卡,我们所需要做的就是把模型和数据 ...

  2. 简单介绍pytorch中分布式训练DDP使用 (结合实例,快速入门)

    文章目录 DDP原理 pytorch中DDP使用 相关的概念 使用流程 如何启动 torch.distributed.launch spawn调用方式 针对实例voxceleb_trainer多卡介绍 ...

  3. Kubeflow使用Kubernetes进行机器学习GPU分布式训练

    Kubeflow使用Kubernetes进行机器学习 Kubeflow是Google推出的基于kubernetes环境下的机器学习组件,通过Kubeflow可以实现对TFJob等资源类型定义,可以像部 ...

  4. GPU — 分布式训练

    目录 文章目录 目录 分布式训练的挑战 算法挑战 工程挑战 分布式范式 NCCL MPI 共享存储 分布式训练的挑战 算法挑战 数据并行或模型并行 同步或异步 批量较大,影响模型精度 热身,调整学习速 ...

  5. 『TensorFlow』分布式训练_其二_单机多GPU并行GPU模式设定

    建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...

  6. 分布式入门,怎样用PyTorch实现多GPU分布式训练

    这篇文章旨在阐述训练大规模深度学习模型时的分布式计算思想. 选自 Medium,作者:Ayan Das,机器之心编译,参与:Nurhachu Null.路. 具体来讲,本文首先介绍了分布式计算的基本概 ...

  7. 程序如何在两个gpu卡上并行运行_深度学习分布式训练相关介绍 - Part 1 多GPU训练...

    本篇文章主要是对深度学习中运用多GPU进行训练的一些基本的知识点进行的一个梳理 文章中的内容都是经过认真地分析,并且尽量做到有所考证 抛砖引玉,希望可以给大家有更多的启发,并能有所收获 介绍 大多数时 ...

  8. Pytorch:多块GPU分布式|并行训练

    分布式与并行训练的区别 分布式: 多台服务器上的多个GPU,分布式涉及了服务器之间的通信,因此比较复杂,PyTorch封装了相应的接口,可以用几句简单的代码实现分布式训练. 并行: 一台服务器上的多个 ...

  9. 快手八卦!突破TensorFlow、PyTorch并行瓶颈的开源分布式训练框架来了!

    来源:AI前线本文约5200字,建议阅读8分钟 本文介绍了专门针对分布式场景设计了特定的优化算法同比,性能较同类提升60%. 近日,快手和苏黎世理工宣布开源分布式训练框架 Bagua(八卦),相比于 ...

最新文章

  1. Redis源码学习-MasterSlave的命令交互
  2. matlab球面波衍射,单色点源矩孔菲涅耳衍射光场的计算与模拟
  3. 计算机七年级书籍段落,七年级下册片段.doc
  4. JAVA实现inotify一样的功能_WPF实现INotifyPropertyChanged
  5. 前端学习-flex布局
  6. android 贝塞尔曲线 波浪线,Android 贝塞尔曲线实现水纹波动效果
  7. 自驾游开什么车最靠谱?
  8. ArrayList 和 HaspMap 链式添加的实现
  9. leetcode-205-Isomorphic Strings
  10. linux获取cpu数量函数,Linux上获取CPU Core个数的实现
  11. qt信号槽踩坑日记(信号执行一次,槽函数执行多次解决方案)
  12. 为什么软件需要数字签名?代码签名证书的作用
  13. 操作系统实验ucore lab1
  14. msxml6_x86.msi和msxml6_ia64.msi和msxml6_x64.msi的选择
  15. nfc卡模式与标准模式_NFC是什么?有什么优势和劣势?
  16. java脚本错误修复,win10系统使用iE浏览器时不断出现Java活动脚本功能出错问题的操作技巧...
  17. 操作系统之Windows
  18. 8 9区别 endnote7_带鱼5-7和8-9的区别
  19. java计算机毕业设计中医药院校科研会议系统源码+数据库+系统+lw文档
  20. 立创开源 |ESP32-PICO-D4开发板

热门文章

  1. TG Pro使用教程 使用TG Pro的自定义控制功能完全覆盖系统的方法
  2. 商城项目(七)整合RabbitMQ实现延迟消息
  3. Java 实现文件拷贝粘贴
  4. android studio apk安装在模拟器可以通http获取数据;但安装在手机,就不能通过http获得数据
  5. 高山仰之可极,谈半同步/半异步网络并发模型
  6. 20几岁决定女人的一生
  7. TimeLine及Animation动画的坑
  8. 联想笔记本摄像头被禁用
  9. php养老院管理系统百度网盘_养老院智能化养老管理系统
  10. 响应式布局的简单案例演示