【踩坑】探究PyTorch中创建稀疏矩阵的内存占用过大的问题

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn]

如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~


目录

问题复现

原因分析

解决方案

碎碎念


问题复现

        创建一个COO格式的稀疏矩阵,根据计算公式,他应该只占用约5120MB的内存:

        但通过nvidia-smi查看,实际上占用了10240MB:

        网上对此的讨论又是没有找到,只好又是自己一点点摸索。

原因分析

        对于CUDA的内存问题,那就可以使用torch.cuda.memory_stats()来看他的内存使用情况:

coo_matrix = sparse_matrix.to_sparse_coo()
print(torch.cuda.memory_stats())

        输出结果:

OrderedDict([('active.all.allocated', 24), ('active.all.current', 6), ('active.all.freed', 18), ('active.all.peak', 8), ('active.large_pool.allocated', 11), ('active.large_pool.current', 6), ('active.large_pool.freed', 5), ('active.large_pool.peak', 8), ('active.small_pool.allocated', 13), ('active.small_pool.current', 0), ('active.small_pool.freed', 13), ('active.small_pool.peak', 2), ('active_bytes.all.allocated', 15313152512), ('active_bytes.all.current', 8598454272), ('active_bytes.all.freed', 6714698240), ('active_bytes.all.peak', 13967163392), ('active_bytes.large_pool.allocated', 15312696832), ('active_bytes.large_pool.current', 8598454272), ('active_bytes.large_pool.freed', 6714242560), ('active_bytes.large_pool.peak', 13967163392), ('active_bytes.small_pool.allocated', 455680), ('active_bytes.small_pool.current', 0), ('active_bytes.small_pool.freed', 455680), ('active_bytes.small_pool.peak', 80896), ('allocated_bytes.all.allocated', 15313152512), ('allocated_bytes.all.current', 8598454272), ('allocated_bytes.all.freed', 6714698240), ('allocated_bytes.all.peak', 13967163392), ('allocated_bytes.large_pool.allocated', 15312696832), ('allocated_bytes.large_pool.current', 8598454272), ('allocated_bytes.large_pool.freed', 6714242560), ('allocated_bytes.large_pool.peak', 13967163392), ('allocated_bytes.small_pool.allocated', 455680), ('allocated_bytes.small_pool.current', 0), ('allocated_bytes.small_pool.freed', 455680), ('allocated_bytes.small_pool.peak', 80896), ('allocation.all.allocated', 24), ('allocation.all.current', 6), ('allocation.all.freed', 18), ('allocation.all.peak', 8), ('allocation.large_pool.allocated', 11), ('allocation.large_pool.current', 6), ('allocation.large_pool.freed', 5), ('allocation.large_pool.peak', 8), ('allocation.small_pool.allocated', 13), ('allocation.small_pool.current', 0), ('allocation.small_pool.freed', 13), ('allocation.small_pool.peak', 2), ('inactive_split.all.allocated', 3), ('inactive_split.all.current', 1), ('inactive_split.all.freed', 2), ('inactive_split.all.peak', 2), ('inactive_split.large_pool.allocated', 1), ('inactive_split.large_pool.current', 1), ('inactive_split.large_pool.freed', 0), ('inactive_split.large_pool.peak', 1), ('inactive_split.small_pool.allocated', 2), ('inactive_split.small_pool.current', 0), ('inactive_split.small_pool.freed', 2), ('inactive_split.small_pool.peak', 1), ('inactive_split_bytes.all.allocated', 20376064), ('inactive_split_bytes.all.current', 12451840), ('inactive_split_bytes.all.freed', 7924224), ('inactive_split_bytes.all.peak', 14548480), ('inactive_split_bytes.large_pool.allocated', 15808000), ('inactive_split_bytes.large_pool.current', 12451840), ('inactive_split_bytes.large_pool.freed', 3356160), ('inactive_split_bytes.large_pool.peak', 12451840), ('inactive_split_bytes.small_pool.allocated', 4568064), ('inactive_split_bytes.small_pool.current', 0), ('inactive_split_bytes.small_pool.freed', 4568064), ('inactive_split_bytes.small_pool.peak', 2096640), ('max_split_size', -1), ('num_alloc_retries', 0), ('num_ooms', 0), ('oversize_allocations.allocated', 0), ('oversize_allocations.current', 0), ('oversize_allocations.freed', 0), ('oversize_allocations.peak', 0), ('oversize_segments.allocated', 0), ('oversize_segments.current', 0), ('oversize_segments.freed', 0), ('oversize_segments.peak', 0), ('requested_bytes.all.allocated', 15313145274), ('requested_bytes.all.current', 8598453372), ('requested_bytes.all.freed', 6714691902), ('requested_bytes.all.peak', 13967161592), ('requested_bytes.large_pool.allocated', 15312695031), ('requested_bytes.large_pool.current', 8598453372), ('requested_bytes.large_pool.freed', 6714241659), ('requested_bytes.large_pool.peak', 13967161592), ('requested_bytes.small_pool.allocated', 450243), ('requested_bytes.small_pool.current', 0), ('requested_bytes.small_pool.freed', 450243), ('requested_bytes.small_pool.peak', 80000), ('reserved_bytes.all.allocated', 14250147840), ('reserved_bytes.all.current', 14250147840), ('reserved_bytes.all.freed', 0), ('reserved_bytes.all.peak', 14250147840), ('reserved_bytes.large_pool.allocated', 14248050688), ('reserved_bytes.large_pool.current', 14248050688), ('reserved_bytes.large_pool.freed', 0), ('reserved_bytes.large_pool.peak', 14248050688), ('reserved_bytes.small_pool.allocated', 2097152), ('reserved_bytes.small_pool.current', 2097152), ('reserved_bytes.small_pool.freed', 0), ('reserved_bytes.small_pool.peak', 2097152), ('segment.all.allocated', 10), ('segment.all.current', 10), ('segment.all.freed', 0), ('segment.all.peak', 10), ('segment.large_pool.allocated', 9), ('segment.large_pool.current', 9), ('segment.large_pool.freed', 0), ('segment.large_pool.peak', 9), ('segment.small_pool.allocated', 1), ('segment.small_pool.current', 1), ('segment.small_pool.freed', 0), ('segment.small_pool.peak', 1)])

        这里快速推进。实际上我们只需要看reserved_bytes和active_bytes。其中,active_bytes.all.current 表示当前正在使用的所有活跃内存总量。在输出中,这个值为 8598454272 字节,约等于 8192 MBreserved_bytes.all.current 表示当前已保留的所有内存总量。在输出中,这个值为 14250147840 字节,约等于 13595 MB

        因此,很明显这多出来的内存占用,实际上是reserved_bytes搞的

  • 活跃内存(Active Memory):指当前正在使用的显存量,包括已经分配并且正在使用的内存。
  • 保留内存(Reserved Memory):指已经分配但尚未使用的显存量。这些内存空间可能会被保留以备将来使用,或者是由于内存碎片而导致的无法立即分配给新的内存请求。总的来说,保留的所有内存总量是由系统根据实时的内存使用情况和策略进行动态调整和触发的。它的目的是优化内存的分配和释放,以提高系统的性能和稳定性。

