Паттерны проектирования для систем машинного обучения. Часть 1

Kate

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

Цели​

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

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

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

Источник​

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

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

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

Паттерны​

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

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

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

Применение​

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

Архитектура​

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

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

Диаграмма​

5d32834e455029cfb43f3cce5b9ebe8b.png

Плюсы​

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

Минусы​

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

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

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

Пример​

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

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

Применение​

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

Архитектура​

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

Диаграмма​

fe203f3fa126c6cc601c55d983c8dcc6.png

Плюсы​

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

Минусы​

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

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

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

Пример​

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

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

Применение​

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

Архитектура​

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

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

Диаграмма​

Диаграмма 1​

77381d3a5f7ba0ddab40b31e9667bb21.png

Диаграмма 2​

07f4ae1c63b73125d2f04ac239007ae0.png

Плюсы​

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

Минусы​

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

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

  • Как запустить предсказание:
    • Очередь: прогноз будет FIFO
    • Кэш: зависит от доступного кэша
    • PubSub: подписка предиктора на запуск предсказания
  • Необходимо учитывать ошибку прогнозирования:
    • Если вам нужно повторить попытку, рассмотрите возможность запуска повторной попытки на сервере прогнозирования или возврата в очередь.
    • Если ошибка вызвана проблемой с данными или программой, может быть вероятность того, что запрос будет повторяться до тех пор, пока вы не удалите его вручную.
  • Поскольку паттерн не поддерживает упорядоченное предсказание, вам нужно будет как следует проработать ваш рабочий процесс, если в вашем варианте использования важен порядок ввода или событий.

Пример​

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

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

Применение​

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

Архитектура​

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

Диаграмма​

4bd506e348b69c2175c186dc4cad104c.png

Плюсы​

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

Минусы​

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

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

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

Пример​

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

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

Применение​

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

Архитектура​

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

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

Диаграмма​

Диаграмма 1​

fb2b479513a8c7c05eb4e7f811b5982d.png

Диаграмма 2​

03644cb9b845c75b3f13aa842b420ed0.png

Плюсы​

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

Минусы​

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

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

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

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

Применение​

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

Архитектура​

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

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

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

Диаграмма​

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

500fa514309eb391543c9c42c35ba979.png

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

cb4a0db71c673e5a7d10e1699692ee04.png

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

a30912eefad09e80db2fee2f261a5ea3.png

Плюсы​

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

Минусы​

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

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

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

Пример​

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

 
Сверху