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

news2024/11/19 14:52:30

转载请注明出处:小锋学长生活大爆炸[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.coloradmin.cn/o/1899883.html

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

相关文章

Interview preparation--Https 工作流程

HTTP 传输的弊端 如上图,Http进行数据传输的时候是明文传输,导致任何人都有可能截获信息,篡改信息如果此时黑客冒充服务器,或者黑客窃取信息,则其可以返回任意信息给客户端,而且不被客户端察觉,…

力扣(3200)- 三角形的最大高度

好方法: 垃圾方法:

递归(三)—— 初识暴力递归之“字符串的全部子序列”

题目1 : 打印一个字符串的全部子序列 题目分析: 解法1:非递归方法 我们通过一个实例来理解题意,假设字符串str “abc”,那么它的子序列都有那些呢?" ", “a”, “b”,…

做有一个有表情且会动的 Finder

作为一只合格的互联网巡回猎犬,今天给大家分享一个有趣且无聊的小工具,摸鱼发呆必备,可以说是一件「无用良品」了。 软件介绍 Mouse Finder 长的跟访达差不多,功能也一样,但有一个重要区别:眼睛会跟随鼠标…

视频参考帧和重构帧复用

1、 视频编码中的参考帧和重构帧 从下图的编码框架可以看出,每编码一帧需要先使用当前帧CU(n)减去当前帧的参考帧CU(n)得到残差。同时,需要将当前帧的重构帧CU*(n)输出,然后再读取重构帧进行预测…

Linux存储管理I

存储管理I 一 .存储管理 主要知识点: 基本分区、逻辑卷LVM、EXT3/4/XFS文件系统、RAID 1.1.初识硬盘 机械 HDD(Hard Disk Drive) 固态 SSD(Solid State Drive):优点:读写速度快、防震抗摔性、低功耗、无噪音、工作温度范围大、轻便;缺点:容…

笔记:SpringBoot+Vue全栈开发2

笔记:SpringBootVue全栈开发2 1. MVVM模式2. Vue组件化开发3. 第三方组件element-ui的使用4. axios网络请求5. 前端路由VueRouter 1. MVVM模式 MVVM是Model-View-ViewModel的缩写,是一种基于前端开发的架构模式,其核心是提供对View和ViewMod…

Shopee(虾皮)怎么获取流量?

店铺流量的高低会直接关联到卖家店铺单量,也关系到一个店铺的营业情况和利润,那么Shopee的流量从哪里来呢? Shopee的平台流量可分为五个部分: 1.自然流量 2.关键字广告流量 3.平台活动流量 4.营销流量 5.粉丝流量 怎么提升…

Vue + SpringBoot:el-upload组件单文件、多文件上传实战解析

文章目录 单文件上传后端前端 多文件上传后端前端 单文件上传 后端 PostMapping("/uploadDxfFile") public R uploadDxfFile(RequestParam(value "file", required true) MultipartFile multipartFile) throws Exception {// 文件校验工作if (multipar…

类和对象深入理解

目录 static成员概念静态成员变量面试题补充代码1代码2代码3如何访问private中的成员变量 静态成员函数静态成员函数没有this指针 特性 友元友元函数友元类 内部类特性1特性2 匿名对象拷贝对象时的一些编译器优化 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接…

Qtgui编程基础

Qt简介 ( 框架5.9.8版本 ) Qt是源代码级的跨平台一次编写到处编译.一次开发的Qt应用程序可以移值到不同平台. Qt体系架构 Qt的整个设计都是以单根继承为主这跟java相同.所谓单根继承就是说所有的Qt类都有一个共同的祖先都是QObject类QObject类后面有三个大的子类分别负责不同…

厌倦了Nvim、vim等命令行编辑器?来看看新血脉....

是否厌倦了那几款烂大街的命令行风格编辑器?今天就来给各位换换血,介绍几个新成员。 让我们深入了解这些文本编辑器的主要功能和优点: 1. Ox Editor:优雅的新秀 Ox Editor是一款新兴的终端文本编辑器,以其简洁和优雅…

汽车IVI中控开发入门及进阶(三十三):i.MX linux开发之开发板

前言: 大部分物料/芯片,不管MCU 还是SoC,都会有原厂提供配套开发板,有这样一个使用原型,在遇到问题时或者进行开发时可以使用。 i.MX 8QuadXPlus MEK board: 1、要测试display显示器,可使用i.MX mini SAS将“LVDS1_CH0”端口连接到LVDS到HDMI适配器的cable。 2、要测试…

接口参数化--代码支撑参数

如果测试的用例里传动态参数,就需要把列出规则,然后在代码里运用前期是把动态参数都列出了,现在需要运用 步骤: 先excel表中定义规范,将请求参数里的时间戳定义规则(规范也需要提前写出) 建立…

库表设计(基础)-实体与设计关系

实体关系分析 1 实体关系是指系统事务之间的联系。 2 实体关系需要双向分析。 3 实体关系决定表关系。 实体关系的种类 1 一对一 2 一对多 3 多对多 举例: 上面关系如下: 班级和学生 : 1:N 学生和课程:N : N 学生和学籍档案&a…

【MotionCap】pycharm 远程在wsl2 ubuntu20.04中root的miniconda3环境

pycharm wsl2 链接到pycharmsbin 都能看到内容,/root 下内容赋予了zhangbin 所有,pycharm还是看不到/root 下内容。sudo 安装了miniconda3 引发了这些问题 由于是在 root 用户安装的miniconda3 所以安装路径在/root/miniconda3 里 这导致了环境也是root用户的,会触发告警 WA…

温州网站建设方案及报价

随着互联网的发展,网站建设已经成为企业推广和营销的重要手段。温州作为中国经济发达地区之一,各行各业企业纷纷意识到网站建设的重要性,纷纷加大网站建设工作的投入。那么,温州网站建设方案及报价是怎样的呢?下面我们…

昇思25天学习打卡营第10天|ResNet50迁移学习

文章目录 昇思MindSpore应用实践基于MindSpore的ResNet50迁移学习1、迁移学习简介2、加载ImageNet数据集数据集可视化 3、ResNet50 模型4、模型训练固定特征进行训练 5、模型推理 Reference 昇思MindSpore应用实践 本系列文章主要用于记录昇思25天学习打卡营的学习心得。 基于…

AI革命:RAG技术引领未来智能

AI革命:RAG技术引领未来智能 在人工智能的浪潮中,一种名为RAG(Retrieval-Augmented Generation)的技术正在悄然改变我们的世界。这种技术通过整合外部知识库,极大地增强了大型语言模型(LLM)的性能,为智能助手、聊天机器人等应用带来了革命性的提升。 1 突破性的RAG技…

迈威通信本安Wi-Fi 6工业无线AP系列,促进井下无线全覆盖

在现代化的工业生产中,无线通信技术的应用日益广泛。特别是对于矿井等复杂环境,传统的有线通信方式往往面临着布线困难、维护成本高、灵活性差等问题。为了解决这些难题,迈威通信推出了本安Wi-Fi 6工业无线AP系列,以其卓越的性能和…