【CUDA OUT OF MEMORY】【Pytorch】计算图与CUDA OOM

news2024/9/25 3:26:16

计算图与CUDA OOM

在实践过程中多次碰到了CUDA OOM的问题,有时候这个问题是很好解决的,有时候DEBUG一整天还是头皮发麻。

最近实践对由于计算图积累导致CUDA OOM有一点新的看法,写下来记录一下。包括对计算图的一些看法和一个由于计算图引发错误的简化实例记录。

本人能力有限,认识片面如果犯了错误希望大家指教!

计算图的存储

计算图是pytorch进行梯度反向传播核心,计算图是在程序运行过程中动态产生的,当tensor变量赋予了requires_grad=True的属性时,torch会自动记录其参与的计算并形成计算图保存在显存中。

敲重点:计算图是会吃显存的! 本来想截下来描述一下计算图是长什么样的,至少是概念的表述一下,结果去学习了一圈发现:和我想的完全不一样!附上学习链接:传送门。更关键的是我还没完全看懂学会(🐶),有没有大大学会了教我一下,不甚感激!

总的来说一个tensor它内部包含的grad_fn别有洞天,首先grad_fn也是作为一个节点在计算图中的(其在pytorch的C艹中是Node的子类),grad_fn不仅是记录了这个tensor是被什么数学符号计算来的,它还暗搓搓记录了这个tensor是是从哪些数字里头窜出来的,以及其和其他grad_fn的py友谊,还有被包含在其内部context中的信息,我偷那个学习链接的一张图展示一下一个计算图的形态,借花献佛,展示一下grad_fn偷偷摸摸用你的卡干了啥事情。
在这里插入图片描述

BTW,提几个小知识点

  • 我们常用的detach()方法,就是通过把tensor的grad_fn扬了从而把tensor从计算图中剥离出来。
>>> x
tensor([1.], requires_grad=True)
>>> y = x+1
>>> y.grad_fn
<AddBackward0 object at 0x7f8306e68b50>
>>> y.detach().grad_fn is None
True
  • 关于*.backward(retain_graph=True)的问题,backwardretain_graph默认是False,其含义是经过默认的*.backward()之后,计算图会被清空从而释放其占用的显存。和detach不一样的是,grad_fn还是那个grad_fn只不过它悄咪咪维持的友谊被杀掉了,如下:
>>> x
tensor([1.], requires_grad=True)
>>> y = x+1; y.grad_fn
<AddBackward0 object at 0x7f8306e68b50>
>>> y.backward(retain_graph=False)
>>> y.grad_fn
<AddBackward0 object at 0x7f8306e68b50>
  • 续上面一点的内容,但是内容包含我瞎猜的成分(🐶),我们猜测一下backward杀掉了grad_fn的什么东西。一般的,我们认为当retain_graph=False的时候,我们只能backward()一次,因为计算图会被清空,第二次尝试反向传播会造成错误。但其实不然!如下实验例子1的尝试,我们连续backwrad并没有报错。AMAZING啊!。进一步的我们进行例子2的实验,我们只是简单的让前向多了一个乘法计算,然后另z反向传播两次,这回顺理成章的报错,同时报错之后我们再次反传y,我们发现反传y又不会报错。我猜测:backward()会清楚grad_fn节点和其他grad_fn的联系,因此zgrad_fn不能联系到ygrad_fn了,于是第二次z.backward()报错,但是y直接和叶子x连接,不需要其他的grad_fn朋友也能自己和自己玩。
