修复由于在Heroku上实例化大型Keras模型而导致的Flask超时

时间:2018-06-25 05:58:09

标签: python heroku flask keras

因此,我有一个简单的Flask演示应用程序,用于服务我训练的Keras模型。该应用程序在我的计算机上本地运行正常,但在Heroku上经常超时。在应用程序中,当Flask启动时会加载模型。这样做最有意义,因为那时我们不必在每个请求上都重新加载模型。通常这会很好,因为Flask会连续运行。但是,由于这是一个免费的Heroku应用程序,因此Heroku在30分钟后会停用我的实例。这意味着每次应用程序必须从头开始重新加载模型时,由于实例化模型而导致超时错误(通常需要20秒钟以上的时间)(有时还存在内存不足错误)。我想尽可能减少模型加载时间。除非找到另一种方法来避免在Heroku上超时而不进行升级(即多线程)。我意识到我可以将模型托管在AWS上的GPU或类似的东西上,但是我想保持模型尽可能简单和经济高效。这并不意味着可以处理数千个请求,而仅当一两个人单击我的论文中的链接时才起作用。

代码在下面。

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:

5 个答案:

答案 0 :(得分:1)

使用 Celery 处理 Long task running。 这将防止超时。

答案 1 :(得分:0)

您只希望它可以与1-2个人一起使用,谁会点击您论文中的链接?

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

Github有一个内置的预览渲染,然后您可以包括一个设置教程,以使其在本地工作。


我唯一想到的另一件事是使用Heroku worker,一个子进程或:

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')

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

您应该在超时之前检查一下heroku日志。如果导入Keras库导致“加载Tensorflow后端”,然后dyno超时,则应尝试使用TensorFlow Keras扩展。

我会在这里查看文档:{​​{3}}

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

希望有帮助。

答案 4 :(得分:0)

这有点hack,但是应该可以。

只需导入keras中所需的内容,而不是导入庞然大物的tensorflow.contrib库。

示例:

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