1、導包順序不變,變了會失敗;好像是import torch影响
2、 用 with app.app_context() 確保全局變量在相同的上下文
3、如果有像浏览一样的全局变量,则在操作浏览器打开页面时需要上锁,否则可能会导致浏览器内容混乱
from flask import Flask, g
from flask import jsonify
from flask import request
from gevent import monkey
from gevent.pywsgi import WSGIServer
monkey.patch_all()
import gc
import os
import sys
import time
import warnings
import function
import torch
from func_timeout import FunctionTimedOut
curPath = os.path.dirname(os.path.abspath(__file__))
rootPath = os.path.abspath(os.path.dirname(curPath) + os.path.sep + "..")
sys.path.append(rootPath)
# logging.basicConfig(level=logging.DEBUG)
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
# app.config['SQLALCHEMY_POOL_SIZE'] = 10 # 设置连接池大小为10
warnings.filterwarnings("ignore")
# 解决 Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing,
# you must use the 'spawn' start method 问题
torch.multiprocessing.set_start_method('spawn')
def init_global_data():
if not hasattr(g, 'global_models'):
logger.info(f"Start initializing model...")
inside_models = InitModels(base_dir=curPath).pre_load_model()
g.global_models = inside_models
logger.info(f"Successfully initialized model!")
if not hasattr(g, 'global_assemble'):
logger.info(f"Start initializing browser...")
# assemble = AssembleTable(repeat_x=False, repeat_y=True)
# assemble.browser = assemble.init_driver()
g.global_assemble = None
logger.info(f"Successfully initialized browser!")
return g.global_models, g.global_assemble
@app.route("/ner", methods=['POST', "GET"])
def main():
all_time_s = time.time()
content_info, lengths, content_object = [], [], {}
data_ids = ""
try:
# models, assemble 可直接調用
models
finally:
gc.collect()
torch.cuda.empty_cache()
return jsonify({"code": 200, "msg": "Predict successful", "result": {}, "data_info": {}})
if __name__ == '__main__':
with app.app_context():
models, assemble = init_global_data()
# 使用 Gevent 服务器
http_server = WSGIServer(('0.0.0.0', 6666), app)
http_server.serve_forever()
4、使用场景
Gevent:
- 适用于需要高并发处理的传统Web应用,网络爬虫,实时聊天应用等。
- 适合需要将现有的阻塞I/O代码转换为非阻塞I/O的场景。
- Uvicorn:
- 适合需要高性能和低延迟的Web服务。
- 适用于现代异步Web框架,如FastAPI和Starlette。