2017-07-18 9 views
0

私は、Djangoを使用して機械学習サービスをホストしています。これは、パラメータを照会すると予測を返します。反復インポートの代わりに永続ライブラリdjango

私の問題は、それがimport tensorflowにあり、すべてのさまざまなライブラリすべての繰り返し、毎回新しいリクエストが来ています。これは本当に遅くなります。永続的なライブラリとモデルを作るための方法があります(Tensorflowは、その輸入いつでもメッセージの束を吐き出すと、ロードするために4秒のようになります)

現在のアーキテクチャ(のみ、そのサービス):

main_app/ 
    manage.py 
    classifiers/ 
     __init__.py 
     util.py 
     views.py 
     lstm_predictor.py 

util.py:(!Tensorflowは、新しい要求が入るたびにリロードされる)

from sklearn.externals import joblib 
import pandas as pd 
import xgboost as xgb 
from keras.models import load_model 
from keras.preprocessing import sequence 
from nltk.corpus import stopwords 
import os,calendar,re 
import logging 
from lstm_predictor import lstm_predict 
logger = logging.getLogger(__name__) 

# Load models here to avoid reload every time 
ensemble_final_layer = joblib.load("final_ensemble_layer.pkl") 
text_processor = joblib.load("text_processor.pkl") 
lstm = load_model("LSTM_2017-07-18_V0") 

views.py

import json, pdb, os, hashlib 
import logging 

from django.core.serializers.json import DjangoJSONEncoder 
from django.http.response import HttpResponse 
from django.shortcuts import render 
from django.views.decorators.csrf import csrf_exempt 
from classifiers.util import * 

logger = logging.getLogger(__name__) 


@csrf_exempt 
def predict(request): 
    result = get_prediction(params) 
    result_hash = {"routing_prediction":result} 
    data = json.dumps(result_hash, cls = jangoJSONEncoder) 
    return HttpResponse(data, content_type="application/json") 

私はどこにインポートをシフトすることができるので、そのアプリケーションが起動すると一度だけ読み込まれますか?

ありがとうございました! :)

+0

モジュールはシングルトンであるため一度だけロードされますが、 'uwsgi'などを使用して展開するといくつかのプロセスが実行されるため、プロセスごとに1回ロードされます。 – Grimmy

+0

@Grimmyこんにちは、あなたの返信ありがとう!それはdoesntです。ログを見ると、新しいリクエストが来るたびにテンソルフローがリロードされます。(Tensorflowは最初にインポートしたときにたくさんのメッセージを表示します) – Wboy

+0

'./manage.py shell'で' util'を何度もインポートすると、これも起こりますか?それは変だ。 – Grimmy

答えて

2

は、これは本当に問題に直接の答えではなく、直接Djangoのビューでメモリおよび/または時間空腹のプロセスを実行するに依存しているウェブAPIを作成する際に、潜在的に重要な問題を指摘しています。

Web apisは軽く、できるだけ早く応答するはずです。あまりにも多くのリソースを費やすことなく、より多くのプロセスでスケールアップすることも容易でなければなりません。

直接、各Djangoのプロセスは独自のtensorflowモジュールとデータファイルを初期化しますジャンゴでtensorflow使用。これらのプロセスは、マスタプロセスのルールに基づいて再起動される傾向がありますが、Herokuのデフォルト動作がわかりません。 (私は彼らがuwsgiまたはgunicornを使用していると推測しています)

より良い方法は、ワーカープロセスを分離するために作業を移動することです。これらのプロセスは、キュー上で作業を開始するまで待機します。 predictビューでは、新しいジョブをキューにプッシュし、レスポンスにユニークなjob_idを返します(わずか数ミリ秒かかる)。 apiを使用しているクライアントは、その状態を定期的に取得することができます。job_idジョブが正常に完了すると、json結果が返されます。

このようにすれば、本当に軽く応答性の高いapiサーバーを作成できます。労働者の数は、必要に応じて拡大縮小することができます。ワーカーは別のサーバー/コンテナで実行することもできます。これを達成する

一つの方法は、django_celeryを使用しているが、おそらく他の多くのオプションがあります。

+0

ありがとうございました! :) – Wboy

1

Djangoは各リクエストに応じてないインポートモジュールを行います。プロセスごとに1回記録されます。通常、サーバーはサイトにサービスを提供するために複数のプロセスを起動します。それぞれがテンソルフローと他のモジュールを一度だけインポートします。

+0

こんにちは@ダニエルので、私はあなたが正しく理解している - たとえ、私は "新しいテンソルフローバックエンド"メッセージを使用して、新しいプロセスは、それを処理するためにスピンアップされているので? – Wboy

+0

@Wboyおそらくそうだと思います。私は私の質問にもそれにコメントを追加しました。私はおそらくHerokuが遅いか、あまりにも多くのメモリを使用するため、プロセスを殺したと思われます。おそらくそのルールを設定することができます。 – Grimmy

関連する問題