位置: IT常识 - 正文

【已解决】探究CUDA out of memory背后原因,如何释放GPU显存?(想要探究的问题)

编辑:rootadmin
原力计划【已解决】探究CUDA out of memory背后原因,如何释放GPU显存? 目录1 问题背景2 问题探索2.1 CUDA固有显存2.2 显存激活与失活2.3 释放GPU显存3 问题总结4 告别Bug1 问题背景

推荐整理分享【已解决】探究CUDA out of memory背后原因,如何释放GPU显存?(想要探究的问题),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:想要探究的问题,写出你探究的结果,写出你探究的结果,探究结果怎么答,探究一下,写出你探究的结果,探究并解决问题的方法翻译,探究并解决问题的方法翻译,内容如对您有帮助,希望把文章链接给更多的朋友!

研究过深度学习的同学,一定对类似下面这个CUDA显存溢出错误不陌生

RuntimeError: CUDA out of memory. Tried to allocate 916.00 MiB (GPU 0; 6.00 GiB total capacity; 4.47 GiB already allocated; 186.44 MiB free; 4.47 GiB reserved in total by PyTorch)

本文探究CUDA的内存管理机制,并总结该问题的解决办法

2 问题探索2.1 CUDA固有显存

在实验开始前,先清空环境,终端输入nvidia-smi

接下来向GPU存入一个小的张量

import torchdevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')torch.randn((2, 3), device=device)

占用显存情况如下,共计448M

而当我们增大张量的尺寸,例如

torch.randn((200, 300, 200, 20), device=device)

此时GPU占用也随之上升,共计1362M

这表明:GPU显存占用率和存入的数据尺寸成正相关,越大的数据占用显存越多,这其实是废话,但是把这句话反过来:越小的数据占用显存越小吗?做个实验

torch.randn((1, 1), device=device)

仍然占用448M

事实上,这是因为CUDA运行时,其固件会占用一定的显存,在本机软硬件环境下是448M,不同的CUDA版本或显卡型号固件显存不同。换言之,只要使用了GPU,就至少会占xxx M的显存,且这部分显存无法被释放。

2.2 显存激活与失活

给出以下代码,请问哪一个会报错?

代码Ax1 = torch.randn((200, 300, 200, 20), device=device)x2 = torch.randn((200, 300, 200, 20), device=device)x3 = torch.randn((200, 300, 200, 20), device=device)x4 = torch.randn((200, 300, 200, 20), device=device)x5 = torch.randn((200, 300, 200, 20), device=device)x6 = torch.randn((200, 300, 200, 20), device=device)代码Bx = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)

答案可以猜到,代码A报错了,这与CUDA显存的激活机制有关。可以把CUDA当前的数据空间看成一个队列,队列中有两种内存——激活内存(Activate Memory)和失活内存(Unactivate Memory)。当一块内存不再被变量所引用时,这块内存就由激活内存转为失活内存,但它仍然存在于这个数据队列中。

接下来,一块新的数据被添加进来,CUDA就会释放掉一部分失活内存,用于存放新的数据。如果新的数据占用空间大于队列中的所有失活内存,就会从显存再申请一部分空间添加到队列,相当于队列的容量被扩充了;如果新的数据占用空间约等于队列中的失活内存,那么CUDA显存的占用率就几乎不变

可以实验验证,运行

x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300), device=device)【已解决】探究CUDA out of memory背后原因,如何释放GPU显存?(想要探究的问题)

的显存占用为1364M,与单独运行

x = torch.randn((200, 300, 200, 20), device=device)

的1362M相比差不多,但是新的数据占用空间大于队列中的所有失活内存时

x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((300, 300, 300, 20), device=device)

显存占用就飙升到3422M。当数据队列达到某个阈值时,CUDA会触发垃圾回收机制,清理失活内存。

上述实验解释了深度学习中非常常见的代码

for images, labels in train_bar:images, labels = images.to(config.device), labels.to(config.device)# 梯度清零opt.zero_grad()# 正向传播outputs = model(images)# 计算损失loss = F.cross_entropy(outputs, labels)# 反向传播loss.backward()# 模型更新opt.step()

为什么能维持GPU显存不变。本质上,这就是上面代码B的执行过程。

2.3 释放GPU显存

运行下面的命令可以手动清理GPU数据队列中的失活内存

torch.cuda.empty_cache()

需要注意的是,上述命令可能要运行多次才会释放空间,比如

x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = torch.randn((200, 300, 200, 20), device=device)x = 1