解决方案

        知道了原因,那么就很好处理了。我们可以通过torch.cuda.empty_cache()清空缓存来删掉这部分保留的内存:

coo_matrix = sparse_matrix.to_sparse_coo()
print('memory_allocated: ', torch.cuda.memory_allocated())
print('memory_reserved: ', torch.cuda.memory_reserved())
torch.cuda.empty_cache()
print('empty_cache done!')
print('memory_allocated: ', torch.cuda.memory_allocated())
print('memory_reserved: ', torch.cuda.memory_reserved())

输出:

memory_allocated:  8598454272
memory_reserved:  14250147840
empty_cache done!
memory_allocated:  8598454272
memory_reserved:  8613003264

        可以看到已经成功删除了多的部分。


碎碎念

        1、可能还有其他方法,欢迎评论讨论~

        2、如果不是后面不会再有GPU内存申请了,这个保留内存实际还是建议保留的。比如以下这个连续创建矩阵的,那么在创建第二个矩阵的时候,就不会再去申请新的内存,而是会放在保留内存里。因此这样会更高效一点:

A = create_dense_matrix(size, device=env.device)
B = create_dense_matrix(size, device=env.device)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go zero入门

一、goctl安装 goctl 是 go-zero 的内置脚手架,可以一键生成代码、文档、部署 k8s yaml、dockerfile 等。 # Go 1.16 及以后版本 go install github.com/zeromicro/go-zero/tools/goctllatest检查是否安装成功 $ goctl -v goctl version 1.6.6 darwin/amd64vscod…

通过SDK使用百度智能云的图像生成模型SDXL

