如何处理从joblib.Parallel返回的非常大的对象

问题描述 投票:0回答:1

我在尝试并行化的地方有以下代码:

import numpy as np
from joblib import Parallel, delayed

lst = [[0.0, 1, 2], [3, 4, 5], [6, 7, 8]]
arr = np.array(lst)
w, v = np.linalg.eigh(arr)

def proj_func(i):
    return np.dot(v[:,i].reshape(-1, 1), v[:,i].reshape(1, -1))

proj = Parallel(n_jobs=-1)(delayed(proj_func)(i) for i in range(len(w)))

proj返回一个非常大的列表,这会导致内存问题。

我有办法解决这个问题吗?我曾考虑过要返回一个生成器而不是一个列表,但是我不知道该怎么做。任何其他方式也将受到欢迎。

非常感谢。

python parallel-processing multiprocessing generator joblib
1个回答
0
投票

Q“有没有办法可以解决this?”

那到底取决于什么[this代表。


是否正在确定瓶颈的内存大小?静态大小的数据的空间:

如上所述,鉴于您的MCVE,MEMORY的大小取决于N = arr.size并且您的系统至少具有:-N * 3 * 8 [B] RAM,用于容纳lst, arr, w-[N * N * 8 [B]用于保存v]的RAM>

总共,必须有比[[<n_CPUs_> * 8 * N * ( 3 + N ) [B]

RAM空间更多的方式,只是为了介绍n_jobs == -1 python解释器过程的完整副本(对于MacOS / WinOS绝对是这样,对于linux,因为fork / method在2019/2020年被记录为产生不稳定/不安全的结果)之前代码甚至试图进行[C0的第一次调用如果这不是您系统的容量,则可以直接停止阅读。


下一个?

动态数据空间:对下一个

proj_func( i )

的任何调用-N的调用,每个调用都增加了-[proj_func( i ) RAM空间的额外RAM分配,用于保存N * N * 8 [B]-结果
总共超过[[np.dot()个用于保存k * N * N * N * 8 [B]结果的RAM,其中

np.dot()

,因为这些k >> 2结果中的每一个必须获得[C0 ]打包(再次为此分配一些RAM空间),然后每个这样的N -ed-payload必须从远程<< [SER-executor转发到主进程(这里再次为SER负载分配了一些RAM空间),接下来,此RAM存储的中间二进制有效负载必须进行joblib.Parallel()(delayed()(...))序列化(因此再次分配一些额外的RAM-用于存储原始大小为[[SERDES -ed数据的空间,以便最终将此SER / DES管道产品乘以DES-次并附加到初始N * N * 8 [B]如上述使用N子句的指定语法所坚持并强制执行。proj == []RESUMÉ:这很快就扩展了(即使我们假设没有其他python进程joblib.Parallel(…)( delayed( proj_func )( i ) for i in range( len( w ) ) ) -s和静态数据时),对于任何
[<_nCPUs_> * 8 * N * ( 3 + N ) //     static storage: data + all python process-replicas
+
<_nCPUs_> * 8 * N * N * k     //    dynamic storage: SER/DES on joblib.Parallel()(delayed…)
+
            8 * N * N * N     // collective storage: proj-collected N-( np.dot() )-results
~
=           8 * N * ( N * N + <_nCPUs_> * ( 3 + N * ( k + 1 ) ) )
 import: >
N

EPILOGUE:

所以一个简单的SLOC,使用与== arr.size >= 1E3一样简单的语法,如果至少在原始代码上没有花费适当的设计精力,就可以立即以一种无法挽救的方式破坏整个计算图的全部工作。数据处理定量估计。
© www.soinside.com 2019 - 2024. All rights reserved.