Sobes.tech
Middle+
51

¿Cómo optimizar el servicio para que una tarea sincrónica de CPU (modelo predictivo) no bloquee el event loop de FastAPI?

Empresas donde se preguntó
ИннотехИннотех

Respuesta de la IA

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 и позволяет обрабатывать другие запросы параллельно.