摘要
问题描述:起服务时没有占用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 端口号