OSError: [Errno 12] Невозможно выделить память при использовании многопроцессорного пула Python - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь применить функцию к 5 перекрестным проверочным наборам параллельно, используя Python's multiprocessing, и повторяю это для разных значений параметров, например так:

import pandas as pd
import numpy as np
import multiprocessing as mp
from sklearn.model_selection import StratifiedKFold

#simulated datasets
X = pd.DataFrame(np.random.randint(2, size=(3348,868), dtype='int8'))
y = pd.Series(np.random.randint(2, size=3348, dtype='int64'))

#dummy function to apply
def _work(args):
    del(args)

for C in np.arange(0.0,2.0e-3,1.0e-6):
    splitter = StratifiedKFold(n_splits=5)
    with mp.Pool(processes=5) as pool:
        pool_results = \
            pool.map(
                func=_work,
                iterable=((C,X.iloc[train_index],X.iloc[test_index]) for train_index, test_index in splitter.split(X, y))
            )

Однако в середине выполнения я получаю следующееошибка:

Traceback (most recent call last):
  File "mre.py", line 19, in <module>
    with mp.Pool(processes=5) as pool:
  File "/usr/lib/python3.5/multiprocessing/context.py", line 118, in Pool
    context=self.get_context())
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 168, in __init__
    self._repopulate_pool()
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 233, in _repopulate_pool
    w.start()
  File "/usr/lib/python3.5/multiprocessing/process.py", line 105, in start
    self._popen = self._Popen(self)
  File "/usr/lib/python3.5/multiprocessing/context.py", line 267, in _Popen
    return Popen(process_obj)
  File "/usr/lib/python3.5/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
  File "/usr/lib/python3.5/multiprocessing/popen_fork.py", line 67, in _launch
    self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory

Я запускаю это на Ubuntu 16.04 с 32 ГБ памяти и проверяю htop во время выполнения, оно никогда не превышает 18,5 ГБ, поэтому я не думаю, что у меня заканчиваетсяпамять.
Это определенно связано с разделением моих фреймов данных с индексами из splitter.split(X,y), так как, когда я непосредственно передаю свои фреймы данных в объект Pool, никакая ошибка не выдается.

Я видел этот ответ , в котором говорится, что это может быть связано с созданием слишком большого числа зависимостей файлов, но я понятия не имею, как мне это исправить, и не является диспетчером контекстадолжен помочь избежать подобных проблем?

1 Ответ

0 голосов
/ 04 февраля 2019

os.fork() делает копию процесса, поэтому, если вы используете около 18 ГБ и хотите позвонить fork, вам нужно еще 18 ГБ.Дважды 18 - это 36 ГБ, что намного больше 32 ГБ.Хотя этот анализ (намеренно) наивен - некоторые вещи не копируются на вилку - вероятно, достаточно объяснить проблему.

Решение состоит в том, чтобы сделать пулы более ранними, когда требуется копировать меньше памятиили усерднее работать над совместным использованием самых больших объектов.Или, конечно, добавить в систему больше памяти (возможно, просто виртуальной памяти, т. Е. Пространства подкачки).

...