如何在分布在多个节点的 Python 中可靠地生成随机数?

计算科学 Python 并行计算 随机数生成
2021-12-20 12:52:12

考虑以下场景:我想在具有多个节点的计算集群上执行大型蒙特卡罗模拟。为了避免过度传输数据,我将在各个节点上为我的模拟生成随机数据。使用 Python,我想使用numpy.random函数来做到这一点。

我需要确保各个节点生成不同的随机数据(如果它们生成相同的数据,它们只会复制彼此的工作)。我可以通过为各个节点上的 RNG 选择不同的种子来做到这一点。但是我如何选择这些种子以确保生成的随机数序列不会在不同节点之间意外相交?

如果我只是在将工作负载提交给计算节点的一个节点上为我的计算节点生成随机种子数,理论上我可能会遇到计算节点生成随机数序列的情况,这些随机数序列在 RNG 的可能随机数空间中有所交叉序列,尝试在这里说明:

node 1  |-------************----------------------------------------------|
node 2  |----------------------------------************-------------------|
node 3  |---************--------------------------------------------------|

s 说明了每个节点生成的***随机数序列,它们的起点由在工作开始时给予每个节点的(随机生成的)种子给出。我意识到可能的随机数序列的空间可能是巨大的,发生这种情况的概率可能很低,但是我如何确保它不会发生(假设节点对随机数的集体需求不会耗尽空间可能的随机序列)?

3个回答

据我所知,Numpy 不支持独立流。事实上,从 Mersenne Twister (Pythons RNG) 获得独立的流是出了名的困难,尽管它可以做到

考虑使用RandomGen包。它与 Numpy 完全兼容,并为您提供 PCG64 生成器,最多支持263独立的流。可以说对于大多数数据中心来说已经足够了。有关详细信息,请参阅文档

如果一个处理器生成一个已经出现在另一个处理器上的数字,这不是问题。但是,如果这两个生成的整个序列相似,那将是一个问题。如果您从不同的随机种子开始,这不太可能,因为在 RNG 开始重复之前从 RNG 获得的数字数量(循环长度)非常大,以至于随机选择的起点不太可能导致重叠序列.

但是,如果您想确定地避免这种情况,那么为什么不采用以下过程:假设您有两个处理器,然后让每个处理器从相同的种子生成相同的序列,并让处理器零只取第 0、第 2、第 4 个, ...这个序列的元素,处理器一个是第一个,第三个,第五个,......元素。如果你有P处理器,让p处理器取元素xi ,则为随机数序列这保证了每个过程的循环长度是最大的,并且您肯定不会得到任何重叠序列。i=pmodP

这个确切的问题(不生成相同的随机数序列)在 John D. Cook 的博客文章Random number generator seed errors中有描述。

解决方案只是确保进程以唯一的种子启动。您在问题中也提到了这一点。我认为您的数字可能有点误导,因为大多数随机数生成器不会产生以所示方式重叠的随机序列。

来自约翰的帖子:

在这种情况下,最好用顺序种子为每个进程播种:给第一个进程种子 1,第二个种子 2,等等。种子不必是随机的;它们必须是独一无二的。如果您使用的是好的随机数生成器,则以 1、2、3、...、1000 为种子的 1,000 个进程的输出将是独立的。