Как разделить большой набор данных между несколькими процессами? - PullRequest
2 голосов
/ 22 октября 2019

Мне нужно прочитать большой набор данных (около 25 ГБ изображений) в память и прочитать его из нескольких процессов. Ни один из процессов не должен писать, только читать. Все процессы запускаются с использованием многопроцессорного модуля Python, поэтому они имеют один и тот же родительский процесс. Они тренируют разные модели на данных и работают независимо друг от друга. Причина, по которой я хочу читать это только один раз, а не в каждом процессе, заключается в том, что память на машине ограничена.

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

Возможно ли каким-то образом иметь другой процесс, который служит только функцией "получить изображение с идентификатором x"? Какой модуль Python подойдет для этого? В противном случае я думал о реализации небольшого веб-сервера с использованием werkzeug или Flask, но я не уверен, станет ли это моим новым узким местом, тогда ...

Еще одна возможность, которая пришла мне в голову, - это использовать потоки вместопроцессов, но поскольку Python на самом деле не выполняет «настоящую» многопоточность, это, вероятно, станет моим новым узким местом.

Ответы [ 2 ]

2 голосов
/ 22 октября 2019

Если вы используете linux и содержимое только для чтения , вы можете использовать механизм наследования linux fork .

из документация mp :

Лучше наследовать, чем pickle / unpickle

При использовании методов запуска spawn или forkserver многие типы из многопроцессорной обработки должны выбираться так, чтобы дочерний процесспроцессы могут использовать их. Однако, как правило, следует избегать отправки общих объектов другим процессам с использованием каналов или очередей. Вместо этого вы должны расположить программу так, чтобы процесс, которому нужен доступ к общему ресурсу, созданному в другом месте, мог унаследовать его от процесса-предка.

, что означает:

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

Затем в том же модуле запустите вашего ребенка с многопроцессорной обработкой в ​​режиме 'fork' set_start_method('fork').

с помощью этого подпроцессы увидят эту переменную без ее копирования. Это происходит из-за механизма разветвления Linux, который создает дочерние процессы с тем же отображением памяти, что и родительский (см. «Копирование при записи»).

1 голос
/ 22 октября 2019

Я бы предложил mmap пинговать файлы , чтобы они могли совместно использоваться несколькими процессами, а также получать / выгружаться в зависимости от ситуации

подробности этого будутзависит от того, что вы подразумеваете под «25 ГБ изображений», и как эти модели хотят получить доступ к изображениям

. Основная идея заключается в предварительной обработке изображений в соответствующий формат (например, один большой массив 4D uint8 иливозможно меньшие, индикаторы могли бы быть (image, row, column, channel)) и сохранять их в формате, где они могут эффективно использоваться моделями. см. numpy.memmap для некоторых примеров этого

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...