登录进入百度智能云控制台,在模型广场按照图像生成类别进行筛选,可以找到Stable-Diffusion-XL模型。点击Stable-Diffusion-XL模型的API文档后在弹出的新页面下拉可以找到SDK调用的说明。 import qianfandef sdxl(file: str, prompt: str, steps: int 2…

C语言_练习题

求最小公倍数 思路:假设两个数,5和7,那么最小至少也要7吧,所以先假定最小公倍数是两个数之间较大的,然后看7能不能同时整除5和7,不能就加1继续除 int GetLCM(int _num1, int _num2) {int max _num1>_n…

堆叠的作用

一、为什么要堆叠 传统的园区网络采用设备和链路冗余来保证高可靠性,但其链路利用率低、网络维护成本高,堆叠技术将多台交换机虚拟成一台交换机,达到简化网络部署和降低网络维护工作量的目的。 二、堆叠优势 1、提高可靠性 堆叠系统多台成…

25款404网页源码(下)

25款404网页源码(下) 13部分源码 14部分源码 15部分源码 16部分源码 17部分源码 18部分源码 19部分源码 20部分源码 21部分源码 22部分源码 23部分源码 24部分源码 25部分源码 领取完整源码下期更新 13 部分源码 .rail {position: absolute;width: 100%…

Node.js-path 模块

path 模块 path 模块提供了 操作路径 的功能,如下是几个较为常用的几个 API: 代码实例: const path require(path);//获取路径分隔符 console.log(path.sep);//拼接绝对路径 console.log(path.resolve(__dirname, test));//解析路径 let pa…

Docker搭建MySQL双主复制详细教程

在此之前需要提前安装好Docker和 Docker Compose 。 一、创建目录 首先创建一个本地数据挂载目录。 mkdir -p master1-data master2-data二、编写docker-compose.yml version: 3.7services:mysql-master1:image: mysql:5.7.36container_name: mysql-master1environment:MYSQL_…

mac|idea导入通义灵码插件

官方教程:通义灵码下载安装指南_智能编码助手_AI编程_云效(Apsara Devops)-阿里云帮助中心 下载插件: ⇩ TONGYI Lingma - JetBrains 结果如下: 选择apply、ok,会出现弹窗,点击登录 可以实现:生成单元测…

FRP反向隧道代理打CFS三层

目录 攻击机 查看服务端frps.ini配置文件 开启服务端frps 蚁剑打目标机 上传客户端frp到目标机 ​frpc.ini文件配置成 客户端打开代理frpc vps显示成功客户端frpc打开 访问成功192.168.22.22的第二层内网主机 省去前面漏洞利用的rce过程,直接蚁剑开搞隧道…

如何使用VScode创建和上传Arduino项目

Visual Studio Code (VS Code) 是一种非常流行的通用集成开发环境 (IDE)。IDE 是一种将文本编辑器、编程界面、调试视图和项目管理集成在一个地方的软件。这个开源项目由微软领导,可以在所有操作系统上运行。使 VS Cod…

深度解析Ubuntu版本升级:LTS版本升级指南

深度解析Ubuntu版本升级:Ubuntu版本生命周期及LTS版本升级指南 Ubuntu是全球最受欢迎的Linux发行版之一,其版本升级与维护策略直接影响了无数用户的开发和生产环境。Canonical公司为Ubuntu制定了明确的生命周期和发布节奏,使得社区、企业和开…

宿舍报修小程序的设计

管理员账户功能包括:系统首页,个人中心,管理员管理,基础数据管理,论坛管理,故障上报管理,新闻信息管理,维修人员管理 微信端账号功能包括:系统首页,新闻信息…

C++ 视觉开发 六.特征值匹配

以图片识别匹配的案例来分析特征值检测与匹配方法。 目录 一.感知哈希算法(Perceptual Hash Algorithm) 二.特征值检测步骤 1.减小尺寸 2.简化色彩 3.计算像素点均值 4.构造感知哈希位信息 5.构造一维感知哈希值 三.实现程序 1.感知哈希值计算函数 2.计算距离函数 3…

CTF入门知识点

CTF知识点 md5函数 <?php$a 123;echo md5($a,true); ?> 括号中true显示输出二进制 替换成false显示输出十六进制绕过 ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c&#xff0c;这个字符串前几位刚好是 or 6 而 Mysql 刚好又会把 …

分支与循环

目录 1. if语句 1&#xff09;if 2) else 3&#xff09;分支中包含多条语句 4&#xff09;if嵌套 2.关系操作符 3.条件操作符 4.逻辑操作符&#xff1a;&& || ! 1) 逻辑取反运算符 !​编辑 2 与运算符​编辑 3) 或运算符​编辑 4) 闰年的判断 5) 短路 …

一行代码用git新建分支

1.在本地创建分支 dev git branch dev2.切换分支 git checkout devwebstorm操作如下&#xff1a; 3.推送新分支到远程 git push --set-upstream origin 分支名webstorm操作如下&#xff1a;提交代码的时候会自动推送到远程 4.到git上面可以看看刚刚推送的内容 dev多推送…

MacOS miniconda安装方法

打开macos “终端” 应用 执行命令 mkdir -p ~/miniconda3curl https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o ~/miniconda3/miniconda.shbash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3rm -rf ~/miniconda3/mini…

Java项目:基于SSM框架实现的智慧城市实验室管理系统分前后台【ssm+B/S架构+源码+数据库+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的智慧城市实验室管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单…

golang与以太坊交互

文章目录 golang与以太坊交互什么是go-ethereum与节点交互前的准备使用golang与以太坊区块链交互查询账户的余额使用golang生成以太坊账户使用golang生成以太坊钱包使用golang在账户之间转移eth安装使用solc和abigen生成bin和abi文件生成go文件使用golang在测试网上部署智能合约…

RK3588 Android12实现UVC输出功能详解

首先需要在相关部分添加uvc的功能&#xff0c;这里参考一下&#xff1a;rockchip rk3588添加uvc及uvc,adb的复合设备_uvc.gs6-CSDN博客 setprop sys.usb.config none;setprop sys.usb.config uvc 或者setprop sys.usb.config none;setprop sys.usb.config uvc,adb 使rk3588 进…