如何在Flask中缓存大型机器学习模型?

时间:2015-08-25 20:55:22

标签: python caching flask machine-learning

以下是我面临的情况:

我刚刚写了一个Flask应用程序,人们可以输入他们想要的文本评论,我的应用程序将从我们的数据集中返回最相似的评论。所以基本上它是一个NLP项目,机器学习模型已经训练好了。现在的问题是模型大约是2.5GB,每次用户键入某些内容时,它会加载该模型进行一些计算。

我很喜欢机器学习的东西,但在网络开发领域是一个新手。经过一些谷歌搜索,我发现Flask中的缓存可能是解决方案,我尝试按照本教程http://brunorocha.org/python/flask/using-flask-cache.html

但是,我未能实现它。任何人都可以给我一些关于正确方法的建议。如果Flask缓存是""解决方案,我会继续关注那些东西,并希望我能做到。

5 个答案:

答案 0 :(得分:1)

我建议您在运行应用程序时加载一次模型。只需将模型加载到main函数中即可完成。第一次加载应用程序会花费一些时间,但是每次调用预报API时都会更快。

@app.route('/predict', methods=['POST', 'OPTIONS']) 
def predict(tokenized):
     global model
     "do something"
     return jsonify(result)

 if __name__ == '__main__':
    model = load_model('/model/files/model.h5')
    app.run(host='0.0.0.0', port=5000)

答案 1 :(得分:0)

每次在脚本中初始化模型一次,使其保留在内存中而不必重新加载,而不是在函数中加载模型。 您可以先尝试上述方法,而不是使用flask-cache。

答案 2 :(得分:0)

我就是这样做的:

  1. 为我的模型创建一个类文件,并加载def __init__(self,...):
  2. 中的所有内容
  3. 我在全局范围的主烧瓶服务器文件中实例化该类,它可用于我的所有功能(我将其作为模块从其自己的子目录加载)
  4. 不确定这是构建它的最佳方式,但它很简单并且在我的情况下非常好用,我通常只需要为数据驱动模型公开几条路线,而不是设计复杂的软件根据坚实的原则!

答案 3 :(得分:0)

显然,模型加载操作是时间密集和阻塞的,并且随着更新模型的大小而增加。默认情况下Flask是阻塞的,除非您在其上使用类似uwsgi负载均衡器的东西并部署n个线程或进程以确保一定量的水平可伸缩性。假设您运行Flask应用程序的单个实例,那么在初始化应用程序时(特别是在app.run()之前)加载更新的模型是有意义的。您将此作为全局变量进行维护,以使其上下文在整个应用程序实例中可用。您还可以添加/ reload-model端点,该端点接受模型名称并更新内存引用以指向更新的模型。当然,你不会经常调用这个终点,但不时。

更高级的解决方案是:

  • 编写某种与主Flask应用程序一起运行的调度程序(查看ApScheduler的BackgroundScheduler)。
  • 此调度程序有一个作业,它定期轮询包含已训练模型的目录,并检查模型是否最近更改(使用https://pythonhosted.org/watchdog/之类的内容),如果文件已更改,则调度程序只是重新加载和更新全局引用变量中的模型实例引用。

答案 4 :(得分:0)

这是我的解决方案。

from flask import current_app
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    current_app.model.predict_something()

if __name__ == '__main__':
    with app.app_context():
        current_app.model = load_your_model()
    app.run()

使用 global 变量不是一个好主意。