Многопоточность и контроль использования ОЗУ в режиме riseapi

Добрый день!

Спасибо за отличную библиотеку и проделанную большую работу! Пользоваться приятно и решает много насущных задач!

Со временем накопились вопросы. Согласно документации, можно взять готовую предобученную модель, поднять ее на определенном порту, отправлять к ней запросы по REST и получать ответы. Очень удобно:

python -m deeppavlov riseapi <config_path> -p 8888

Можете раскрыть принципы и дать рекомендации, как лучше эксплуатировать модель под нагрузкой и как этим лучше управлять в конфиге? В дефолтном конфиге сервера не могу найти опций для этого.

Интересно, как регулируется объем ОЗУ для запущенной на указанном порту модели? Вот запускаем через riseapi одну модель на порту. По информации из лога видно, что используется асинхронный неблокирующий веб-сервер Uvicorn - отличное решение. Модель заняла в ОЗУ 2 ГБ. Вот пошла нагрузка:

  1. Запросы к этому экземпляру модели будут накапливаться в очереди и обслуживаться одним экземпляром модели в один поток (последовательно, запрос за запросом), т.е. расход памяти будет оставаться 2ГБ?
  2. Запросы будут накапливаться в очереди и отправляться многопоточно к одному экземпляру модели? А если это tensorflow, а если это pytorch? Решение потокобезопасно? Сколько будет запущено потоков в этом случае? Вырастет ли потребление ОЗУ грубо и насколько и как этим можно управлять через конфиг?
  3. Запросы будут накапливаться в очереди и в зависимости от нагрузки (настраивается?) поднимется еще один экземпляр модели и расход ОЗУ станет 2ГБ + 2ГБ, зато запросы обрабатываются быстрее? А если память на сервере закончится, как этим можно управлять через конфиг?
  4. Аналогичные вопросы, но с учетом использования GPU с ограниченной памятью.

Дайте, пожалуйста, рекомендации. Спасибо!

1 Like

Добрый день, @serbul

Запросы обрабатываются последовательно, в один поток, в независимости от того используется TF-модель или Pytorch. Новые запросы добавляются в очередь. Расход ОЗУ вырастет после первого “прогревочного” запроса, затем он будет оставаться примерно на одном уровне (c памятью GPU аналогично).

В последнем релизе 0.13.0 мы добавили мерики для Prometheus (ссылка). Вы можете сделать get-запрос на эндпоинт /metrics и получить статистику в т.ч. и по использованию памяти.

Динамического масштабирования в DeepPavlov нет. У себя при деплое мы поднимаем несколько экземпляров модели, если ожидаем что один инстанс не справится с планируемой нагрузкой. Запросы поступают на load_balancer, а он уже распределяет их по инстансам модели. В метриках есть статистика со временем обработки запроса, можно принимать решение об увеличении числа воркеров ориентируясь на это время.

1 Like

Спасибо большое за подробный ответ. Все максимально стало ясно. Будем использовать ваши рекомендации активно в наших проектах.