码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • python通过导入自定义dll实现显存释放


    博主研究了很多python的代码,发现都是无法释放显存的,或者说是释放显存不彻底。为此实现了自定义dll库,由python调用实现了释放显存。支持pytorch、tensorflow、onnxruntime等cuda运行环境,其运行效果与ai框架无关,由cuda C++ API决定。其中,自定义dll库导出给python使用可以参考vs2019导出动态链接库(dll)给其他vs项目及python代码使用_万里鹏程转瞬至的博客-CSDN博客通过vs可以导出动态链接库(dll文件)给其他c++项目、c#项目、python项目使用。本案例实现将vs项目导出为动态链接库,给c++项目与python项目使用。涉及全局变量、函数、自定义类的导出。项目创建完成后会得到以下结构, 可以将核心代码写在dllmain.cpp里面(原先的内容可以不用管),头文件信息写入在pch.h里面以下内容可以全部拷贝到pch.h中(博主的代码涉及到了cuda,所以需要配置以下cuda,cuda的配置可以参考libtorch显存管理示例_万里鹏程转瞬至的博客-CSDN博客,各https://hpg123.blog.csdn.net/article/details/125396626

    下面代码中所用到的dll文件可以在以下链接下载,也可以参考上述链接自行实现。

    python释放cuda缓存库-深度学习文档类资源-CSDN下载博主自行实现的动态链接库,通过python导入后可以实现释放显存,与ai框架无关。支持pytorch更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/a486259/85725926

     1、导入dll库

    这些要调用cuda,因此电脑需配置好cuda环境。同时,注意按照自己的实际情况修改dll文件的路径。此外,代码用到了pynvml进行显存查询,如果电脑没有安装请用 pip install pynvml  进行安装。

    1. import ctypes
    2. import os
    3. import pynvml
    4. pynvml.nvmlInit()
    5. def get_cuda_msg(tag=""):
    6. handle = pynvml.nvmlDeviceGetHandleByIndex(0)
    7. meminfo = pynvml.nvmlDeviceGetMemoryInfo(handle)
    8. print(tag, ", used:",meminfo.used / 1024**2,"Mib","free:",meminfo.free / 1024**2,"Mib")
    9. #os.environ['Path']+=r'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin'
    10. #python3.7版本以上使用下列代码添加依赖项dll的路径
    11. os.add_dll_directory(r'C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\bin')
    12. lib = ctypes.cdll.LoadLibrary(os.getcwd()+ "/dll_export.dll")
    13. #win32api.FreeLibrary(libc._handle) #发现程序运行结束时无法正常退出dll,需要显式释放dll
    14. #lib.reset_cuda()

    2、搭建pytorch模型

    这里所搭建的模型只是一个demo,没有任何的实际意义,各位可以使用自己的模型和框架。

    1. import torch
    2. import torch.nn as nn
    3. import torch.nn.functional as F
    4. class MyModel(nn.Module):
    5. def __init__(self):
    6. super(MyModel, self).__init__()
    7. self.conv1 = nn.Conv2d(6, 256, kernel_size=3, stride=1, padding=0)
    8. self.relu = nn.ReLU()
    9. self.conv2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=0)
    10. self.conv3 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=0)
    11. self.conv4 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=0)
    12. self.conv5 = nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=0)
    13. self.conv61 = nn.Conv2d(512, 3, kernel_size=3, stride=1, padding=0)
    14. self.conv62 = nn.Conv2d(512, 3, kernel_size=3, stride=1, padding=0)
    15. self.global_pooling = nn.AdaptiveAvgPool2d(output_size=(1, 1))
    16. #假设x1与x2的通道数均为3
    17. def forward(self, x1, x2):
    18. x = torch.cat([x1, x2], dim=1)
    19. x = self.conv1(x)
    20. x = self.conv2(x)
    21. x = self.conv3(x)
    22. x = self.conv4(x)
    23. x = self.conv5(x)
    24. x1= self.conv61(x)
    25. x2= self.conv62(x)
    26. x1 = self.global_pooling(x1).view(-1)
    27. x2 = self.global_pooling(x2).view(-1)
    28. x1 = F.softmax(x1,dim=0)
    29. x2 = F.softmax(x2,dim=0)
    30. return x1,x2

    3、显存释放管理

    代码及运行结果如下所示,包含模型初始化、变量初始化、forword后、del变化后、显存释放后(reset_cuda)5个状态前后的显存变化。可以看到调用lib.reset_cuda后显存基本上已经恢复。

    1. get_cuda_msg("Context start")
    2. model=MyModel().cuda()
    3. get_cuda_msg("\n init model")
    4. x1=torch.ones((10,3,256,256)).cuda()
    5. x2=torch.ones((10,3,256,256)).cuda()
    6. get_cuda_msg("\n init input")
    7. model.forward(x1,x2)
    8. get_cuda_msg("\n finish forward")
    9. del x1,x2,model
    10. get_cuda_msg("\n delete variable and model")
    11. lib.reset_cuda()
    12. get_cuda_msg("\n lib.reset_cuda()")

  • 相关阅读:
    HttpServletRequest接口详解
    Flask部署pytorch服务
    从0搭建Vue3组件库(六):前端流程化控制工具gulp的使用
    Python中的装饰器(Decorator)
    git常用命令以及常见错误处理
    二元分类模型评估方法
    刚刚,百度真来炸场了!
    视觉享受,兼顾人文观感和几何特征的字体「GitHub 热点速览 v.22.46」
    国际结算模拟试题及答案
    SpringDoc基础配置和集成OAuth2登录认证教程
  • 原文地址:https://blog.csdn.net/a486259/article/details/125397433
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号