python - 使用多处理时克服内存限制

标签 python multiprocessing

我正在使用进化算法 (CMAES) 进行函数优化。为了更快地运行它,我使用了多处理模块。我需要优化的函数在下面的代码中将大矩阵作为输入 (input_A_Opt, and input_B_Opt)

它们有几个 GB 的大小。当我在没有多处理的情况下运行该函数时,它运行良好。当我使用多处理时,内存似乎有问题。如果我用小输入运行它,它运行良好,但是当我用完整输入运行时,我得到以下错误:

File "<ipython-input-2-bdbae5b82d3c>", line 1, in <module>
opt.myFuncOptimization()

File "/home/joe/Desktop/optimization_folder/Python/Optimization.py", line 45, in myFuncOptimization
**f_values = pool.map_async(partial_function_to_optmize, solutions).get()**
File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
raise self._value
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 385, in _handle_tasks
put(task)
File "/usr/lib/python3.5/multiprocessing/connection.py", line 206, in send
self._send_bytes(ForkingPickler.dumps(obj))

File "/usr/lib/python3.5/multiprocessing/connection.py", line 393, in _send_bytes
header = struct.pack("!i", n)

error: 'i' format requires -2147483648 <= number <= 2147483647

这是代码的简化版本(同样,如果我在输入小 10 倍的情况下运行它,一切正常):

import numpy as np
import cma
import multiprocessing as mp
import functools
import myFuncs
import hdf5storage



def myFuncOptimization ():

    temp = hdf5storage.loadmat('/home/joe/Desktop/optimization_folder/matlab_workspace_for_optimization')    

    input_A_Opt  = temp["input_A"]
    input_B_Opt  = temp["input_B"]

    del temp

    numCores = 20

    # Inputs
   #________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    P0 = np.array([            4.66666667, 2.5,    2.66666667, 4.16666667, 0.96969697,     1.95959596,     0.44088176,     0.04040404,     6.05210421,     0.58585859,     0.46464646,         8.75751503,         0.16161616,             1.24248497,         1.61616162,                 1.56312625,         5.85858586,                 0.01400841, 1.0,            2.4137931,      0.38076152, 2.5,    1.99679872      ])
    LBOpt = np.array([         0.0,        0.0,    0.0,        0.0,        0.0,            0.0,            0.0,            0.0,            0.0,            0.0,            0.0,                0.0,                0.0,                    0.0,                0.0,                        0.0,                0.0,                        0.0,        0.0,            0.0,            0.0,        0.0,    0.0,            ])
    UBOpt = np.array([         10.0,       10.0,   10.0,       10.0,       10.0,           10.0,           10.0,           10.0,           10.0,           10.0,           10.0,               10.0,               10.0,                   10.0,               10.0,                       10.0,               10.0,                       10.0,       10.0,           10.0,           10.0,       10.0,   10.0,           ])
    initialStdsOpt = np.array([2.0,        2.0,    2.0,        2.0,        2.0,            2.0,            2.0,            2.0,            2.0,            2.0,            2.0,                2.0,                2.0,                    2.0,                2.0,                        2.0,                2.0,                        2.0,        2.0,            2.0,            2.0,        2.0,    2.0,            ])
    minStdsOpt = np.array([    0.030,      0.40,   0.030,      0.40,       0.020,          0.020,          0.020,          0.020,          0.020,          0.020,          0.020,              0.020,              0.020,                  0.020,              0.020,                      0.020,              0.020,                      0.020,      0.050,          0.050,          0.020,      0.40,   0.020,          ]) 

    options = {'bounds':[LBOpt,UBOpt], 'CMA_stds':initialStdsOpt, 'minstd':minStdsOpt, 'popsize':numCores}
    es = cma.CMAEvolutionStrategy(P0, 1, options)

    pool = mp.Pool(numCores)

    partial_function_to_optmize = functools.partial(myFuncs.func1, input_A=input_A_Opt, input_B=input_B_Opt)

    while not es.stop():
        solutions = es.ask(es.popsize)            
        f_values = pool.map_async(partial_function_to_optmize, solutions).get()   
        es.tell(solutions, f_values)
        es.disp(1)
        es.logger.add()

    return es.result_pretty()

关于如何解决这个问题有什么建议吗?我是不是编码不正确(python 新手)还是应该使用其他多处理包,如 scoop?

最佳答案

您的对象太大,无法在进程之间传递。您传递了超过 2147483647 个字节 - 超过 2GB!该协议(protocol)不是为此而制定的,序列化和反序列化如此大的数据 block 的纯粹开销可能是严重的性能开销。

减少传递给每个进程的数据大小。如果您的工作流程允许,请在单独的流程中读取数据,并仅传递结果。

关于python - 使用多处理时克服内存限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40642575/

相关文章:

python - Pandas 每行(一对多)的多个结果

Python 多处理。循环归档文件

python - 在按下的每个键上实现自动建议

python - 1_000 和 100_000 是什么意思?

python - 如何将我自己的 Meta 类与 SQLAlchemy-Model 一起用作父类

Python For 循环在增加迭代次数后速度变慢

python - 在没有互联网连接的情况下将 python 应用程序复制到服务器

python - 无法修改函数以坚持一个工作代理

python - 跟踪joblib.Parallel执行的进度

多处理期间的 Python stdout