热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

pytorch显存一直变大的解决方案

这篇文章主要介绍了pytorch显存一直变大的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

在代码中添加以下两行可以解决:

torch.backends.cudnn.enabled = True
torch.backends.cudnn.benchmark = True

补充:pytorch训练过程显存一直增加的问题

之前遇到了爆显存的问题,卡了很久,试了很多方法,总算解决了。

总结下自己试过的几种方法:

**1. 使用torch.cuda.empty_cache()

在每一个训练epoch后都添加这一行代码,可以让训练从较低显存的地方开始,但并不适用爆显存的问题,随着epoch的增加,最大显存占用仍然会提示out of memory 。

2.使用torch.backends.cudnn.enabled = True 和 torch.backends.cudnn.benchmark = True

原理不太清楚,用法和1一样。但是几乎没有效果,直接pass。

3.最重要的:查看自己的forward函数是否存在泄露。

常需要在forward函数里调用其他子函数,这时候要特别注意:

input尽量不要写在for循环里面!!!

子函数里如果有append()等函数,一定少用,能不用就不用!!!

子函数list一定少用,能不用就不用!!!

总之,子函数一般也不会太复杂,直接写出来,别各种for,嵌套,变量。!!!

补充:Pytorch显存不断增长问题的解决思路

这个问题,我先后遇到过两次,每次都异常艰辛的解决了。

在网上,关于这个问题,你可以找到各种看似不同的解决方案,但是都没能解决我的问题。所以只能自己摸索,在摸索的过程中,有了一个排查问题点的思路。

下面举个例子说一下我的思路。

大体思路

其实思路很简单,就是在代码的运行阶段输出显存占用量,观察在哪一块存在显存剧烈增加或者显存异常变化的情况。

但是在这个过程中要分级确认问题点,也即如果存在三个文件main.py、train.py、model.py。

在此种思路下,应该先在main.py中确定问题点,然后,从main.py中进入到train.py中,再次输出显存占用量,确定问题点在哪。

随后,再从train.py中的问题点,进入到model.py中,再次确认。

如果还有更深层次的调用,可以继续追溯下去。

具体例子

main.py

def train(model,epochs,data):
    for e in range(epochs):
        print("1:{}".format(torch.cuda.memory_allocated(0)))
        train_epoch(model,data)
        print("2:{}".format(torch.cuda.memory_allocated(0)))
        eval(model,data)
        print("3:{}".format(torch.cuda.memory_allocated(0)))

假设1与2之间显存增加极为剧烈,说明问题出在train_epoch中,进一步进入到train.py中。

train.py

def train_epoch(model,data):
    model.train()
    optim=torch.optimizer()
    for batch_data in data:
        print("1:{}".format(torch.cuda.memory_allocated(0)))
        output=model(batch_data)
        print("2:{}".format(torch.cuda.memory_allocated(0)))
        loss=loss(output,data.target)
        print("3:{}".format(torch.cuda.memory_allocated(0)))
        optim.zero_grad()
        print("4:{}".format(torch.cuda.memory_allocated(0)))
        loss.backward()
        print("5:{}".format(torch.cuda.memory_allocated(0)))
        utils.func(model)
        print("6:{}".format(torch.cuda.memory_allocated(0)))

如果在1,2之间,5,6之间同时出现显存增加异常的情况。此时需要使用控制变量法,例如我们先让5,6之间的代码失效,然后运行,观察是否仍然存在显存爆炸。如果没有,说明问题就出在5,6之间下一级的代码中。进入到下一级代码,进行调试:

utils.py

def func(model):
print("1:{}".format(torch.cuda.memory_allocated(0)))
a=f1(model)
print("2:{}".format(torch.cuda.memory_allocated(0)))
b=f2(a)
print("3:{}".format(torch.cuda.memory_allocated(0)))
c=f3(b)
print("4:{}".format(torch.cuda.memory_allocated(0)))
d=f4(c)
print("5:{}".format(torch.cuda.memory_allocated(0)))

此时我们再展示另一种调试思路,先注释第5行之后的代码,观察显存是否存在先训爆炸,如果没有,则注释掉第7行之后的,直至确定哪一行的代码出现导致了显存爆炸。假设第9行起作用后,代码出现显存爆炸,说明问题出在第九行,显存爆炸的问题锁定。

几种导致显存爆炸的情况

pytorch的hook机制可能导致,显存爆炸,hook函数取出某一层的输入输出跟权重后,不可进行存储,修改等操作,这会造成hook不能回收,进而导致取出的输入输出权重都可能不被pytorch回收,所以模型的负担越来也大,最终导致显存爆炸。

这种情况是我第二次遇到显存爆炸查出来的,非常让人匪夷所思。在如下代码中,p.sub_(torch.mm(k, torch.t(k)) / (alpha + torch.mm(r, k))),导致了显存爆炸,这个问题点就是通过上面的方法确定的。

这个P是一个矩阵,在使用p.sub_的方式更新P的时候,导致了显存爆炸。

