GPU资源释放

摘要

问题描述:起服务时没有占用gpu资源,但是程序执行一次后存在线程占用gpu显存的问题

解决方案一:手动释放gpu资源(未解决)

torch.cuda.empty_cache()

解决方案二:升高scikit-learn版本,以为是版本较低设置n_jobs造成的,但应该不是(未解决)

解决方案三:不确定是否为异步程序造成,修改异步程序,异步从方案一修改到方案二(未解决)

python异步执行

异步方案一:装饰器

from threading import Thread

def async(f):
    def wrapper(*args, **kwargs):
        thr = Thread(target=f, args=args, kwargs=kwargs)
        thr.start()
    return wrapper

@async   
def restart_fun():  # 需要异步执行的方法
    pass

异步方案二:线程池

from concurrent.futures import ThreadPoolExecutor

thread_pool = ThreadPoolExecutor(2)

def exception_callback(fur):
    if fur.exception() != None:  # 若线程正常退出,返回None
        logging.error(fur.result())  # 判断是否存在异常,存在则打印返回的值

def wait_f():
    fur = thread_pool.submit(restart_fun,)  # restart_fun为需要异步执行的方法
    fur.add_done_callback(exception_callback)

wait_f() 

方案一和方案二是启了一个子进程,所以会显存会释放不掉

方案三是方案二的改进版本:使用os.system启了一个进程。bingo

import os
from concurrent.futures import ThreadPoolExecutor

thread_pool = ThreadPoolExecutor(2)

def exception_callback(fur):
    if fur.exception() != None:  # 若线程正常退出,返回None
        logging.error(fur.result())  # 判断是否存在异常,存在则打印返回的值

def restart_fun(a, b):
    os.system("python xxx.py %s %s" % (a, b))

def wait_f(a, b):
    fur = thread_pool.submit(restart_fun, a, b)
    fur.add_done_callback(exception_callback)

wait_f(a, b) 

# 如果有参数,一下为xxx.py代码文件
# ......
if __name__ == "__main__":
    import sys
    a = sys.argv[1]
    b = sys.argv[2]
    fun(a, b)

方案三在进程结束时会释放gpu资源,但在执行过程中会遇到一个问题,import numpy要在import torch之前,否则会报一下错误。

Error: mkl-service + Intel(R) MKL: MKL_THREADING_LAYER=INTEL is incompatible with libgomp-7c85b1e2.so.1 library.
Try to import numpy first or set the threading layer accordingly. Set MKL_SERVICE_FORCE_INTEL to force it.

使用的查看gpu和进程的linux命令

nvidia-smi
fuser -v /dev/nvidia*
ps -ef | grep 端口号