此时x指向了int型,所以GPU数据队列中的空间均未被变量引用,说明队列中全部都是失活内存,但此时运行nvidia-smi仍有2278M的占用,进一步运行torch.cuda.empty_cache()后即可恢复到448M的基础占用——虽然现在没有数据在GPU上,但固件已经开始运行,因此占用无法被释放。

3 问题总结

关于CUDA GPU显存管理的总结:

GPU显存占用率和存入的数据尺寸成正相关,越大的数据占用显存越多只要使用了GPU,就至少会占xxx M的显存,且这部分显存无法被释放当一块内存不再被变量所引用时,这块内存就由激活内存转为失活内存,但它仍然存在于这个数据队列中当数据队列达到某个阈值时,CUDA会触发垃圾回收机制,清理失活内存运行torch.cuda.empty_cache()可以手动清理失活内存

那么根据上述理论,就可以得到对应的问题解决方案

调小batch_size

本质上是防止GPU数据队列向显存申请的空间大于显存本身

检查是否有数据持续存入GPU而未释放

举个例子:

app = []for _ in range(1000):app.append(torch.randn((200, 300, 200, 20), device=device))

这里append函数相当于获得张量torch.randn((200, 300, 200, 20), device=device)的拷贝存入列表,因此每次存入的张量都会被隐式地引用,GPU持续地增加激活内存而不被释放,导致崩溃。

训练过程中的测试阶段和验证阶段前插入代码with torch.no_grad()

原理是不计算梯度,从而不用GPU加速运算,不会把数据再加到数据队列中

4 告别Bug

本文收录于《告别Bug》专栏,该专栏记录人工智能领域中各类Bug以备复查,文章形式为:问题背景 + 问题探索 + 问题解决,订阅专栏+关注博主后可通过下方名片联系我进入AI技术交流群帮忙解决问题


🔥 更多精彩专栏:

《ROS从入门到精通》《Pytorch深度学习实战》《机器学习强基计划》《运动规划实战精讲》…

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文链接地址:https://www.jiuchutong.com/zhishi/278092.html 转载请保留说明!

上一篇:Mac电脑登录支付宝无法输入密码的解决方法(苹果电脑付款方式设置)

