如何在Flask中先渲染页面再执行深度学习模型后台训练任务?
解决方案:Flask中异步执行深度学习训练任务
兄弟,这个问题我太熟了!Flask默认是同步处理请求的,你现在的写法里network.train(...)会把整个请求卡住,必须等训练完才会返回页面。要实现先渲染页面再跑训练,核心就是把训练逻辑放到后台异步执行,下面给你两个实用的方案:
方案一:用Python内置线程快速实现(适合小型项目/原型)
这个方案不用额外装依赖,直接利用Python的threading模块把训练逻辑放到子线程,主线程先返回页面给用户,子线程在后台默默跑训练。
修改你的代码如下:
from threading import Thread from flask import Flask, request, render_template app = Flask(__name__) # 把训练逻辑抽成单独的函数,供子线程调用 def background_train(architecture): network = get_architecture(architecture) network.train(...) # 你的训练代码,这里阻塞也不影响主线程 @app.route('/train', methods=['POST']) def train(): architecture = request.form.get('architecture', str) # 启动子线程执行训练 train_thread = Thread(target=background_train, args=(architecture,)) train_thread.daemon = True # 设置为守护线程,Flask退出时自动结束任务 train_thread.start() # 先返回页面,把用户传入的参数也传过去展示 return render_template("begin_training.html", architecture=architecture)
优缺点:
- ✅ 优点:零额外依赖,代码改动极小,快速实现需求
- ❌ 缺点:如果Flask进程重启/崩溃,后台训练任务会直接中断;没法追踪训练进度和状态
方案二:用Celery异步任务队列(适合生产环境)
如果你的项目需要稳定的后台任务管理、状态追踪甚至分布式训练,Celery是工业级的解决方案。它需要搭配一个消息中间件(比如Redis或RabbitMQ)来管理任务队列。
步骤1:安装依赖
pip install celery redis
步骤2:配置Celery并定义异步任务
from flask import Flask, request, render_template, jsonify from celery import Celery app = Flask(__name__) # 配置Redis作为消息队列和结果存储 app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0' app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0' # 初始化Celery celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL']) celery.conf.update(app.config) # 定义异步训练任务 @celery.task def train_task(architecture): network = get_architecture(architecture) network.train(...) # 你的训练逻辑 return "训练完成!" @app.route('/train', methods=['POST']) def train(): architecture = request.form.get('architecture', str) # 把任务发送到Celery队列,立即返回任务ID task = train_task.delay(architecture) # 返回页面,同时把任务ID传给前端,方便后续查询状态 return render_template("begin_training.html", architecture=architecture, task_id=task.id) # 新增路由:查询训练任务状态 @app.route('/task_status/<task_id>') def task_status(task_id): task = train_task.AsyncResult(task_id) if task.state == 'PENDING': response = { 'state': task.state, 'status': '训练正在进行中...' } elif task.state == 'SUCCESS': response = { 'state': task.state, 'status': task.result } else: # 处理失败/重试等状态 response = { 'state': task.state, 'status': f"训练异常:{str(task.info)}" } return jsonify(response)
步骤3:启动Celery Worker
在终端运行以下命令启动Celery worker来处理任务:
celery -A your_flask_app_name worker --loglevel=info
优缺点:
- ✅ 优点:任务持久化,进程重启也不会丢失;支持任务状态查询、重试、分布式部署;适合生产环境
- ❌ 缺点:需要额外配置消息中间件,学习成本略高
额外优化:前端展示训练状态
用方案二的话,你可以在begin_training.html里加一段AJAX代码,定时请求/task_status/<task_id>接口,实时更新训练状态给用户,体验会更好。
内容的提问来源于stack exchange,提问作者Rocket Pingu
相关产品推荐
相关产品推荐

