为什么numpy.random和multiprocessing不兼容?

9 投票
1 回答
6299 浏览
提问于 2025-04-18 10:38

我有一个随机漫步的函数,它使用 numpy.random 来生成随机步伐。这个 walk 函数单独运行时没问题。在大多数情况下,它在并行处理时也能正常工作,但当和 multiprocessing 一起使用时,就出现了问题。为什么 multiprocessing 会出错呢?

import numpy as np

def walk(x, n=100, box=.5, delta=.2):
    "perform a random walk"
    w = np.cumsum(x + np.random.uniform(-delta,delta,n))
    w = np.where(abs(w) > box)[0]
    return w[0] if len(w) else n

N = 10

# run N trials, all starting from x=0
pwalk = np.vectorize(walk)
print pwalk(np.zeros(N))

# run again, using list comprehension instead of ufunc
print [walk(0) for i in range(N)]

# run again, using multiprocessing's map
import multiprocessing as mp
p = mp.Pool()
print p.map(walk, [0]*N)

结果通常是这样的……

[47 16 72  8 15  4 38 52 12 41]
[7, 45, 25, 13, 16, 19, 12, 30, 23, 4]
[3, 3, 3, 3, 3, 3, 3, 14, 3, 14]

前两种方法明显显示了随机性,而后面一种则没有。到底发生了什么,导致 multiprocessing 不能正常工作呢?

如果你加一个 sleep,让它变成 sleepwalk,并且有明显的延迟,multiprocessing 依然会出错。

不过,如果你把调用 np.random.uniform 的部分换成一个非数组的方法,比如 [(random.random()-.5) for i in range(n)],那么它就能正常工作了。

那么,为什么 numpy.randommultiprocessing 不能很好地配合呢?

1 个回答

13

到底发生了什么,导致多进程处理不正确呢?

你需要在每个进程中重新设置种子,这样才能确保每个伪随机数流是相互独立的。

我使用 os.urandom 来生成这些种子。

撰写回答