pytorch中使用cuda进行多任务multiprocessing

我们都知道python有自带的multiprocessing模块,但是如果要使用cuda的话会报错:

RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method

但是查找torch中spawn,查找到torch.multiprocessing.spawn,所得的介绍并不多而且网上搜到的都是抄这个说明书的

仔细阅读torch.multiprocessing的英文解释发现这个部分就是把python的官方multiprocessing给wrap(包)了一下,所以之前的应该都能用,因此我之前的pool代码可以直接使用

原来spawn的方法只是一种多任务的方法

spawn

父进程启动一个新的Python解释器进程。子进程只会继承那些运行进程对象的 run() 方法所需的资源。特别是父进程中非必须的文件描述符和句柄不会被继承。相对于使用 fork 或者 forkserver,使用这个方法启动进程相当慢。

只需要设定context为"spawn”即可,但是,如果直接使用

torch.multiprocessing.set_start_method("spawn")

会出bug:

RuntimeError('context has already been set')

查找stackflow中可以找到一位仁兄,跟我做的事情还差不多,都是pytorch想要多任务

https://github.com/pytorch/pytorch/issues/3492

从里边我使用的一种方法成功了,就是这个

I found a solution, which is to use a context object in multiprocessing.

ctx = multiprocessing.get_context("spawn")

And then replace multiprocessing.xxx with ctx.xxx.

我最终的代码为

def func(a,b,c):
    return {"a":a,"b":b,"c":c}


def func2():

        ctx = torch.multiprocessing.get_context("spawn")
        print(torch.multiprocessing.cpu_count())
        pool = ctx.Pool(5) # 7.7G



        pool_list = []

        for XX:
            for XXX:
                for XXX:


                    res = pool.apply_async(func, args=(a,b,c))
                    pool_list.append(res)

        pool.close()  # 关闭进程池,不再接受新的进程
        pool.join()  # 主进程阻塞等待子进程的退出
        ccc = pd.DataFrame(columns=["a", "b", "c"])
        for i in pool_list:
            data = i.get()
            ccc = ccc.append(data, ignore_index=True)

 只是一个示意,供大家参考!

注意应该合理选择pool的worker个数,我这里是五个,然后使用了大约7.7G的显存。如果直接使用cpu_count()就是24个,显存直接爆掉。在实验的时候要使用如下代码来监视gpu使用情况:

watch -n 0.1 nvidia-smi

感谢您的阅读!

PyTorch中,`torch.multiprocessing.spawn` 是一个多进程的工具,用于创建和管理多个进程。这个函数是用来替代 Python 标准库中的 `multiprocessing` 模块的。以下是如何正确使用 `torch.multiprocessing.spawn` 创建和管理多个进程的基本步骤: 1. **定义函数**: 首先,需要定义一个函数,该函数是每个进程将要执行的任务。这个函数应当接收一个进程索引参数。 2. **使用 spawn 方法**: 使用 `torch.multiprocessing.spawn` 来启动多个进程。这个函数的参数包括进程函数、进程数量、其他可选参数如 args(传递给进程函数的参数)等。 3. **初始化CUDA环境**: 如果在使用CUDA并且需要在多个进程间共享模型或数据,需要先调用 `torch.multiprocessing.set_start_method('spawn')` 来初始化环境,确保CUDA环境在多进程下正常工作。 下面是一个简单的例子来展示如何使用 `torch.multiprocessing.spawn`: ```python import torch import torch.multiprocessing as mp def train_process(rank, args): # 这里的 rank 是每个进程的唯一标识,args 是传递给函数的参数 # 在这里编写每个进程需要执行的代码 print(f"Process {rank} is training...") if __name__ == '__main__': # 设置启动方法为 'spawn' mp.spawn(train_process, args=(args,), nprocs=4, join=True) ``` 在这个例子中,`train_process` 是每个进程将要执行的函数,我们通过 `mp.spawn` 启动了4个进程,并且将 `args` 传递给了每个进程。`join=True` 表示主线程会等待所有子进程完成后再继续执行。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值