例子1:
>>> x
tensor([1.], requires_grad=True)
>>> y = x+1
>>> y.backward(retain_graph=False);y.backward()
返回没有报错!
---------------------------------------------------------------
例子2:
>>> x
tensor([1.], requires_grad=True)
>>> y=x+1;z=2*y #前向过程多了一个乘法
>>> z.backward(retain_graph=False)
>>> z.backward()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/**/opt/anaconda3/lib/python3.8/site-packages/torch/_tensor.py", line 487, in backward
    torch.autograd.backward(
  File "/Users/**/opt/anaconda3/lib/python3.8/site-packages/torch/autograd/__init__.py", line 200, in backward
    Variable._execution_engine.run_backward(  # Calls into the C++ engine to run the backward pass
RuntimeError: Trying to backward through the graph a second time (or directly access saved tensors after they have already been freed). Saved intermediate values of the graph are freed when you call .backward() or autograd.grad(). Specify retain_graph=True if you need to backward through the graph a second time or if you need to access saved tensors after calling backward.
>>>y.backward()
返回没有报错

一个由于没处理好计算图导致OOM的例子

import torch,time
l1 = torch.nn.Linear(1000,1000).cuda()
l2 = torch.nn.Linear(1000,1000).cuda()
memory = []

for _ in range(10000000):
	time.sleep(0.01)
	data_input = torch.rand(1000).cuda()
	output = l1(l2(data_input))
	output.backward(retain_graph=True) #此行与报错无关 
	memroy.append(output.cpu()) 
	#memory存储的内容通过.cpu()转移在主存上,
	#但是与output相关联的l1,l2的计算图依旧停留在显存中,并在循环中一直积累撑爆显存。
	...some other operations...

这个例子中,由于每个output不能被正常清除计算图显存,最终导致OOM。

这个例子是某次实践的超级简化版,如果只看这个例子的话,其实只要把最后一行改写成

memory.append(output.detach().cpu())

就会由于output在每次循环后失去引用(detach()创建了新的变量)从而被回收,计算图被自动清空避免OOM。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/985745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小商户记账系统企业财务管理系统 uniapp微信小程序

本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言&#xff0c;应用ssm框架&#xff0c; MySQL为后台数据库。来完成对系统的设计。整个开发过程首先对小商户记账系统进行需求分析。 小商户记账系统小程序主要是为了提高用户…

炫酷的开关--20230907

Night && Day Toggle ☀️/&#x1f319; [Completed It!] HTML&#xff1a; <div class"controls"><label for"sync">Sync <body></label><input id"sync" type"checkbox"/> </div> &l…

四川玖璨电子商务有限公司:抖店怎么运营爆款

如今&#xff0c;随着网络的普及和电商平台的兴起&#xff0c;越来越多的人开始关注和尝试开设自己的网店。然而&#xff0c;在面对激烈的市场竞争中&#xff0c;如何让自己的抖店脱颖而出&#xff0c;成为爆款产品的运营者&#xff0c;是每个抖店经营者迫切需要解决的问题。 …

[PG]将一行数据打散成多行数据

原始数据 比如有如此表结构定义: 假如查询数据如下&#xff1a; select dt as "日期",bj_count as "北京", sh_count as "上海",gz_count as "广州", sz_count as "深圳" from city_stats order by dt--------------------…

Linux密码遗忘?别慌!解锁你的系统小秘籍!

很多朋友经常会忘记Linux系统的root密码&#xff0c;linux系统忘记root密码的情况该怎么办呢&#xff1f;重新安装系统吗&#xff1f;当然不用&#xff01;进入单用户模式更改一下root密码即可。 步骤如下&#xff1a; 重启linux系统 3 秒之内要按一下回车&#xff0c;出现如…

基于Java+SpringBoot+Vue前后端分离在线互动学习网站设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

LeetCode寻找两个有序数组的中位数打败100%人

&#x1f600;前言 在本文中&#xff0c;我们将深入研究一种复杂的算法问题&#xff1a;查找两个有序数组的中位数。这是一个经典的计算问题&#xff0c;通常出现在编程面试和算法挑战中。我们将首先探讨一种常见的暴力解决方法&#xff0c;然后逐步引入更高效的解决方案&#…

外滩大会今日开幕 生成式AI成为热议话题

2023 Inclusion外滩大会9月7日在上海黄浦世博园正式开幕。这场以“科技创造可持续未来”为主题的大会为期三天&#xff0c;近20位“两院”院士、诺贝尔奖和图灵奖得主&#xff0c;全球超500位有影响力的科技领军企业和专家学者&#xff0c;将在此带来一场科技、人文和产业的思想…

第5章 驱动模块传参实验(iTOP-RK3568开发板驱动开发指南 )

经过前两章实验的实战操作&#xff0c;我们已经完成最简单的helloworld驱动实验和模块驱动实验&#xff0c;加载模块可以使用“insmod”函数&#xff0c;使用“insmod”函数进行模块加载时也能进行参数的传递。运用得当可以极大提升内核测试速度。本节就来学习一下如何进行驱动…

Kafka入门与安装

为什么要用消息中间件&#xff1f; 异步处理 场景说明&#xff1a;用户注册后&#xff0c;需要发注册邮件和注册短信。传统的做法有两种1.串行的方式&#xff1b;2.并行方式。 串行方式&#xff1a;将注册信息写入数据库成功后&#xff0c;发送注册邮件&#xff0c;再发送注…

element-ui dialog弹窗 设置点击空白处不关闭

根据官网提供方法 场景&#xff1a;vue实现的网站有两个弹窗同时出现时&#xff0c;关闭报警&#xff0c;批量进度条弹窗也关闭了&#xff0c; 1、每一个页面都有可能出现的报警弹窗&#xff0c; 2、页面a批量操控硬件添加操作的进度条弹窗 开始以为是因为点击报警弹窗&#…

划片机实现装片、对准、切割、清洗到卸片的自动化操作

划片机是一种用于切割和分离材料的设备&#xff0c;通常用于光学和医疗、IC、QFN、DFN、半导体集成电路、GPP/LED氮化镓等芯片分立器件、LED封装、光通讯器件、声表器件、MEMS等行业。划片机可以实现从装片、对准、切割、清洗到卸片的自动化操作。 以下是划片机实现这些操作的步…

CSS 设置渐变背景 CSS 设置渐变边框

一、css渐变背景添加透明度opacity css渐变背景经常会在项目开发中遇到&#xff0c;此时UI如果给出的是单一的渐变背景&#xff08;没有背景透明度&#xff09;&#xff0c;这个我们会很快的写出代码&#xff0c;如下: <div class"btn">这是一个按钮</div&…

datagrip 相关数据连接信息无缝迁移

背景 因为公司换电脑了&#xff0c;接触的项目比较多&#xff0c;不同项目&#xff0c;不同环境的数据库连接有好几十个&#xff0c;如果在新电脑上挨个重新连接一遍劳心劳力&#xff0c;所以想看一下能不能直接将之前保存的连接信息直接迁移到新的电脑上面。 为此&#xff0c…

Apipost压测参数化如何使用

Apipost7.2.1版本一键压测新增参数化功能 如何使用&#xff1f; 这里我们用一个多用户登录情况来演示&#xff0c;需要准备包含用户名密码的CSV文件 创建CSV文件&#xff1a; 新建一个excel表格&#xff0c;在表格中新建username password&#xff0c;在下方输入每个账号和…

利用SoapIU工具生成webservice服务端java代码【二】

整理下今日使用SoapIU工具生成java代码的步骤&#xff0c;以axis2为例. 1.使用SoapUI&#xff0c;new SOAP Project 2.连接成功后&#xff0c;选择project&#xff0c;右键选择“Generate Code”&#xff0c;然后选择“Axis2”

java 整合 swagger-ui 步骤

1.在xml 中添加Swagger 相关依赖 <!-- springfox-swagger2 --><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><!-- springfox-swa…

2023年05月 C/C++(八级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;道路 N个以 1 … N 标号的城市通过单向的道路相连:。每条道路包含两个参数&#xff1a;道路的长度和需要为该路付的通行费&#xff08;以金币的数目来表示&#xff09; Bob and Alice 过去住在城市 1.在…

阿里云云主机免费试用三个月

试用链接如下&#xff1a; 阿里云云产品免费试用 云主机 费用试用三个月&#xff0c;每月750小时 实例规格 1核(vCPU) 2 GiB S6 系列机型 适用搭建网站等场景 网络带宽 1M 公网固定网络带宽 云盘40 GiB 真香&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

【经验分享】如何使用VSCode对比两个文件

问题&#xff1a; 当有两个不同版本的文件&#xff0c;如何使用VSCode对比两个文件 解决办法 长按ctrl选择想要对比的两个文件-----右键选择将已选项进行比较----大功告成 大功告成