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

Python 如何在Flask中缓存大型机器学习模型?,python,caching,flask,machine-learning,Python,Caching,Flask,Machine Learning,以下是我面临的情况: 我刚刚编写了一个Flask应用程序,人们可以输入他们想要的文本评论,我的应用程序将从我们的数据集中返回最相似的评论。所以基本上这是一个NLP项目,机器学习模型已经被训练过了。现在的问题是该模型大约为2.5GB,每次用户输入某个内容时,它都会加载该模型进行一些计算 我对机器学习的东西还可以,但在网络开发领域我完全是个新手。在谷歌搜索之后,我发现Flask中的缓存可能是解决方案,我试着遵循本教程 然而,我没有实现它。谁能给我一些建议,告诉我正确的方法是什么。如果Flask ca

以下是我面临的情况:

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

我对机器学习的东西还可以,但在网络开发领域我完全是个新手。在谷歌搜索之后,我发现Flask中的缓存可能是解决方案,我试着遵循本教程


然而,我没有实现它。谁能给我一些建议,告诉我正确的方法是什么。如果Flask cache是“最佳”解决方案,我将继续关注这些内容,并希望我能够做到。

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

我就是这样做的:

  • 为我的模型创建一个类文件,并加载
    def\uuuu init\uuuu(self,…):
  • 我在全局范围内的主flask服务器文件中实例化该类,在该文件中该类可用于我的所有函数(我将其作为模块从其自己的子目录加载)

  • 我不确定这是构建这个架构的最佳方式,但在我的例子中,它很简单,而且效果很好,我通常只需要为数据驱动的模型公开一些路径,而不是根据可靠的原则设计复杂的软件

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

    更理想的解决方案是:

    • 编写一些与主Flask应用程序一起运行的调度程序(查看ApScheduler的BackgroundScheduler)
    • 此计划程序有一个作业,它定期轮询包含经过训练的模型的目录,并检查模型是否最近发生了更改(使用类似的方式),如果文件已更改,计划程序只需重新加载并更新全局引用变量中的模型实例引用

    我建议在运行应用程序时加载模型一次。只需将模型加载到主函数中即可。第一次加载应用程序时需要一些时间,但每次调用predict 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)
    
    这是我的解决办法

    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
    变量不是一个好主意。

    谢谢您的回复。我确实想过这样做,但我不确定如果我计划在AWS上部署该应用程序是否合适。如果有人找到了一个循序渐进的教程,请让我知道。如果您对您的代码进行解释,以及为什么
    global
    不是一个好主意,您的答案将更有帮助。