FastAPI - создание и развертывание детектора хот-догов

И научитесь контейнеризовать его с помощью Docker

Я не курю, за исключением особых случаев - Цзянь Ян

Те из вас, кто знаком с популярным сериалом Силиконовая долина, уже догадались, что послужило источником вдохновения для этой статьи.

Персонаж Джимми О. Янга из Кремниевой долины разработал приложение, которое использует компьютерное зрение, чтобы определять, является ли фотография хот-догом или нет.

Сегодня мы рассмотрим, как реплицировать и развернуть такой API с помощью FastAPI и Docker.

FastAPI - одна из самых быстрорастущих веб-фреймворков, которая используется для создания API-интерфейсов на Python.

TL; DR: Репозиторий Github

Набор данных 📊

Набор данных, который я буду использовать, взят от Kaggle. Вы можете найти его здесь.

Обучение модели 🏃

Чтобы обучить нашу модель компьютерного зрения, я решил использовать знаменитую библиотеку Джереми Ховарда Fastai.

Короче говоря, Fastai - это оболочка поверх библиотеки Pytorch, которая позволяет разработчикам быстро разрабатывать модели машинного обучения.

Для обучения нашего классификатора хот-догов мы использовали предварительно обученную модель Resnet34.

Чтобы лучше понять, какие еще варианты были выбраны в процессе обучения, вы можете обратиться к записной книжке Google Colab, которую можно найти здесь.

Как видите, после обучения всего за одну эпоху наша модель достигает точности 95% на проверочном наборе.

Мы видим, что наша модель неплохо работает для образца изображения, взятого из нашего тестового набора.

Создание API 💻

В этом разделе мы создадим API для развертывания нашей обученной модели детектора хот-дога в производственной среде.

Структура проекта

.
├── LICENSE
├── README.md
├── app
│   ├── __init__.py
│   ├── json_models
│   │   ├── __init__.py
│   │   └── request.py
│   ├── main.py
│   ├── models
│   │   ├── __init__.py
│   │   └── model.pkl
│   └── utils.py
├── notebooks
│   └── HotDogOrNot.ipynb
└── requirements.txt

Большая часть соответствующего кода находится в appdirectory. Обратите внимание, что мы создали каталог с именем models, в котором хранится наш обученный файл модели.

Прежде чем мы начнем, обязательно установите все требования, выполнив следующую команду из родительского каталога:

$ pip3 install -r requirements.txt

Давайте посмотрим на наш код.

utils.py

Наш utils.pyfile содержит три функции. Каждая из трех функций служит разным целям:

read_image говорит само за себя. Эта функция помогает считывать данные изображения в виде байтов из запроса и преобразовывать их в соответствующий формат, чтобы использовать их в модели для прогнозов.

is_hotdog - это немного более тонкая функция. Эта функция фактически используется нашим fastai DataLoader для надлежащего предоставления данных нашей модели.

Хотя наша модель была сохранена в .pkl файле после обучения, она не сохраняет функцию is_hotdog в целом.

Вместо этого он сохраняет ссылку на функцию в файле. Следовательно, мы пишем функцию в нашем файле utils, чтобы при загрузке модели она могла успешно искать функцию is_hotdog и работать по назначению.

Для получения дополнительной информации об этом и ImageDataLoaders вы можете прочитать официальную документацию Fastai и эту ветку форума.

Наконец, наша функция predict_hotdog загружает нашу модель, которая будет использовать функцию is_hotdog и выполнять прогнозы. Функция возвращает словарь, который будет служить ответом для нашего API.

response.py

Этот файл, который находится в каталоге json_models, содержит классPydantic для модели ответа нашего API.

Короче говоря, Pydantic - фантастическая библиотека, которая обеспечивает проверку данных с использованием аннотаций типа python во время выполнения.

Эта библиотека особенно полезна для создания API-интерфейсов и имеет превосходную совместимость с FastAPI.

Как мы видим, атрибуты нашего класса Response имеют те же имена, что и ключи нашей функции predict_hotdog.

main.py

Наконец, это файл, который наше приложение будет запускать в производственной среде.

Сначала мы создаем объект класса FastAPI. Затем мы украшаем нашу predict функцию с помощью этого объекта класса. @app.post указывает, что наш запрос будет почтовым запросом, за которым следует путь для нашего API /predict/.

У нас также есть параметр response_model, который принимает нашу модель Pydantic в качестве входных данных. Этот параметр предназначен для проверки нашего ответа во время выполнения.

Наконец, наша predict функция имеет параметр запроса с именем myfile типа UploadFile, который будет использоваться для чтения нашего файла изображения в API.

Эта переменная передается в read_image функцию, которую мы видели раньше, которая преобразует данные нашего изображения в байтах в объект PILImage, который мы можем легко использовать для загрузки нашей модели FastAI.

Наконец, изображение передается в нашу predict_hotdog функцию, которая выполняет прогнозы и возвращает объект словаря в качестве ответа.

Тестирование 📝

Чтобы протестировать API вручную, вам нужно сначала запустить его.

Перейдите в каталог app в вашем репо и введите следующую команду:

$ uvicorn main:app --reload 

Примечание. Следующий отрывок взят непосредственно из документации FastAPI.

Команда uvicorn main:app относится к:

  • main: файл main.py (модуль Python).
  • app: объект, созданный внутри main.py строкой app = FastAPI().
  • --reload: перезапустить сервер после изменения кода. Используйте только для разработки.

На вашем терминале вы должны увидеть следующую строку:

INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit

Откройте http://127.0.0.1:8000/docs в любом браузере.

Вы должны увидеть что-то вроде этого - Пользовательский интерфейс документации Swagger.

Если вы щелкните раскрывающийся список для POST, вы увидите следующее:

Нажмите Попробовать, после чего вам будет предложено загрузить изображение. Как только вы это сделаете, нажмите выполнить, и вы получите следующее:

Обратите внимание, что в дополнение к ответу пользовательский интерфейс также генерирует настраиваемую команду curl, которую вы можете использовать в своем терминале. Довольно аккуратно, правда?

Dockerize 📦

До сих пор мы видели, как успешно развернуть нашу модель детектора хот-дога локально. Однако на практике хотелось бы иметь возможность развернуть такое приложение на любой машине.

Следовательно, лучший способ сделать это - поместить ваше приложение в контейнер с помощью Docker.

Прежде чем продолжить, убедитесь, что в вашей системе установлен Docker. Вы можете установить его здесь.

Мы можем использовать официальный образ Docker, созданный создателем FastAPI, для создания нашего локального образа. Посмотрим на наш Dockerfile:

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 
COPY ./app /app 
COPY requirements.txt requirements.txt 
RUN pip3 install -r requirements.txt

Выполните следующую команду в терминале, чтобы создать образ:

$ docker build -t fastimage .

После этого вы можете запустить образ в контейнере следующим образом:

$ docker run -d --name fastcontainer -p 80:80 fastimage

Если вы откроете localhost/docs в браузере, вы сможете увидеть пользовательский интерфейс Swagger.

Таким образом, теперь мы создали наш образ Docker, который теперь можно отправить в Docker Hub или любой другой реестр контейнеров для использования в производственной среде.

Поздравляю! Вы дошли до конца этой статьи. Надеюсь, вам понравилось это читать. Я оставлю некоторые ресурсы, чтобы узнать больше о FastAPI, FastAI и Docker. До скорого! ✋

Ресурсы 📚