Docker容器中Flask应用下载HuggingFace模型后持续重启求助
问题分析与解决方案
看起来你的问题核心是uWSGI的prefork运行模式与大模型加载的冲突,结合日志里反复出现的Instantiating model就能看出:每次uWSGI启动worker进程时,都会重新执行app.py里的全局代码——也就是模型初始化的部分。这不仅会重复触发模型下载,更关键的是bert-large-cased这类大模型内存占用极高,多个worker同时加载很容易把容器内存耗尽,导致worker被系统杀死,进而触发uWSGI重启worker,形成无限循环。
下面是针对性的解决方案:
方案1:让模型只在uWSGI Master进程加载,共享给所有Worker
uWSGI支持在Master进程中预加载资源,再通过fork让所有Worker共享,这样就能避免重复初始化模型。
第一步:修改uWSGI配置(/etc/uwsgi/uwsgi.ini)
[uwsgi] # 保留你原有配置的基础上,添加/修改以下项 master = true # 启用Master进程模式 preload-app = true # 让Master进程预加载应用 workers = 2 # 减少Worker数量(根据容器内存调整,1.5G内存建议最多2个) single-interpreter = true
第二步:调整app.py的模型初始化逻辑
确保模型只在Master进程中加载,Worker直接共享:
import os from flask import Flask from flask_cors import CORS from transformers import AutoModelForTokenClassification, AutoTokenizer, pipeline import logging log = logging.getLogger(__name__) server = Flask(__name__) cors = CORS(server) server.config["CORS_HEADERS"] = "Content-Type" # 全局变量声明 model = None tokenizer = None pipe = None def init_model(): """初始化模型的函数,仅在Master进程执行""" global model, tokenizer, pipe log.info("Instantiating model") model = AutoModelForTokenClassification.from_pretrained('dbmdz/bert-large-cased-finetuned-conll03-english') tokenizer = AutoTokenizer.from_pretrained('bert-base-cased') pipe = pipeline('ner', model=model, tokenizer=tokenizer) # 判断运行环境:uWSGI Master进程加载模型,本地调试直接加载 try: import uwsgi if uwsgi.masterpid() == os.getpid(): init_model() except ImportError: init_model() if __name__ == "__main__": server.run(host=appconf.host, port=appconf.port, debug=appconf.isdev, use_reloader=False)
方案2:提前在Docker构建阶段下载模型,避免重复下载
每次启动容器都重新下载模型既慢又容易出问题,你可以在Docker构建时就把模型缓存到容器内:
在你的Dockerfile中添加以下指令:
# 安装依赖后,提前下载模型到容器缓存目录 RUN python -c "from transformers import AutoModelForTokenClassification, AutoTokenizer; \ AutoModelForTokenClassification.from_pretrained('dbmdz/bert-large-cased-finetuned-conll03-english'); \ AutoTokenizer.from_pretrained('bert-base-cased')"
这样模型会被保存到容器的~/.cache/huggingface/hub目录,启动时直接加载本地缓存,不会再触发网络下载。
方案3:确保容器有足够的内存资源
bert-large-cased-finetuned-conll03-english模型加载后大概会占用1.5-2GB内存,加上Worker进程的开销,建议给容器分配至少4GB内存:
# 运行容器时指定内存限制 docker run --memory=4g ...
另外可以在容器内检查内存使用情况,确认是否存在内存溢出:
docker exec <容器ID> free -h
内容的提问来源于stack exchange,提问作者tenticon
相关产品推荐
相关产品推荐

