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

Цели

Главная задача этой статьи — перечислить и описать системные паттерны для проектирования систем машинного обучения в производственной среде. Паттерны проектирования, которые помогают в разработке моделей машинного обучения, достигающих определенных показателей точности, не являются приоритетом, хотя для некоторых из перечисленных паттернов такие юзкейсы все-таки будут указаны.

Минимальные требования

Все системные паттерны машинного обучения, приведенные здесь, предназначены для развертывания в публичной облачной среде или на кластере Kubernetes. В рамках подготовки обзора мы пытались максимально абстрагироваться от конкретных языков программирования или платформ, хотя, поскольку Python является наиболее значимым языком для технологии машинного обучения, большинство шаблонов можно реализовать с применением Python.

Источник

Полный список всех паттернов можно найти здесь:
GitHub Pages

Примеры реализации

Некоторые примеры реализации доступны по ссылке ниже: https://github.com/shibuiwilliam/ml-system-in-actions

Паттерны

Паттерны проектирования обслуживающих систем

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

Паттерн “Единый веб-сервер” (Web single pattern)

Применение

  • Когда вам нужно быстро зарелизить предиктор в самой простой архитектуре.

Архитектура

Паттерн “Единый веб-сервер” предлагает архитектуру, в рамках которой все артефакты и код для модели прогнозирования заключены в одном веб-сервере. Поскольку в этом паттерне REST (или GRPC) интерфейс, предварительная обработка и обученная модель находятся в одном месте (на сервере), вы можете создать и развернуть их в виде простого предиктора.
Если вам нужно развертывать сразу несколько реплик, для доступа к ним вам придется реализовать балансировщик нагрузки или прокси-сервер. Если вы используете в качестве интерфейса GRPC, то вам всерьез стоит подумать о реализации балансировки нагрузки на стороне клиента или layer-7 балансировщика.

Чтобы встроить вашу модель в веб-сервер, вы можете воспользоваться паттерном “модель в образе” или паттерном с загрузкой модели.

Диаграмма

Плюсы

  • Возможность использовать один язык программирования, например Python, для веб-сервера, предварительной обработки и логического вывода.

  • Удобен в управлении из-за своей простоты.

  • Проще устранять неполадки.

  • Минимальные затраты времени на дообучение модели.

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

Минусы

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

  • Обновления также потребуют развертывания сервиса, что в более крупных организациях требует выполнения серьезного SDLC.

О чем нужно подумать

  • Процедуры обновления и обслуживания для каждого компонента.

  • Масштабирование предполагает изменения в управлении веб-сервером.

Пример

https://github.com/shibuiwilliam/ml-system-in-actions/tree/main/chapter4_serving_patterns/web_single_pattern

Паттерн синхронной обработки (Synchronous pattern)

Применение

  • Вывод модели блокирует переход к следующему шагу в вашей бизнес-логике.

  • Когда ваш рабочий процесс зависит от вывода.

Архитектура

Паттерн синхронной обработки реализует синхронный процесс прогнозирования. В нем рабочий процесс блокируется до завершения прогнозирования. Если вы разрабатываете сервер логических выводов c REST или GRPC, то скорее всего он будет реализовывать паттерн синхронной обработки. Это один из самых простых в использовании паттернов, поскольку весь его рабочий процесс можно визуализировать простым пошаговым алгоритмом.

Диаграмма

Плюсы

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

  • Рабочий процесс сервиса тоже довольно прост, поскольку процесс не будет продолжаться, пока прогноз не завершится.

Минусы

  • Задержка прогнозирования может стать узким местом в производительности.

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

  • Если клиентом вашего сервиса является другой сервис, то этот шаблон неминуемо станет причиной блокировки потоков на стороне клиента.

О чем нужно подумать

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

  • Требуются тайм-ауты, если задержка слишком велика.

Пример

https://github.com/shibuiwilliam/ml-system-in-actions/tree/main/chapter4_serving_patterns/synchronous_pattern

Паттерн асинхронной обработки (Asynchronous pattern)

Применение

  • Когда текущий процесс не зависит от предсказания.

  • Чтобы отделить клиента, который делает запрос прогнозирования, от места назначения, где ожидается ответ.

Архитектура

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

Кроме того, как в случае, описанном на Диаграмме 1, так и для Диаграммы 2, вы можете заставить сервер прогнозов передавать результат другому компоненту. Но это требует от вас тщательной проработки такого варианта использования. так как и система, и сам рабочий процесс становятся довольно сложным.

Диаграмма

Диаграмма 1

Диаграмма 2

Плюсы

  • Вы можете разделить клиент и прогнозы.

  • Клиенту не нужно ждать, пока будет сгенерирован прогноз.

Минусы

  • Требуется очередь, кэш или какой-нибудь другой посредник.

  • Не подходит для использования в реальном времени.

О чем нужно подумать

  • Как запустить предсказание:

    • Очередь: прогноз будет FIFO 

    • Кэш: зависит от доступного кэша

    • PubSub: подписка предиктора на запуск предсказания

  • Необходимо учитывать ошибку прогнозирования:

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

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

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

Пример

https://github.com/shibuiwilliam/ml-system-in-actions/tree/main/chapter4_serving_patterns/asynchronous_pattern

Паттерн пакетной обработки (Batch pattern)

Применение

  • Если нет необходимости в прогнозировании в реальном или почти реальном времени.

  • Если прогнозы должны отрабатываться для большого количества данных.

  • Если запуск прогнозов можно запланировать; ежечасно, ежедневно, еженедельно или ежемесячно.