将这行代码修改为p=p-(torch.mm(k, torch.t(k)) / (alpha + torch.mm(r, k))),显存爆炸的问题解决。

  def pro_weight(p, x, w, alpha=1.0, cnn=True, stride=1):
                if cnn:
                    _, _, H, W = x.shape
                    F, _, HH, WW = w.shape
                    S = stride  # stride
                    Ho = int(1 + (H - HH) / S)
                    Wo = int(1 + (W - WW) / S)
                    for i in range(Ho):
                        for j in range(Wo):
                            # N*C*HH*WW, C*HH*WW = N*C*HH*WW, sum -> N*1
                            r = x[:, :, i * S: i * S + HH, j * S: j * S + WW].contiguous().view(1, -1)
                            # r = r[:, range(r.shape[1] - 1, -1, -1)]
                            k = torch.mm(p, torch.t(r))
                            p.sub_(torch.mm(k, torch.t(k)) / (alpha + torch.mm(r, k)))
                    w.grad.data = torch.mm(w.grad.data.view(F, -1), torch.t(p.data)).view_as(w)
                else:
                    r = x
                    k = torch.mm(p, torch.t(r))
                    p.sub_(torch.mm(k, torch.t(k)) / (alpha + torch.mm(r, k)))
                    w.grad.data = torch.mm(w.grad.data, torch.t(p.data))

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。


推荐阅读
  • 在 PyTorch 的 `CrossEntropyLoss` 函数中,当目标标签 `target` 为类别 ID 时,实际上会进行 one-hot 编码处理。例如,假设总共有三个类别,其中一个类别的 ID 为 2,则该标签会被转换为 `[0, 0, 1]`。这一过程简化了多分类任务中的损失计算,使得模型能够更高效地进行训练和评估。此外,`CrossEntropyLoss` 还结合了 softmax 激活函数和负对数似然损失,进一步提高了模型的性能和稳定性。 ... [详细]
  • 本文探讨了BERT模型在自然语言处理领域的应用与实践。详细介绍了Transformers库(曾用名pytorch-transformers和pytorch-pretrained-bert)的使用方法,涵盖了从模型加载到微调的各个环节。此外,还分析了BERT在文本分类、情感分析和命名实体识别等任务中的性能表现,并讨论了其在实际项目中的优势和局限性。 ... [详细]
  • 利用 PyTorch 实现 Python 中的高效矩阵运算 ... [详细]
  • 本文介绍了一款高效的开源OCR文本识别模型,结合了TextBoxes++和RetinaNet的优势。该模型在文本检测方面表现出色,适用于多种场景。项目代码已托管至GitHub,方便研究人员和开发者使用和改进。 ... [详细]
  • 在上一节中,我们完成了网络的前向传播实现。本节将重点探讨如何为检测输出设定目标置信度阈值,并应用非极大值抑制技术以提高检测精度。为了更好地理解和实践这些内容,建议读者已经完成本系列教程的前三部分,并具备一定的PyTorch基础知识。此外,我们将详细介绍这些技术的原理及其在实际应用中的重要性,帮助读者深入理解目标检测算法的核心机制。 ... [详细]
  • 在 PyTorch 中,`pin_memory` 技术用于锁定页面内存。当在创建 `DataLoader` 时将 `pin_memory` 参数设置为 `True`,这意味着生成的 Tensor 数据最初会被存储在锁定的内存中。这一技术能够显著提高数据从 CPU 到 GPU 的传输效率,从而加快训练速度。通过合理利用 `pin_memory`,可以有效减少数据加载的瓶颈,提升整体性能。 ... [详细]
  • 谷歌工程师:TensorFlow已重获新生;网友:我还是用PyTorch
    乾明发自凹非寺量子位报道|公众号QbitAI道友留步!TensorFlow已重获新生。在“PyTorch真香”的潮流中,有人站出来为TensorFlow说话了。这次来自谷歌的工程师 ... [详细]
  • 1.如何进行迁移 使用Pytorch写的模型: 对模型和相应的数据使用.cuda()处理。通过这种方式,我们就可以将内存中的数据复制到GPU的显存中去。 ... [详细]
  • 5.Numpy 索引(一维索引/二维索引)
    本文内容是根据莫烦Python网站的视频整理的笔记,笔记中对代码的注释更加清晰明了,同时根据所有笔记还整理了精简版的思维导图,可在此专栏查看,想观看视频可直接去他的网 ... [详细]
  • python教程分享Pytorchmlu 实现添加逐层算子方法详解
    目录1、注册算子2、算子分发3、修改opmethods基类4、下发算子5、添加wrapper6、添加wrapper7、算子测试本教程分享了在寒武纪设备上pytorch-mlu中添加 ... [详细]
  • [TensorFlow系列3]:初学者是选择Tensorflow2.x还是1.x? 2.x与1.x的主要区别?
    作者主页(文火冰糖的硅基工坊):https:blog.csdn.netHiWangWenBing本文网址:https:blog.csdn.netHiW ... [详细]
  • pytorch(网络模型训练)
    上一篇目录标题网络模型训练小插曲训练模型数据训练GPU训练第一种方式方式二:查看GPU信息完整模型验证网络模型训练小插曲区别importtorchatorch ... [详细]
  • 一、Transorboard使用(可视化工具)(观察模型不同阶段的数据状况)fromtorch.utils.tensorboardimportSummaryWriterfromPI ... [详细]
  • CBAM:卷积块注意模块
    CBAM:ConvolutionalBlockAttentionModule论文地址:https:arxiv.orgabs1807.06521简介:我们提出了 ... [详细]
  • 1.首先在终端中输入python进入python交互式环境2.接着输入 importtorch print(torch.__version__)#注意是 ... [详细]
author-avatar
幽灵-玲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有