【问题标题】:Fixing Flask timeout due to instantiation of large Keras model on Heroku由于在 Heroku 上实例化大型 Keras 模型,修复了 Flask 超时
【发布时间】:2018-06-25 05:58:08
【问题描述】:

所以我有一个简单的 Flask 演示应用程序,旨在为我训练的 Keras 模型提供服务。该应用程序在我的计算机上本地运行良好,但在 Heroku 上经常超时。在应用程序中,模型在 Flask 启动时被加载。这是最有意义的,因为我们不必在每个请求上重新加载模型。通常这会很好,因为 Flask 会连续运行。但是,鉴于这是一个免费的 Heroku 应用程序,Heroku 会在 30 分钟后停用我的实例。这意味着每次应用程序必须从头开始重新加载模型时,由于模型被实例化(通常需要 20 多秒)而导致超时错误(有时它也会出现内存不足错误)。如果可能的话,我想减少模型加载时间。除非找到另一种方法来避免 Heroku 超时而不升级(即多线程)。我意识到我可以将我的模型托管在 AWS 上的 GPU 或其他东西上,然后调用它,但我想让它尽可能简单和具有成本效益。它并不是为了满足 1000 个请求,而只是在 1 或 2 个人点击我论文中的链接时起作用。

代码如下。

import os
from flask import Flask, redirect, url_for, request, render_template, send_from_directory
from werkzeug import secure_filename
from examples2.example_keras import SimpleResNet50, ResNet2

# folder to upload pictures
UPLOAD_FOLDER = 'uploads/'
# what files can upload
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])

# start + config
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['ALLOWED_EXTENSIONS']=ALLOWED_EXTENSIONS
model = ResNet2("long_path/model_weights.h5")
# main route
@app.route('/')
def index():
    return render_template('upload.html')

示例错误代码

at=error code=H12 desc="Request timeout" method=GET path="/" host=lung-r.herokuapp.com request_id=79bfba10-810e-444d-a73a-d32bcd68d603 fwd="24.198.104.217" dyno=web.1 connect=0ms service=30000ms status=503 bytes=0 protocol=https
2018-06-25T05:22:18.893433+00:00 app[web.1]: load model weights_path:

【问题讨论】:

  • 这对我来说也是个大问题

标签: python heroku flask keras


【解决方案1】:

使用 Celery 处理 Long 任务运行。 它将防止超时。

【讨论】:

    【解决方案2】:

    您只希望它适用于 1-2 个人,他们点击您论文中的链接?

    您是否考虑过制作一个 Jupyter Notebook,包括 ipynb 中的编译输出,然后在您的 github 上链接到它?

    Github 有一个内置的预览渲染,然后你可以只包含一个设置教程让他们在本地工作。


    我能想到的唯一另一件事是使用 Heroku 工作程序、子进程,或者:

    model = None
    # main route
    @app.route('/')
    def index():
        global model
        if model is None: model = ResNet2("long_path/model_weights.h5") 
        # to inform the user, load this^ in another thread/process,
        # and return 'loading' message
        return render_template('upload.html')
    

    【讨论】:

      【解决方案3】:

      创建一个在初始化时加载模型并提供预测功能的类。

      使用烧瓶注入器 (https://github.com/alecthomas/flask_injector) 将该类的实例注入 api 函数。

      【讨论】:

        【解决方案4】:

        超时错误通常是由于 Keras 必须加载 TensorFlow 后端,如果尚未完成加载,则会在 30 秒后导致测功机超时。模型加载时间通常不是问题。

        您应该在超时发生之前检查 heroku 日志的内容。如果导入 Keras 库导致“Loading Tensorflow backend”,然后测功机超时,您应该尝试改用 TensorFlow Keras 扩展。

        我会在这里查看文档:https://www.tensorflow.org/api_docs/python/tf/keras/models/load_model

        您可以将模型保存为 h5,然后通过此函数将其导入。它在 Heroku 上应该可以正常工作 - 不确定 TF Keras 包中是否有像 ResNet 这样的预训练模型。

        希望对您有所帮助。

        【讨论】:

          【解决方案5】:

          这有点小技巧,但它应该可以工作。

          不要导入庞然大物 keras 库,只需从 tensorflow.contrib 导入您需要的东西。

          例子:

          from tensorflow.python.keras.layers import LSTM, TimeDistributed, Dense, ...
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-15
            • 2020-12-25
            • 1970-01-01
            • 2020-04-05
            • 2015-10-27
            相关资源
            最近更新 更多