Разработка, документирование, развертывание и типизация
Многие из вас, возможно, слышали о FastAPI или даже читали мою статью о нем. FastAPI, как следует из названия, представляет собой платформу ASGI на основе Python, которая намного быстрее, чем Django и Flask. Он поставляется с Pydantic и Starlette и доказывает, что является лучшим py-кандидатом.
Приступая к делу, в этой статье предполагается, что у вас уже настроен FastAPI с uvicorn для сервера. Мы собираемся использовать замороженную модель, обученную на наборе данных MNIST, который можно найти здесь — Github. Загрузите это и поместите в свою основную папку.
Теперь напишем файл нашего сервера — main.py. Давайте сначала напишем статический код, в котором мы создаем экземпляр сервера, и загружаем модель.
Чтобы загрузить модель, мы пишем следующее: —
import tensorflow.compat.v1 as tf frozen_file_path = 'mnist.model.best.hdf5' print("Loading Model") model_graph = tf.Graph() new_model = tf.keras.models.load_model(frozen_file_path)
Чтобы создать экземпляр сервера, мы импортируем и вызываем следующее
from fastapi import FastAPI app = FastAPI()
Теперь мы пишем конечные точки для вызова модели для случайного изображения.
@app.get("/random_prediction") async def predict_random(): rand_int = random.randint(0,len(X_test)) print(rand_int) random_image_data = X_test[rand_int] rand_image = Image.fromarray(random_image_data,'L') y_out = await new_model.predict(numpy.expand_dims(random_image_data,axis=0)) predicted_value = numpy.where(y_out[0]==1)[0][0] return {"prediction": predicted_value}
Убедитесь, что вы импортируете данные для MNIST из keras, используя
from keras.datasets import mnist (X_train, y_train), (X_test, y_test) = mnist.load_data()
Давайте рассмотрим другой пример, когда входные данные являются числовыми или категориальными. Теперь мы получаем входные данные из нашего внешнего интерфейса, когда пользователь обращается к нашему API. Чтобы использовать поддержку Pydantic, мы будем вводить нашу модель ввода, например:
@app.post("/input_predict") def get_output_category(data: InputType): predicted_output = model.predict([[**data.dict()]]) return {'prediction': predicted_output}
Это полезно, так как автоматически обрабатывает случаи неверного ввода. Кроме того, этот InputType также отображается в сгенерированных документах API.
InputType должен быть определен в другом (предпочтительном) файле с использованием базовой модели Pydantic.
from pydantic import BaseModel from typing import Optional class InputType(BaseModel): input_field1: float input_field2: Optional[float] = 0.1 ...
Теперь FastAPI также позволяет HTMLResponse, если вы хотите напрямую генерировать HTML. Также для людей, имеющих опыт работы с Jinja и Django, можно использовать шаблоны Jinja2, доступные в FastAPI. Подробнее здесь.
Автоматически сгенерированные документы по умолчанию размещаются по адресу http://127.0.0.1:8000/docs и автоматически отображают информацию о ваших конечных точках, ожидаемом типе данных и типе возвращаемого значения, если он указан. Это полезно, если вы не хотите создавать модный интерфейс для своего веб-приложения, поскольку документы swagger интерактивны.
Вы можете не только отправить запрос (POST, GET, PUT, DELETE), но и указать данные по умолчанию для каждой конечной точки. Вы также можете включить информацию в описание каждой конечной точки, поля и схемы.
Чтобы использовать поддержку ASGI, вы можете определить функцию с префиксом async и вызывать другие асинхронные утилиты, используя префикс await. Это особенно полезно в случае обработки больших данных, обучающих моделей и приложений компьютерного зрения.
У FastAPI есть очень классный пример того, как работает параллелизм и асинхронный код с использованием бургеров! Проверьте, что здесь. Используя асинхронные методы, вы можете обучать свою модель параллельно, продолжая обслуживать API, и даже выполнять прогнозирование модели для большого объема данных и отображать выходные данные после их получения.
Для развертывания в Docker вы можете использовать следующий образ в качестве базового образа и скопировать содержимое своего приложения, чтобы создать собственный образ Docker.
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 COPY ./app /app
Поскольку у нас также будут внешние библиотеки, нам придется установить их в наш файл докера. Это можно сделать с помощью команды run pip следующим образом:
RUN pip install -r requirements.txt
Если в вашем проекте нет файла requirements.txt, вы можете просто установить библиотеки, включив
RUN pip install sklearn numpy tensorflow tensorflow-gpu
и любые другие библиотеки, которые вы использовали.
Вывод
Поскольку большинство из вас пришли сюда из Flask, вы можете увидеть сходство с Flask. Но что делает FastAPI лучше, помимо скорости, так это поддержка ASGI. У нас также могут быть автоматически сгенерированные документы из FastAPI, которые действительно полезны. FastAPI — это недостающая золотая середина между Django и flask. Хотя для Data Scientist или разработчика машинного обучения Django — это излишество. FastAPI обеспечивает столь необходимое превосходство, когда речь идет о скорости и асинхронных вызовах.
Ссылки
- https://fastapi.tiangolo.com/tutorial/response-model/
- https://fastapi.tiangolo.com/deployment/docker/
- Привет этому простому проекту GitHub, который можно клонировать и запустить, чтобы увидеть базовую модель RF, работающую с FastAPI https://github.com/kaustubhgupta/FastAPI-Demo