Параллельное вычисление с помощью joblib во Flask

У меня есть python функция, которую мне нужно многократно вызывать с разными значениями аргументов. Я хотел бы выполнить это параллельно на нескольких процессорах. Я успешно сделал это с помощью модуля joblib. Теперь я хотел бы сделать свой код доступным в виде веб-приложения, использующего flask, работающего на AWS EC2 instance с несколькими процессорами. Вот игрушечный пример того, что я пробовал:

from flask import Flask
from joblib import Parallel, delayed
from time import sleep

def myfunc(x):
    sleep(5)
    return x

application = Flask(__name__)

@application.route('/', methods = ['GET'])
def getresult():
    out = Parallel(n_jobs=-1, verbose=10)(delayed(myfunc)(i) for i in range(5))
    return str(sum(out))

if __name__ == "__main__":
    application.debug = True
    application.run()

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

    /Library/anaconda/lib/python3.6/site-packages/joblib/parallel.py:547:
    UserWarning: Multiprocessing-backed parallel loops cannot be nested below 
    threads, setting n_jobs=1
      **self._backend_args)
    [Parallel(n_jobs=-1)]: Done   1 out of   1 | elapsed:    5.0s remaining:    0.0s
    [Parallel(n_jobs=-1)]: Done   2 out of   2 | elapsed:   10.0s remaining:    0.0s
    [Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:   15.0s remaining:    0.0s
    [Parallel(n_jobs=-1)]: Done   4 out of   4 | elapsed:   20.0s remaining:    0.0s
    [Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:   25.0s remaining:    0.0s
    [Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:   25.0s finished

Какие-либо предложения?


person Miguel    schedule 24.05.2018    source источник


Ответы (1)


Посмотрите на UserWarning:

UserWarning: Multiprocessing-backed parallel loops cannot be nested below 
threads, setting n_jobs=1

Может быть, это поможет:

Параллельные циклы с поддержкой многопроцессорной обработки не могут быть вложены под потоками, значение n_jobs = 1

Flask, вероятно, раскручивает свои собственные потоки под капотом, поэтому ваш getresult () может не работать в MainThread.

person Sebastian Loehner    schedule 24.05.2018
comment
По общему признанию, я не являюсь экспертом в области параллельной обработки, поэтому я не совсем понимаю предупреждение. Но я все же попробовал установить threading.current_thread().name == 'MainThread', как было предложено в сообщении, на которое вы ссылались, и это не помогло. - person Miguel; 24.05.2018
comment
на самом деле это должно быть: threading.current_thread().name = 'MainThread', поскольку кажется, что joblib проверяет, является ли имя "MainThread" ... - person Sebastian Loehner; 24.05.2018
comment
Да, вы правы, но это, к сожалению, не решает проблемы. - person Miguel; 24.05.2018
comment
Есть обновления по этому поводу? Не может быть, чтобы вы не могли запускать параллельные процессы из маршрута фляги - person James; 21.09.2018