Keras + Tensorflow и многопроцессорность в Python

Я использую Keras с Tensorflow в качестве backend.

Я пытаюсь сохранить модель в своем основном процессе, а затем загрузить/запустить (т.е. вызвать model.predict) в рамках другого процесса.

В настоящее время я просто пытаюсь использовать наивный подход из документов для сохранения/загрузки модели: https://keras.io/getting-started/faq/#how-can-i-save-a-keras-model.
Итак, в основном:

  • model.save() в основном процессе
  • model = load_model() в дочернем процессе
  • model.predict() в дочернем процессе

Однако он просто зависает при вызове load_model.

Поиск вокруг Я обнаружил этот потенциально связанный ответ, предполагающий, что Keras можно использовать только в одном процессе: используя многопроцессорную обработку с помощью anano, но я не уверен, что это правда ( как представляется, не находят много на этом).

Есть ли способ достичь моей цели? Приветствуется описание высокого уровня или короткий пример.

Примечание. Я попытался подходить к методам передачи графа процессу, но сработал, так как кажется, что графики тензорного потока не подбираются (связанная с этим ссылка SO здесь: Tensorflow: Передача сеанса в многопроцесс python). Если действительно есть способ передать график/модель тензорного потока в дочерний процесс, тогда я также открыт для этого.

Спасибо!

Ответ 1

Из моего опыта - проблема заключается в загрузке Keras в один процесс, а затем при создании Keras нового процесса, когда он загружен в вашу основную среду. Но для некоторых приложений (например, для подготовки смеси моделей Keras) просто лучше иметь все это в одном процессе. Итак, я советую следующее (немного громоздкое, но работающее для меня) подход:

  • НЕ НАГРУЖАЙТЕ КЕРАС К ВАШЕЙ ОСНОВНОЙ СРЕДЕ. Если вы хотите загрузить Keras/Theano/TensorFlow, сделайте это только в среде функций. Например. не делать это:

    import keras
    
    def training_function(...):
        ...
    

    но выполните следующие действия:

    def training_function(...):
        import keras
        ...
    
  • Запуск работы, связанной с каждой моделью, в отдельном процессе: Я обычно создаю рабочих, которые выполняют работу (например, обучение, настройка, подсчет очков), и я запускаю их в отдельных процессах. Что хорошо, что вся память, используемая этим процессом, полностью освобождена, когда ваш процесс завершен. Это помогает вам с множеством проблем с памятью, которые обычно возникают при использовании многопроцессорности или даже при запуске нескольких моделей в одном процессе. Так что это выглядит, например. например:

    def _training_worker(train_params):
        import keras
        model = obtain_model(train_params)
        model.fit(train_params)
        send_message_to_main_process(...)
    
    def train_new_model(train_params):
        training_process = multiprocessing.Process(target=_training_worker, args = train_params)
        training_process.start()
        get_message_from_training_process(...)
        training_process.join()
    

Разный подход - это просто подготовка разных сценариев для разных действий модели. Но это может привести к ошибкам памяти, особенно когда ваши модели потребляют память. ПРИМЕЧАНИЕ, что по этой причине лучше сделать ваше выполнение строго последовательным.

Ответ 2

Я создал один простой пример, чтобы показать, как запустить модель Keras в нескольких процессах с несколькими gpus. Надеюсь, этот образец поможет вам. https://github.com/yuanyuanli85/Keras-Multiple-Process-Prediction

Ответ 3

Я создал декоратор, который исправил мой код.

from multiprocessing import Pipe, Process

def child_process(func):
    """Makes the function run as a separate process."""
    def wrapper(*args, **kwargs):
        def worker(conn, func, args, kwargs):
            conn.send(func(*args, **kwargs))
            conn.close()
        parent_conn, child_conn = Pipe()
        p = Process(target=worker, args=(child_conn, func, args, kwargs))
        p.start()
        ret = parent_conn.recv()
        p.join()
        return ret
return wrapper

@child_process
def keras_stuff():
    """ Keras stuff here"""