pytorch 多GPU训练总结(DataParallel的使用)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40087578/article/details/87186613
这里记录用pytorch 多GPU训练 踩过的许多坑 仅针对单服务器多gpu 数据并行 而不是 多机器分布式训练
一、官方思路包装模型
这是pytorch 官方的原理图 按照这个官方的原理图 修改应该参照
https://blog.csdn.net/qq_19598705/article/details/80396325
上文也用dataParallel 包装了optimizer, 对照官方原理图中第二行第二个,将梯度分发出去,将每个模型上的梯度更新(第二行第三个),然后再将更新完梯度的模型参数合并到主gpu(第二行最后一个步骤)
其实完全没必要,因为每次前向传播的时候都会分发模型,用不着反向传播时将梯度loss分发到各个GPU,单独计算梯度,再合并模型。可以就在主GPU 上根据总loss 更新模型的梯度,不用再同步其他GPU上的模型,因为前向传播的时候会分发模型。
所以 上述链接里 不用 dataParallel 包装 optimizer。
DataParallel并行计算只存在在前向传播
总结步骤:
import os
import torch
args.gpu_id="2,7" ; #指定gpu id
args.cuda = not args.no_cuda and torch.cuda.is_available() #作为是否使用cpu的判定
#配置环境 也可以在运行时临时指定 CUDA_VISIBLE_DEVICES='2,7' Python train.py
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id #这里的赋值必须是字符串,list会报错
device_ids=range(torch.cuda.device_count()) #torch.cuda.device_count()=2
#device_ids=[0,1] 这里的0 就是上述指定 2,是主gpu, 1就是7,模型和数据由主gpu分发
if arg.cuda:
model=model.cuda() #这里将模型复制到gpu ,默认是cuda('0'),即转到第一个GPU 2
if len(device_id)>1:
model=torch.nn.DaraParallel(model);#前提是model已经.cuda() 了
#前向传播时数据也要cuda(),即复制到主gpu里
for batch_idx, (data, label) in pbar:
if args.cuda:
data,label= data.cuda(),label.cuda();
data_v = Variable(data)
target_var = Variable(label)
prediction= model(data_v,target_var,args)
#这里的prediction 预测结果是由两个gpu合并过的,并行计算只存在在前向传播里
#前向传播每个gpu计算量为 batch_size/len(device_ids),等前向传播完了将结果和到主gpu里
#prediction length=batch_size
criterion = nn.CrossEntropyLoss()
loss = criterion(prediction,target_var) #计算loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
之后调用model里的函数 继承的函数可以直接调用 例如 model.state_dict() ,model.load_state_dict(torch.load(model_path)......不受影响。但是自己写的函数 要加上.module才行 model.module.forward_getfeature(x)。自己写的函数 不可以并行运算 ,只能在主gpu中运算。DataParallel并行计算仅存在在前向传播。但可以换个思路 写进forward 里或者被forward调用,多返回几个参数不就得了 return feature,predict
二、解决多GPU 负载不均衡的问题
我的经历是主gpu 显存爆了,而其他gpu显存只用了1/5,负载不均衡到不能忍,无法再加大batch_size
参考:https://discuss.pytorch.org/t/dataparallel-imbalanced-memory-usage/22551/20(看了半天的英文才看懂。。。)
负载不均衡的原因是 loss = criterion(prediction,target_var) 计算loss 占用了大量的内存,如果我们让每个gpu单独计算loss,再返回即可解决这个问题 即 prediction,loss=model(data,target) (#如果后边不用prediction,连prediction也不用返回,只返回loss)。每个gpu返回一个loss,合到主gpu就是一个list,要loss.mean() 或loss.sum(),推荐mean.
这样以来,所有可以在其他gpu中单独计算的都可以写进forward 里,返回结果即可。但要注意 tensor类型的数组 合并len会增加,例如prediction lenth=batchsize,但是loss这种具体的数字,合并就是list了[loss1.loss2]
效果:主GPU 会稍微高一点。多个几百M, 但是基本实现了负载均衡
例子:
#model 里的forward 的函数
def forward(self,x,target_var,args):
feature512=self.forward_GetFeature(x)
if target_var is None:
return feature512;
classifyResult = self.classifier(feature512)
# 如果用DataParallel,forward返回feature 是返回多个GPU合并的结果
# 每个GPU 返回 batchsize/n 个样本,n为GPU数
#计算loss
center_loss = self.get_center_loss(feature512, target_var,args)
criterion = nn.CrossEntropyLoss()
cross_entropy_loss = criterion(classifyResult, target_var)
#CrossEntropyLoss 已经求了softmax 分类结果直接输进去即可
loss = args.center_loss_weight * center_loss + cross_entropy_loss
prec = accuracy(classifyResult.data, target_var, topk=(1,))
# 如果是返回的标量的话,那返回过去就是list,是n个GPU的结果
# 要loss.mean() 之后 在loss.backward()
return prec[0],loss
————————————————
版权声明:本文为CSDN博主「lllily」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40087578/article/details/87186613
pytorch 多GPU训练总结(DataParallel的使用)相关推荐
- pytorch 多GPU训练
pytorch 多GPU训练 pytorch多GPU最终还是没搞通,可用的部分是前向计算,back propagation会出错,当时运行通过,也不太确定是如何通过了的.目前是这样,有机会再来补充 p ...
- PyTorch 使用GPU训练
Pytorch 使用GPU训练 使用 GPU 训练只需要在原来的代码中修改几处就可以了. 我们有两种方式实现代码在 GPU 上进行训练 ## 方法一 .cuda() 我们可以通过对网络模型,数据,损失 ...
- pytorch指定GPU训练
主要讲单机多卡(单主机多GPUs训练) 使用多卡训练的方式有很多,当然前提是我们的设备中存在多个GPU:使用命令nvidia-smi查看当前Ubuntu平台的GPU数量,其中每个GPU被编上了序号:[ ...
- pytorch多GPU训练实例与性能对比
以下实验是我在百度公司实习的时候做的,记录下来留个小经验. 多GPU训练 cifar10_97.23 使用 run.sh 文件开始训练 cifar10_97.50 使用 run.4GPU.sh 开始训 ...
- pytorch 解决gpu训练只占一块卡
一:可以为不同的GPU分配不同的batch_size: 本文主要解决pytorch在进行模型训练时出现GPU的0卡占用显存比其他卡要多的问题. 出现0卡显存更高的原因:网络在反向传播的时候,计算los ...
- pytorch——多GPU训练,CPU测试出现的问题
我在训练模型的时候使用了nn.DataParallel,并在在服务器gpu测试也同时将训练好的模型并行载入,这样没有问题,但是我将训练好的模型在本地cpu运行的时候出错.这里记录出错的地方,并记录大致 ...
- 【Pytorch神经网络实战案例】01 CIFAR-10数据集:Pytorch使用GPU训练CNN模版-方法①
import torch import torchvision from torch import nn from torch.utils.tensorboard import SummaryWrit ...
- 【Pytorch神经网络实战案例】02 CIFAR-10数据集:Pytorch使用GPU训练CNN模版-方法②
import torch import torchvision from torch import nn from torch.utils.tensorboard import SummaryWrit ...
- 【Pytorch神经网络实战案例】03 CIFAR-10数据集:Pytorch使用GPU训练CNN模版-测试方法
import torch import torchvision from PIL import Image from torch import nnimage_path="./test_im ...
最新文章
- HDOJ 1233 还是畅通工程
- python考试报名官网安徽_今年优选:芜湖python
- STM32F1x 逆向工程初步
- php 使用webservice_PHP中如何调用webservice的实例参考
- mysql集群方案,保准看明白!
- Arcgis栅格时序地图制作---时间轴动态展示多期影像
- ActiveMQ_Linux安装
- [堆] Jzoj P5861 失意
- Kylo调研总结(一)
- Excel自动批量发邮件
- 无线网络dns服务器是多少,中国移动宽带dns是多少?
- 三维空间中鼠标点击选择线段的方法
- JAVA计算机毕业设计抑郁症患者博客交流平台Mybatis+源码+数据库+lw文档+系统+调试部署
- gitlab+drone+harbor之CI自动化流程
- 新浪微博图床架构解析
- 基于JavaWeb的校园故障报修系统(源码+数据脚本+论文+技术文档)
- 众享比特中标中电投电力工程有限公司区块链项目
- 数据库系统原理 - - (5)数据库编程
- php100漏洞,phpyun人才管理系统V5.0 SQL注入漏洞分析
- Linux-C TCP简单例子
热门文章
- Docker的安装、镜像源更换与简单应用
- 2022-2028年中国锂电池用聚烯烃隔膜行业市场发展调研及投资方向分析报告
- intellij idea 常见遇到的问题整理
- Python | 安装Jupyter Notebook及其目录的更改 jupyter问题
- LeetCode简单题之设计 Goal 解析器
- 最新Maven及Tomcat配置~(IDEA版 试错无数!)
- [C] 深度优先搜索解决连通块/染色问题——求岛的个数
- C++ 字符串字母大小写转换
- Python 实现九九乘法表
- HarmonyOS 使用DevEcoStudio创建一个xml布局以及引用布局