загрузка моделей в проекты FastAPI при запуске

#deployment #fastapi

#развертывание #fastapi

Вопрос:

итак, в настоящее время я работаю над проектом FastAPI, который обслуживает несколько служб NLP. Для этого я хочу предоставить различные модели из spacy, а также huggingface.

Поскольку эти модели довольно большие, время вывода при загрузке моделей для каждого запроса post довольно велико. Моя идея состоит в том, чтобы загрузить все модели при запуске FastAPI (в app/main.py ), однако я не уверен, является ли это хорошим выбором / идеей или у этого подхода есть какие-то недостатки, поскольку модели будут находиться в кэше (?). (Информация: я хочу настроить проект и впоследствии развернуть его на виртуальной машине)

До сих пор я не смог найти никаких указаний в Интернете, поэтому я надеюсь получить хороший ответ здесь 🙂

Заранее спасибо!

Ответ №1:

Если вы развертываете свое приложение с использованием gunicorn uvicorn worker stack. Вы можете использовать gunicorn --preload флаг ‘s.

Из документации gunicorn

предварительная загрузка_app

—предварительная загрузка по умолчанию: False

Загрузите код приложения до того, как рабочие процессы будут разветвлены.

Предварительно загрузив приложение, вы можете сэкономить некоторые ресурсы оперативной памяти, а также ускорить время загрузки сервера. Хотя, если вы откладываете загрузку приложения для каждого рабочего процесса, вы можете легко перезагрузить код приложения, перезапустив workers.

Вам просто нужно использовать --preload flag с вашими параметрами запуска.

 gunicorn --workers 2 --preload --worker-class=uvicorn.workers.UvicornWorker my_app:app
 

Комментарии:

1. Привет, Ягиз, спасибо за ваш ответ — поэтому вместо загрузки моделей в «main.py » Я должен придерживаться своего текущего кода и просто запускать приложение с gunicorn и установленным флагом —preload? К вашему сведению: в настоящее время я загружаю модели с помощью пользовательского класса, который вызывается при выполнении запроса POST. p.s. Я пока не могу отказаться от голосов:(

2. Эй, я думаю, вы можете использовать одноэлементный подход. Объявите модель один раз в вашем main.py . Затем используйте это, оно загрузит модель один раз в память, насколько я понимаю, вы создаете новый экземпляр класса для каждого запроса, что означает, что вы загружаете эту модель в память для каждого запроса, верно?

3. точно! Я изменю свой код в соответствии с вашей рекомендацией — большое спасибо! 🙂

4. @YagizDegirmenci: не могли бы вы проверить, правильно ли я это понимаю? Если мы используем --preload флаг, основной поток gunicorn загружает приложение при загрузке, а затем, когда рабочие разветвляются, они получают копию приложения? Если это так, будет ли приложение, загруженное рабочими, использовать одно и то же пространство памяти? Есть ли какие-либо оговорки к этому подходу, о которых мне нужно знать? Спасибо.

5. @coczor Вы пробовали одноэлементный подход? Как вы сделали объекты модели доступными через маршрутизатор API?