假设我有一个"blackbox"函数,其设置如下:
def bb_func():
#Does lots of stuff
#Including lots of scikit-learn stuff
if __name__ == '__main__':
bb_func()
CCD_ 1是显著的CPU密集型,并且将从使用多个核中受益匪浅。编辑:我只需要运行bb_func()
一次。
由于我使用的是scikit-learn
,我想知道是否有可用的东西(不一定在软件包中)可以做到这一点。
多次运行黑盒的最简单方法是使用具有并行map
函数的辅助Pool
。有几个python包具有map
函数。multiprocessing
是最流行的一个,并且被构建在python标准库中。我使用一个名为pathos
的包,它构建在multiprocessing
接口上,并对其进行扩展,以通过套接字连接提供并行映射。bb_func()
0还提供了更健壮的并行map
(我将在下面讨论)。在这里,我们看到了几种不同风格的并行映射(阻塞、异步和迭代)。
>>> def bb_func(id):
... import random
... import time
... n = random.random()
... time.sleep(n)
... return int(10*n)
...
>>> import pathos
>>>
>>> thpool = pathos.multiprocessing.ThreadingPool()
>>> mppool = pathos.multiprocessing.ProcessingPool()
>>> pppool = pathos.pp.ParallelPythonPool()
>>>
>>> # blocking map using multiple processes
>>> mppool.map(bb_func, range(10))
[4, 5, 8, 7, 4, 2, 0, 0, 5, 3]
>>>
>>> # iterative map using multiple threads
>>> res = thpool.imap(bb_func, range(10))
>>> res.next()
8
>>> res.next()
4
>>> list(res)
[8, 2, 5, 2, 4, 2, 3, 1]
>>>
>>> # asynchronous map able to work across sockets
>>> res = pppool.amap(bb_func, range(10))
>>> res.ready()
True
>>> res.get()
[1, 2, 8, 9, 6, 7, 0, 5, 8, 9]
对于pathos
,这些映射也可以被布置为提供层次并行性。在这里,我们以异步并行方式启动5个多处理映射,其中每个多处理映射对10个项目调用CCD_ 13。
>>> res = thpool.amap(mppool.map, [bb_func]*5, [range(10)]*5)
>>> res.get()
[[7, 1, 4, 7, 8, 9, 2, 6, 0, 2], [9, 5, 1, 6, 9, 0, 5, 3, 4, 5], [4, 7, 2, 7, 3, 5, 8, 3, 3, 9], [4, 8, 8, 8, 3, 5, 0, 6, 1, 0], [8, 0, 6, 7, 7, 4, 1, 6, 2, 7]]
pathos
还提供了建立ssh tunnel
连接的能力,因此,如果您的套接字连接需要安全,您可以建立ssh tunnel
,并确保map
通过隧道套接字发送调用。此外,还有一个名为pyina
的姊妹包,它使用MPI
作为后端为map
函数提供了类似的接口。如果您想使用MPI
和计算集群调度器而不是pathos
(或与之协调),我将让您看看这一点。pyina
在背后使用mpi4py
,并为执行利用MPI
的并行批处理调用提供了更直观的高级界面。
您的bb_func
将有两个关键问题。首先,bb_func
需要是可序列化的。pathos
包(和pyina
)使用dill
序列化程序,因为dill
可以序列化大多数python对象。如果您要导入bb_func
,而不是在同一个文件(或解释器)中自己定义它,那么它更有可能是可序列化的。其次,scikit-learn
可能会占用大量内存,因此并行运行几个scikit-learn
调用通常会占用所有内存。至于如何绕过这种内存限制……你需要试着聪明地编码,并可能使用一些技巧,比如处理内存映射文件,或者在使用大型数据集后立即处理它们(到文件或垃圾收集)。
在此处获取pathos
(以及pyina
和dill
):https://github.com/uqfoundation
EDIT:我从您的编辑中看到,您只运行了一次bb_func
,这是一个黑框。所以这种情况下的答案很简单…"不,对不起。除非你想挖黑盒子,否则你会被卡住。"