下一篇:总结Linux中用于文本处理的awk、sed、grep命令用法(linux使用范围)

  • 华为电脑怎么开启小娜(华为电脑怎么开摄像头)

    华为电脑怎么开启小娜(华为电脑怎么开摄像头)

  • dns服务器是什么(DNS服务器是什么络好)

    dns服务器是什么(DNS服务器是什么络好)

  • OPPO Ace2的屏幕是多大(oppo ace2什么屏幕)

    OPPO Ace2的屏幕是多大(oppo ace2什么屏幕)

  • 小米一元流量怎么恢复(小米一元流量怎么不能用了)

    小米一元流量怎么恢复(小米一元流量怎么不能用了)

  • 100兆的宽带用多少兆的路由器(100兆的宽带用多少兆的光猫)

    100兆的宽带用多少兆的路由器(100兆的宽带用多少兆的光猫)

  • 控制器应该具有的功能(控制器的主要功能是进行)

    控制器应该具有的功能(控制器的主要功能是进行)

  • 质量更新和功能更新卸载哪个(质量更新和功能更新 驱动)

    质量更新和功能更新卸载哪个(质量更新和功能更新 驱动)

  • 麦克风阵列和麦克风区别(麦克风阵列和麦克风选哪个)

    麦克风阵列和麦克风区别(麦克风阵列和麦克风选哪个)

  • w10安全模式退出后无法上网(w10安全模式退出来就没有网了)

    w10安全模式退出后无法上网(w10安全模式退出来就没有网了)

  • 微信能边语音边录音吗(微信边语音边看视频对方听得到吗)

    微信能边语音边录音吗(微信边语音边看视频对方听得到吗)

  • qq相册可以存多少照片和视频(qq相册可以存多少g)

    qq相册可以存多少照片和视频(qq相册可以存多少g)

  • oppo手机黑名单在哪个里面找(oppo手机黑名单怎么移出来)

    oppo手机黑名单在哪个里面找(oppo手机黑名单怎么移出来)

  • vivo勿扰模式怎么关闭(vivo勿扰模式怎么收藏联系人)

    vivo勿扰模式怎么关闭(vivo勿扰模式怎么收藏联系人)

  • mate30防窥屏怎么设置(mate30ai防窥屏)

    mate30防窥屏怎么设置(mate30ai防窥屏)

  • 手机京东评价怎么删除(手机京东评价怎样删除)

    手机京东评价怎么删除(手机京东评价怎样删除)

  • 华为移动服务能卸载吗(华为移动服务是干什么的可以删除么)

    华为移动服务能卸载吗(华为移动服务是干什么的可以删除么)

  • oppok3有nfc功能吗(oppok3支不支持nfc)

    oppok3有nfc功能吗(oppok3支不支持nfc)

  • 三星s10支持wifi6吗(三星s10支持sd卡吗)

    三星s10支持wifi6吗(三星s10支持sd卡吗)

  • 阿里巴巴保证金怎么退回(阿里巴巴保证金交90还是3000)

    阿里巴巴保证金怎么退回(阿里巴巴保证金交90还是3000)

  • viv0y97指纹怎样设置(vivo x9指纹)

    viv0y97指纹怎样设置(vivo x9指纹)

  • 怎么看电话有没有被拉黑(怎么看电话有没有打出去)

    怎么看电话有没有被拉黑(怎么看电话有没有打出去)

  • Win10系统如何禁用光驱呢?(win10系统如何禁用驱动强制签名)

    Win10系统如何禁用光驱呢?(win10系统如何禁用驱动强制签名)

  • tracert命令的用法教程(tracert命令的用法)

    tracert命令的用法教程(tracert命令的用法)

  • 如何免费使用ChatGPT进行学术润色?你需要这些指令...(如何免费使用超级简历)

    如何免费使用ChatGPT进行学术润色?你需要这些指令...(如何免费使用超级简历)

  • 全国增值税发票服务平台
  • 设在西部地区的鼓励类产业企业减按15%怎么填
  • 暂时进出境货物和暂准进出境货物
  • 留抵退税手续
  • 非正常损失的货物,增值税做什么科目
  • 信息技术服务开票单位填什么
  • 无形资产界定标准
  • 企业政策性搬迁所得税
  • 售后维修费怎么开票
  • 库存现金限额一般由开户银行根据企业
  • 契税法律依据
  • 没有发票怎么报销入账
  • 开增值税票需要对方什么资料
  • 小额开专票
  • 所得税调增调减项目
  • 处置打包债权如何缴纳个人所得税?
  • 报销老板垫款会计处理
  • 一万元国债一年多少利息
  • 季报中现金流量表报的是当季的还是本年累计数
  • windows11永久解决蓝屏
  • 非一般纳税人可以抵扣吗
  • 出租其取得的不动产是什么意思
  • 股份有限公司变更法人的流程
  • 解决肚子胀气最快方法
  • 实际收到的货款怎么做账
  • 年底所得税账务处理
  • 银行存款缴纳房产税会计分录
  • php获取mysql数据
  • 控制器操作视频
  • 大语言模型集成工具
  • 知识图谱的构建方法有两种
  • 通过点击office文件按钮可以选择设置系统选项
  • python htmltestrunner报告
  • 房租费可以一次性摊销吗
  • 母公司的资质怎样才能转给子公司
  • mysql union or
  • mongodbwindows安装
  • sql数据库check 约束代码怎么设置
  • 差旅费报销相关政策
  • 收到的存款利息
  • SQL SERVER 2008 R2 重建索引的方法
  • ado连接access数据库
  • 金税盘地区编号怎么查
  • 一般纳税人的商业保险可以开票吗
  • 挂靠的项目如何做账?
  • 所得税季报季末从业人数
  • 公司注销清算时个人股东如何计算个人所得税
  • 不征税收入怎么申报增值税
  • 累计折旧需要分录吗
  • 发生销售折让的双方应做的会计分录是
  • 土地使用税退税怎么做会计分录
  • 一般纳税人销售旧货可以开专票吗
  • 免税收入计入起征点吗
  • 建筑业营改增后税率变化
  • mysql查询分组后 组内数据
  • mysql查询结果是什么类型
  • win7电脑一键关机快捷键
  • 在windows xp中说法正确的是
  • ubuntu下安装deb文件
  • linux中w命令详解
  • 局域网 打印机 共享
  • win7 显示日期
  • linux系统磁盘管理的主要内容
  • win8.1怎么关机
  • 下载手游网
  • cocos creatorapi
  • js 模拟滑动
  • html手机号验证
  • python module import
  • jquery 图片
  • javascript获取html元素的方法
  • js中concat的用法
  • javascript总结笔记
  • jquery attribute
  • python代码规范化
  • 出口退税报关单在哪里打印
  • 发票机怎么测试打印
  • 购销合同印花税的计税依据怎么算
  • 打税务局电话
  • 出口退税函调不予退税的后果
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设