Создайте готовую к работе службу машинного обучения для прогнозирования в реальном времени с помощью FastAPI

Таблица содержания:

  1. "Вступление"
  2. Модель машинного обучения
  3. REST API
  4. Конечная точка прогноза
  5. Локальная разработка vs производство

1. Введение

Существует ряд шаблонов для использования моделей машинного обучения (ML) в производственной среде, например в автономном режиме, в режиме реального времени и потоковой передаче. В этой статье мы подробно рассмотрим, как использовать модели машинного обучения для онлайн-прогнозирования.

Вы можете найти десяток статей на тему «Как создать REST API для машинного обучения». Проблема в том, что почти все они очень поверхностно описывают эту тему. В этой статье мы подробно рассмотрим, в чем разница между локальной и производственной средами, как обновить модель без повторного развертывания, вопросы безопасности.

Для прогнозирования в реальном времени обычно используют REST API, и такая служба делает прогнозы по запросу, обычно через HTTP-вызов [1]. Для построения REST-сервиса мы будем использовать фреймворк FastAPI. FastAPI - это современный высокопроизводительный веб-фреймворк Python с включенными батареями, который идеально подходит для создания RESTful API. Он может обрабатывать как синхронные, так и асинхронные запросы и имеет встроенную поддержку проверки данных, сериализацию JSON [2].

Весь проект Dockerized и доступен в репозитории DanilBaibak / real-time-ml-prediction на GitHub. Не стесняйтесь поэкспериментировать с ним и исследовать код напрямую.

2. Модель машинного обучения.

Прежде чем мы начнем говорить о REST API, нам нужна модель машинного обучения. В этой статье мы будем использовать набор данных о ценах на жилье в Бостоне из наборов данных sklearn [3]. Он содержит 506 экземпляров и 13 числовых и категориальных функций. Нам нужно решить проблему регрессии - спрогнозировать цену дома на основе его свойств.

Конвейер машинного обучения будет довольно стандартным:

  • Числовые характеристики будут масштабироваться с помощью StandardScaler;
  • Категориальные признаки будут кодироваться с помощью OneHotEncoder;

Мы будем использовать регрессию Риджа [4] в качестве нашей модели машинного обучения. Важное примечание - не забудьте исправить случайное состояние, чтобы иметь возможность воспроизвести ваши результаты.

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

  1. Для отслеживания версии модели. В идеале у нас должна быть история обучения модели в базе данных.
  2. Также рекомендуется сохранять метаданные модели после каждого обучения. В долгосрочной перспективе эта информация может дать вам возможность увидеть некоторые критические точки в жизненном цикле модели. Мы уже обсуждали идею мониторинга метаданных модели в другой статье. [5]

3. REST API

После того, как вы подготовили модель машинного обучения, вы можете приступить к созданию сервиса. Как упоминалось ранее, мы создадим REST API, используя фреймворк FastAPI.

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

  • Файл server.py является точкой входа для нашей службы REST API.
  • Мы сохраним артефакты машинного обучения в папке ml_pipelines.
  • Папка models предназначена для хранения схем Pydantic. Он определяет свойства и типы для проверки некоторых данных [6].
  • Скрипт scripts / train.py обучает модель машинного обучения.

3.2 Конечные точки API

Обычно служба ML REST имеет одну конечную точку: «POST / прогноз». Он получает список функций для элемента и возвращает прогноз. Мы рассмотрим этот метод более подробно далее.

Еще одна полезная конечная точка может быть: GET / health. Идея, лежащая в основе этого, исходит из лучших практик микросервисов - быстро вернуть рабочее состояние службы и указание на ее способность подключаться к зависимостям ниже по потоку [7]. Версия модели может быть полезной информацией как часть вывода проверки работоспособности:

  • Проверка наличия последней версии конвейера машинного обучения;
  • Если в вашей команде есть инженеры по обеспечению качества, они могут сообщить о проблеме со ссылкой на версию модели;

4. Конечная точка прогнозирования

Теперь мы подошли к основной части - конечной точке предсказания. Общий алгоритм довольно прост, и вы можете найти его во многих статьях:

  1. Получите запрос;
  2. Загрузите модель;
  3. Сделать прогноз;
  4. Отправить ответ;

Этот подход будет работать в зависимости от объема трафика. Давайте посмотрим, как мы можем это улучшить.

4.1 Кэширование модели

