如何使用PyTorch多处理?

Rah*_*hul 2 python multiprocessing computer-vision pytorch

我正在尝试使用python的multiprocessing Pool方法pytorch来处理图像。这是代码:

from multiprocessing import Process, Pool
from torch.autograd import Variable
import numpy as np
from scipy.ndimage import zoom

def get_pred(args):

  img = args[0]
  scale = args[1]
  scales = args[2]
  img_scale = zoom(img.numpy(),
                     (1., 1., scale, scale),
                     order=1,
                     prefilter=False,
                     mode='nearest')

  # feed input data
  input_img = Variable(torch.from_numpy(img_scale),
                     volatile=True).cuda()
  return input_img

scales = [1,2,3,4,5]
scale_list = []
for scale in scales: 
    scale_list.append([img,scale,scales])
multi_pool = Pool(processes=5)
predictions = multi_pool.map(get_pred,scale_list)
multi_pool.close() 
multi_pool.join()
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

`RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method
Run Code Online (Sandbox Code Playgroud)

在这一行:

predictions = multi_pool.map(get_pred,scale_list)
Run Code Online (Sandbox Code Playgroud)

谁能告诉我我在做什么错?

Oli*_*ann 7

我建议您阅读 multiprocessing 模块的文档,尤其是本节。您必须通过调用 来更改子流程的创建方式set_start_method。摘自那些引用的文档:

import multiprocessing as mp

def foo(q):
    q.put('hello')

if __name__ == '__main__':
    mp.set_start_method('spawn')
    q = mp.Queue()
    p = mp.Process(target=foo, args=(q,))
    p.start()
    print(q.get())
    p.join()
Run Code Online (Sandbox Code Playgroud)


nic*_*nne 6

pytorch文档中所述,处理多重处理的最佳做法是使用torch.multiprocessing而不是multiprocessing

请注意,只有在Python 3中,使用start方法spawnforkserver作为start方法,才支持在进程之间共享CUDA张量。

在不修改代码的情况下,正在解决的错误的替代方法是

from multiprocessing import Process, Pool
Run Code Online (Sandbox Code Playgroud)

与:

from torch.multiprocessing import Pool, Process, set_start_method
try:
     set_start_method('spawn')
except RuntimeError:
    pass
Run Code Online (Sandbox Code Playgroud)

  • 有时甚至`torch.multiprocessing.set_start_method('spawn', force=True)` (6认同)
  • 确保主循环由 `if __name__ == '__main__':` 分隔,在这种情况下,全局语句将在生成时执行 (2认同)