Sobes.tech
Back to questions
Middle+
5

Как оптимизировать сервис, чтобы синхронная CPU-задача (predict модели) не блокировала event loop FastAPI?

Companies where asked
ИннотехИннотех

Answer from AI

sobes.tech AI

В FastAPI, который основан на asyncio и event loop, синхронные CPU-интенсивные задачи, такие как вызов модели predict, могут блокировать event loop и снижать производительность сервиса. Чтобы этого избежать, можно:

  • Вынести CPU-задачу в отдельный поток или процесс. Для этого используют:

    • run_in_threadpool из fastapi.concurrency для запуска в пуле потоков (подходит, если задача не слишком тяжёлая и GIL не сильно мешает).
    • concurrent.futures.ProcessPoolExecutor для запуска в отдельном процессе, что эффективно для CPU-интенсивных задач, так как обходится GIL.
  • Использовать очередь задач (например, Celery, RQ) и выполнять предсказания асинхронно в воркерах, возвращая результат позже.

Пример с ProcessPoolExecutor:

from fastapi import FastAPI
import asyncio
from concurrent.futures import ProcessPoolExecutor

app = FastAPI()
executor = ProcessPoolExecutor()

# Синхронная CPU-задача
 def predict_model(data):
    # тяжелые вычисления
    return "prediction"

@app.get("/predict")
async def predict(data: str):
    loop = asyncio.get_running_loop()
    result = await loop.run_in_executor(executor, predict_model, data)
    return {"result": result}

Такой подход не блокирует event loop и позволяет обрабатывать другие запросы параллельно.