Как настроить параллельный запуск ML-моделей в FastAPI?

Ссылка скопирована
1 ответ

Поднял сервис на FastAPI, в который планируется направлять GET-запросы на обработку аудиофайла.
При отправке GET-запроса происходит чтение некоторого аудиофайла, а затем он направляется в ML-модель.
Последний этап занимает наибольшее время.
Так и не смог понять, как настроить процесс так, чтоб N-е число пользователей могли направлять параллельно запросы, и каждый из запросов (в пределах доступных ресурсов) модель бы параллельно обрабатывала и возвращала по итогу обработки.

Примерный код основного функционала сервиса:

from fastapi import FastAPI from ml_models import AudioModel  ml_models = {}  @asynccontextmanager async def ml_model_lifespan(app: FastAPI):      # add model-1     ml_models ["MODEL_1"] = AudioModel(**kwargs)     # add model-2     ml_models ["MODEL_2"] = AudioModel(**kwargs)     yield     # code to execute when app is shutting down     ml_models .clear()  app = FastAPI(title="ML model service", lifespan=ml_model_lifespan)  @app.get("/start") async def run_ml_model(filepath, model_id):     result = ml_models[model_id].predict(filepath)     return {"code": 200, "data": result}

from fastapi import FastAPI from ml_models import AudioModel ml_models = {} @asynccontextmanager async def ml_model_lifespan(app: FastAPI): # add model-1 ml_models ["MODEL_1"] = AudioModel(**kwargs) # add model-2 ml_models ["MODEL_2"] = AudioModel(**kwargs) yield # code to execute when app is shutting down ml_models .clear() app = FastAPI(title="ML model service", lifespan=ml_model_lifespan) @app.get("/start") async def run_ml_model(filepath, model_id): result = ml_models[model_id].predict(filepath) return {"code": 200, "data": result}

Дополнительно:

Показывайте, что именно не получилось.

  • Сколько времени занимает подготовка ответа на один GET запрос при обработки ML-моделью в FastAPI?
  • Михаил Р., Иерокопус Таманский, Добавил код в текст вопроса
  • Martin_AIDEN, если AudioModel.predict синхронная (что логично - вычислительная задача же), то неудивительно, что при её вызове всё встаёт.

    Так что... Треды, мультипроцессинг, отдельный сервис через брокер очередей типа rabbitmq (можно мультитредовый/мультипроцессный или просто запустить N инстансов - брокер очередей умеет гарантировать раздачу задачи только одному инстансу), можно ещё сделать отдельный сервис с uwsgi и достаточным числом воркеров... В общем, варианты есть.

  • shurshur, это выглядит как достойный ответ. Мы ведь не гоняемся за 100% решений в профиле, так?
  • Иерокопус Таманский, я не гонюсь, но обычно мне лень делать нормальные ответы и я часто пишу спонтанные мысли в комментарии.
  • Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Никита Орлов Ответ

    Для настройки параллельного запуска ML-моделей в FastAPI, вы можете воспользоваться библиотекой `concurrent.futures` для запуска нескольких моделей одновременно. Прежде всего, убедитесь, что у вас установлен Python версии 3.7 или выше, так как `concurrent.futures` доступен только в этих версиях.

    Вот пример кода, демонстрирующий параллельный запуск ML-моделей в FastAPI:

    from fastapi import FastAPI
    import concurrent.futures
     
    app = FastAPI()
     
    def predict_model1(input_data):
        # Ваш код для модели 1
        return prediction_model1
     
    def predict_model2(input_data):
        # Ваш код для модели 2
        return prediction_model2
     
    @app.post("/predict")
    async def predict(input_data: dict):
        with concurrent.futures.ThreadPoolExecutor() as executor:
            future_model1 = executor.submit(predict_model1, input_data)
            future_model2 = executor.submit(predict_model2, input_data)
     
            prediction_model1 = future_model1.result()
            prediction_model2 = future_model2.result()
     
        return {"prediction_model1": prediction_model1, "prediction_model2": prediction_model2}

    from fastapi import FastAPI import concurrent.futures app = FastAPI() def predict_model1(input_data): # Ваш код для модели 1 return prediction_model1 def predict_model2(input_data): # Ваш код для модели 2 return prediction_model2 @app.post("/predict") async def predict(input_data: dict): with concurrent.futures.ThreadPoolExecutor() as executor: future_model1 = executor.submit(predict_model1, input_data) future_model2 = executor.submit(predict_model2, input_data) prediction_model1 = future_model1.result() prediction_model2 = future_model2.result() return {"prediction_model1": prediction_model1, "prediction_model2": prediction_model2}

    В этом примере мы создаем две функции `predict_model1` и `predict_model2`, которые содержат код для каждой из ML-моделей. Затем мы создаем эндпоинт `/predict`, который принимает входные данные и использует `concurrent.futures.ThreadPoolExecutor` для запуска обеих моделей параллельно.

    Когда обе модели завершат свою работу, результаты будут объединены и возвращены в формате JSON.

    Этот подход позволяет улучшить производительность вашего приложения, запуская ML-модели параллельно и эффективно использовать ресурсы вашего сервера. Не забудьте адаптировать этот код под ваши конкретные ML-модели и требования вашего приложения.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно