我正在使用 Python 中的 multiprocessing 模块通过 keras 并行训练神经网络,使用 Pool(processes = 4) 对象使用 imap。这会在每个“周期”之后稳定地使用越来越多的内存,即每 4 个进程,直到它最终崩溃。
我使用 memory_profiler 模块来跟踪我的内存使用情况,训练了 12 个网络。这里使用的是 Vanilla imap:
如果我将 maxtasksperchild = 1 放入 Pool 中:
如果我使用 imap(chunksize = 3):
在后一种情况下,一切正常,我只向池中的每个进程发送一个批处理,所以问题似乎在于这些进程携带了有关先前批处理的信息。如果是这样,我可以强制池不这样做吗?
尽管 block 解决方案似乎有效,但我宁愿不使用它,因为
- 我想使用
tqdm模块跟踪进度,在 block 的情况下,它只会在每个 block 之后更新,这实际上意味着它根本不会真正跟踪任何东西,因为这些 block 同时完成(在这个例子中) - 目前,所有网络的训练时间完全相同,但我希望能够让它们有不同的训练时间,这样分块解决方案可能会导致一个进程获得所有较长的训练时间。<
这是普通情况下的代码片段。在另外两种情况下,我只是更改了 Pool 中的 maxtasksperchild 参数,以及 imap 中的 chunksize 参数:
def train_network(network):
(...)
return score
pool = Pool(processes = 4)
scores = pool.imap(train_network, networks)
scores = tqdm(scores, total = networks.size)
for (network, score) in zip(networks, scores):
network.score = score
pool.close()
pool.join()
请您参考如下方法:
不幸的是,python 中的multiprocessing 模块带来了巨大的开销。数据大多不在进程之间共享,需要复制。这将从 python 3.8 开始改变。
https://docs.python.org/3.8/library/multiprocessing.shared_memory.html
虽然 python 3.8 的正式发布是在 2019 年 10 月 21 日,但您已经可以在 github 上下载它了
