我正在开发一个多处理Python应用程序,其中多个进程需要访问大型的、预加载的spaCy NLP模型(例如en_core_web_lg)。由于该模型是内存密集型的,因此我希望避免在每个进程中单独加载它,因为我很快就会耗尽主内存并且该对象是只读的。相反,我想在共享位置加载一次,以便所有进程都可以从中读取数据,而不会重复使用内存。
我研究了 multiprocessing.Manager 和 multiprocessing.shared_memory,但这些方法似乎更适合 NumPy 数组、原始数据缓冲区或简单对象,而不是像 NLP 模型这样具有内部引用的复杂对象。我还研究了 MPI 的 MPI.Win.Allocate_shared() 但遇到了同样的问题。使用 Redis 服务器并使排名 0 与 MPI 一起完成所有处理工作,但由于所有处理都是由单个排名完成的,因此它违背了我使用多处理的建议。
有没有一种有效的方法可以在Python中跨多个进程共享spaCy模型实例,以避免为每个进程重新加载它?
是否有专门适合跨进程共享内存中复杂的只读对象(例如 NLP 模型)的库或技术?
如果 multiprocessing.Manager 或共享内存在这里可行,那么在处理复杂对象时是否有方法可以提高性能或减少内存开销?
任何建议或示例将不胜感激!谢谢!
我强烈建议您不要像对待任何其他 Python 对象一样对待 NLP 模型。我总是更喜欢使用微服务方法加载 NLP 模型,通过将模型逻辑与主应用程序分离,这种方法更符合 ML/软件工程最佳实践。
无需在每个进程中加载模型(这可能会占用大量内存),而是在专用服务中仅加载模型一次。此设置允许应用程序的多个部分使用模型,而无需重复内存使用,从而使其高效、模块化且可扩展。不仅解决了您对内存效率的担忧,而且还提高了可扩展性和模块化性。
使用 FastAPI + Docker 实现此类微服务的示例如下所示:
# main.py: FastAPI service with spaCy model
from fastapi import FastAPI
import spacy
app = FastAPI()
nlp = spacy.load("en_core_web_lg") # Load model once
@app.post("/process/")
async def process_text(text: str):
doc = nlp(text)
return {"tokens": [(token.text, token.pos_) for token in doc]}
将上述 FastAPI 服务容器化:
# Dockerfile for the NLP model microservice
FROM python:3.9-slim
COPY requirements.txt .
RUN pip install -r requirements.txt && python -m spacy download en_core_web_lg
COPY . /app
WORKDIR /app
CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "main:app"]