持久化库而不是重复导入django

时间:2017-07-18 07:03:39

标签: python 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")

我是否可以将导入转移到某个地方,以便在应用启动时仅加载一次?

谢谢! :)

2 个答案:

答案 0 :(得分:2)

这不是一个直接解决问题的答案,但是在制作依赖于直接在Django视图中执行内存和/或耗时的进程的web apis时指出了一个潜在的关键问题。

Web apis应该很轻,并尽可能快地响应。它们也应该易于使用更多流程进行扩展,而不会花费太多资源。

当直接在django中使用tensorflow时,每个django进程都会初始化自己的tensorflow模块和数据文件。这些过程也倾向于根据主进程中的规则重新启动,但我不知道Heroku上的默认行为是什么。 (我猜他们使用uwsgigunicorn

更好的方法是将工作转移到单独的工作进程。这些进程等待队列上的传入工作。您的predict视图只会将新作业推送到队列,并在响应中返回唯一的job_id(仅需几毫秒)。然后,使用api的客户端可以定期提取job_id的状态。成功完成作业后,将返回json结果。

通过这种方式,您可以拥有一台非常轻便且响应迅速的api服务器。工人数量可根据需要按比例增加和减少。工作人员也可以在不同的服务器/容器上运行。

实现此目的的一种方法是使用django_celery,但可能还有许多其他选项。

答案 1 :(得分:1)

Django在每个请求上都导入模块。它为每个进程记录一次。通常,您的服务器将启动多个进程来为您的站点提供服务;每一个都只会导入tensorflow - 以及任何其他模块。