使用uwsgi结合Flask多进程调用TensorFlow模型推理时服务卡住

       使用Flask对TensorFlow训练后的模型进行服务器部署时,想使用uwsgi设置多进程的方式解决发布服务以解决高并发。服务写好后使用uwsgi进行多进程发布后发现运行sess.run调用模型推理时服务会卡住无法运行,查看后台uwsgi进程后会发现仅剩一个uwsgi服务,其他的uwsgi进程已经僵死。

一开始纠结可能是tf的问题,尝试了很多方法将模型调用通过类创建后还是不能解决该问题。最后怀疑是uwsgi造成的。便查找uwsgi相关问题,通过该博客https://www.cnblogs.com/lyssym/p/11643256.html确定原因是uwsgi采用多线程调用Flask服务,即对于上述全局的模型,若是初始化后,会被每一个线程复制一次,即每个线程会有一个自己独立的全局图模型,但在后续调用服务时,会导致session的阻塞。

解决方案:使上述所有的线程共享同一个全局的图模型,即不在多个线程中进行复制,可基于Flask调用钩子函数before_first_request加载全局的图模型,从而解决上述问题。

因而在程序中我加上钩子函数before_first_request后,重新发布服务,uwsgi多个进程运行正常未出现卡住导致进程僵死。

修改后的部分Flask发布代码如下:

import os, time
import sys
import time
import flask
import logging
import logging.config
from flask import request
import service_tensorflow_class as service
import base64
import json

#使用uwsgi运行时去掉下面这行注释
#service.init()
#os.environ["CUDA_VISIBLE_DEVICES"] = "1,2,3,4"
app = flask.Flask(__name__)


detect_class = None
@app.before_first_request
def init():
    print('----init before_first_request --')
    global detect_class
    detect_class = service.pbInference()


@app.route('/volleyball/predict', methods=['GET', 'POST'])
def call_service():
    print('call service start')
    print(request.headers)
    code, input_url, task_id = analy_header(request.headers)
    result_label, result_score = '', 0.0
    if code == '0000':
        try:
            print('调用AI Service')
            #sess = service.model()
            #result_label, result_score = service.service(task_id, input_url)
            t1 = time.time()
            result_label, result_score = detect_class.service(task_id, input_url)
            print('AI 服务时间 inference_time: ', time.time() - t1)
            print('AI 服务返回result_label:%s'%result_label)
            print('AI 服务返回result_score:%s'%result_score)
        except Exception as e:
            code = '2016'
            print('AI内部逻辑异常:%s'%e)
    print('call service end')
    resp = flask.make_response()
    resp.headers = pack_result(result_label,result_score,task_id,code)
    print('resp.headers:',resp.headers)
    return resp
        
if __name__ == '__main__':
    # service.init()
    app.run(host='0.0.0.0', port=8000, debug=False, processes=True, threaded=False)
    # app.run(debug=True)

TensorFlow调用pb的方法可参考我之前的文章,最后再次感谢博主的文章才让我解决问题。

参考资料:

1、https://www.cnblogs.com/lyssym/p/11643256.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值