2017-09-29 16 views
1

Je n'arrive pas à comprendre cela. J'ai un modèle formé avec scikit-learn, enregistré dans un fichier .pkl, et je veux faire une API qui ferait des prédictions basées dessus.Gunicorn/flask API pour exposer un modèle sklearn ne fonctionnant pas

J'ai déjà le code qui fait des prédictions et il fonctionne bien à partir des tests de console/unité. Pour accélérer les prévisions, je divise les données (des milliers de patchs d'image) et j'étale la charge en utilisant joblib/multiprocessing.

Je règle JOBLIB_START_METHOD=forkserver car scikit-learn se bloque s'il est utilisé dans un processus multiprocessing.

J'ai une API faite avec flask qui utilise ce code, et lorsqu'elle est exécutée avec le serveur de développement de flask cela fonctionne très bien. Maintenant, j'essaie d'héberger l'application flask au sein de gunicorn et cela ne fonctionne pas du tout.

Si j'utilise les travailleurs par défaut, alors il se bloque sans erreur en essayant de prédire, un peu comme si je n'avais pas défini le multi-traitement 'forkserver'. Je suis en gunicorn comme ceci:

JOBLIB_START_METHOD=forkserver gunicorn -w 2 -b 0.0.0.0:$PORT --timeout 3600 web.app:app

J'ai aussi essayé d'utiliser le back-end gevent. Cela ne fait le travail, mais il est très lent, et il imprime ceci:

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

Alors, des idées sur obtenir ceci pour travailler d'une manière qu'il ya des travailleurs Web multiples en cours d'exécution (je ne pense pas que ce soit le cas avec le serveur de développement de flask) et avec une demande pouvant tirer parti joblib/multiprocessing? merci

Répondre

0

Gevent ne fonctionnera pas avec joblib car il engendre thread (s) pour traiter les demandes simultanément (référez-vous discussion) et c'est ce que votre avertissement dit réellement. Deuxièmement, c'est très lent parce que joblib convertit vos appels parallèles en appels séquentiels et les exécute (voir discussion).

J'ai fait le même problème face au parallélisme en utilisant joblib. Bien que je n'ai pas utilisé sklearn, je pense que la commande suivante devrait fonctionner pour vous aussi:

gunicorn -b 0.0.0.0:$SERVICE_PORT --workers=2 -t $SERVICE_TIMEOUT rest_api:app 

Si vous voulez jeter un oeil au code source complet, vous pouvez le suivre here.