Архитектура

Если вам не нужно запускать прогнозы в реальном времени, вы можете реализовать паттерн пакетной обработки для запуска прогнозов с желаемым интервалом. Вы можете запланировать пакетное прогнозирование для большого количества данных на регулярной основе, например, ежедневно, и сохранять результаты. Конечно, вы также можете выполнять прогнозы ежечасно или даже ежемесячно, в зависимости от ваших потребностей. Этот паттерн требует, чтобы сервер управления задачами запускал пакетную задачу (batch job). Управляющий сервер запустит задачу в соответствии с заданными вами правилами. Сервер прогнозирования будет развернут в рамках запуска пакетной задачи. Если вы используете какой-нибудь облачный сервис или Kubernetes, привязка запуска и удаление сервера к задачам позволит вам значительно сократить расходы, поскольку сервер не должен будет работать круглосуточно и без выходных.

Диаграмма

Плюсы

  • Вы можете гибко управлять ресурсами сервера в строгом соответствии со спросом.

  • Вы можете перезапустить задачу в случае ошибки.

  • В вашей серверной системе нет требований к высокой доступности.

Минусы

  • Вам нужен сервер для управления задачами.

О чем нужно подумать

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

  • Если у вас есть определенное ограничение по времени на получение результатов прогнозирования, то вам необходимо будет брать в расчет расписание пакетных задач и ресурсы сервера. Если обработка пакета приходится на ночь, то скорее всего вам будет успеть закончить работу к следующему утру.

  • Варианты перезапуска задачи в случае сбоя:

    • Повторить все: повторно выполнить прогноз для всего пакета. Используется, когда прогноз или данные имеют какие-либо взаимозависимости.

    • Частичная повторная попытка: повторно запустить набор данных, в котором произошел сбой. Используется при отсутствии зависимости.

    • Без повторных попыток: запустить прогноз для давшего сбой набора данных в следующем пакете. Используется, когда нет строгого ограничения по времени. 

  • Если временные рамки пакета достаточно свободные, например, один раз в месяц или один раз в год, настоятельно рекомендуется мониторить и делать пробные запуски пакетной обработки, поскольку модель или система могут устареть.

Пример

https://github.com/shibuiwilliam/ml-system-in-actions/tree/main/chapter4_serving_patterns/batch_pattern

Паттерн вертикальной организации микросервисов (Microservice vertical pattern)

Применение

  • Когда вам нужно получить несколько выводов по порядку.

  • Когда у вас есть несколько логических выводов, и между ними есть зависимости.

Архитектура

Паттерн вертикальной организации микросервисов позволяет запускать несколько моделей по порядку. Паттерн предполагает развертывание моделей прогнозирования на отдельных серверах или в контейнерах в качестве сервисов. Вы выполняете запрос на прогнозирование синхронно сверху вниз и собираете результаты для ответа клиенту. Если порядок прогнозов имеет значение, то паттерн вертикальной организации микросервисов — отличный выбор. Он также позволяет вам разделить жизненный цикл обслуживания, локализовать сбои, а также развертывать серверы независимо.

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

Диаграмма

Диаграмма 1

Диаграмма 2

Плюсы

  • Вы можете запускать несколько прогнозов по порядку.

  • Можно выбирать следующий сервис-предиктор в зависимости от результата текущего предсказания.

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

Минусы

  • Поскольку прогнозы выполняются в синхронном порядке, это выльется в более высокую задержку.

  • Вышеупомянутая задержка предсказания может оказаться серьезным узким местом.

  • Сложная структура системы и рабочего процессы.

Что нужно учитывать

  • Возможно, вам придется повозиться с оптимизацией производительности, чтобы соответствовать требуемому уровню обслуживания.

  • Структура системы неминуемо будет сложной. Лучше стараться делать интерфейсы и серверы общими.

Паттерн горизонтальной организации микросервисов

Применение

  • Когда рабочий процесс может выполнять несколько прогнозов параллельно.

  • Когда вы хотите получить совокупный результат прогнозирования.

  • Требуется для запуска нескольких прогнозов для одного запроса.

Архитектура

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

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

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

Диаграмма

Синхронная горизонтальная реализация

Синхронная горизонтальная реализация с извлечением данных

Асинхронная горизонтальная реализация

Плюсы

  • Вы можете независимо настраивать использование ресурсов и изолировать сбой.

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

Минусы

  • Система может стать очень сложной.

  • Для синхронного варианта использования самый медленный вывод становится узким местом.

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

О чем нужно подумать

  • Нужно выбрать синхронный или асинхронный вариант.

  • Что делать с медленной синхронной моделью: тайм-аут или ожидание.

  • Как управлять задержкой для асинхронного режима.

Пример

https://github.com/shibuiwilliam/ml-system-in-actions/tree/main/chapter4_serving_patterns/horizontal_microservice_pattern


Представьте ситуацию: данные ещё умещаются на дисковый массив, но 16 ядер уже явно не хватает для быстрой обработки. Dask готов помочь, предоставляя возможность для распределенных вычислений на нескольких узлах. Поддерживать отдельный Dask-кластер из такого большого числа узлов становится нерентабельным, и мы переезжаем в общий Spark-кластер. Но благодаря pandas API on Spark всё еще остаемся вместе с так полюбившимся нам многоликим зверьком. Приходите сегодня вечером на открытый урок — обсудим всё подробнее.

Комментарии (0)