Одно из важных требований службы REST - задержка. Загрузка модели для каждого запроса занимает много времени. Мы можем ввести локальный кеш - это позволяет нам загрузить модель один раз. Следующий запрос будет использовать кешированную модель. Это ускорит время отклика.

4.2 Загрузите новую версию модели

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

Мы уже подготовили отдельную таблицу для хранения версии конвейера ML и локального кеша - этого должно хватить для реализации логики загрузки последней версии модели. Нам нужно обновить конечную точку прогноза следующим образом:

После того, как новый конвейер машинного обучения обучен, сохранен и последняя версия будет сохранена в базе данных, API будет использовать новейшую модель. Этот подход также будет работать, если у вас есть несколько сервисов с балансировщиком нагрузки [8].

4.3 Сохранение прогнозов

Что касается производственного приложения ML, недостаточно просто делать прогноз. Остаются два важных вопроса:

  1. Как вы будете следить за качеством прогнозов?
  2. Как вы организуете сбор данных для будущего обучения модели?

Чтобы ответить на оба вопроса, вам нужно начать хранить прогнозы. Но если мы просто добавим логику для сохранения прогнозов для каждого запроса, это повлияет на задержку. FastAPI поможет нам решить эту проблему. Одной из наиболее интересных особенностей FastAPI является то, что он из коробки поддерживает асинхронный код с использованием ключевых слов Python async / await [9].

Нам нужно добавить ключевое слово async в функцию, которая сохраняет данные в БД и в функцию конечной точки. Затем добавьте ключевое слово await при сохранении прогноза в БД. Теперь мы можем хранить исторические данные, не влияя на задержку.

Окончательная версия конечной точки прогноза будет выглядеть так:

5. Местная разработка и производство

Чтобы развернуть наш сервис в производственной среде, нам нужно докеризовать наш код. Теоретически нам нужно обернуть наше приложение в Docker согласно документации [10], и все готово. Но есть еще пара важных моментов, на которые следует обратить внимание.

5.1 Местное развитие

Даже после развертывания вам все равно нужно продолжить работу над проектом. Как вы помните, мы используем базу данных для хранения версии конвейера машинного обучения и прогнозов. Мы будем использовать Docker Compose для настройки БД и применения миграции.

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

Обратите внимание, что мы используем отдельный Dockerfile. У вас также может быть отдельный файл requirements.txt для локальной разработки. Это позволяет вам иметь практическую рабочую среду и не перегружать производственный образ Docker.

5.2 Документация по API

FastAPI предоставляет движок документов API из коробки. Если вы посетите http: // localhost / docs, вы увидите автоматическую интерактивную документацию API (предоставляемую Swagger UI) [11]. Это может быть полезно для локальных или промежуточных сред. Но, в зависимости от вашего проекта, вы можете не захотеть иметь открытую конечную точку документации в производственной среде. Легко реализовать:

Также может быть хорошей идеей изменить URL-адрес документации по умолчанию.

5.3 Требования безопасности

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

Резюме

  1. Задержка - одно из важных требований для службы REST. Кэшируйте конвейер машинного обучения и по возможности используйте асинхронный код.
  2. Правильно организованное хранилище для конвейерных версий машинного обучения играет ключевую роль в организации конвейерных обновлений без повторного развертывания.
  3. Отображение версии конвейера машинного обучения как части конечной точки проверки работоспособности может быть полезно для отслеживания ошибок во время разработки.
  4. Создайте безопасное приложение! Заблокируйте доступ к конфиденциальной информации.
  5. Использование docker-compose, отдельного Dockerfile и даже отдельного файла requirements.txt позволяет осуществлять локальную разработку без перегрузки производственной среды Образ Docker.

Вы можете найти полный проект в репозитории DanilBaibak / real-time-ml-prediction с инструкциями по его настройке и использованию.

Использованная литература:

  1. "Изобразительное State Transfer"
  2. FastAPI
  3. Набор данных о ценах на жилье в Бостоне
  4. Sklearn.linear_model.Ridge
  5. Машинное обучение в производстве с использованием Apache Airflow
  6. Пидантические модели
  7. Внедрить API проверки работоспособности для микросервисов
  8. "Балансировка нагрузки"
  9. Параллелизм и асинхронность / ожидание
  10. Развертывание FastAPI с Docker
  11. Документация по интерактивному API FastAPI