Почему вам стоит прочитать этот пост

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

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

На мой взгляд, есть три основных фактора, затрудняющих развертывание:

  1. Поздний запуск процесса. Частично из-за культурных пробелов и частично из-за характера исследовательского цикла многие команды оставляют тему развертывания до самого конца игры, что приводит к множество неприятных сюрпризов и проблем. Например, обнаружение, что данные, используемые для обучения, недоступны в производственной среде.
  2. Отсутствие зрелых архитектурных шаблонов. Поскольку это новая технология, существует относительно немного компаний за пределами технологических гигантов, которые довели до совершенства искусство развертывания моделей и служат для извлечения уроков.
  3. Запутанное множество конкурирующих платформ и технологий -
    Каждая построена с тонким изменением парадигмы и оптимизацией / акцентом на разные части решения.
    Небольшое примечание - Даже номенклатура не полностью установлена ​​-
    так что простите меня за то, что я принял мою собственную для некоторых концепций, упомянутых ниже.

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

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

Предполагается, что у вас есть некоторый опыт в развертывании сервисов в производственной среде, и вы в основном сосредотачиваетесь на решениях / характеристиках, которые являются уникальными для Model Inference.

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

Вывод в контексте ML Dev. Жизненный цикл

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

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

Вывод в контексте более крупной системы

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

Границы конвейера вывода

Бизнес-задачи связаны с предсказанием «вещей» о сущностях в бизнес-области.

Однако модели обычно не используют бизнес-объекты для прогнозирования. Вместо этого модели используют некоторое абстрактное представление объекта данных.

Например, обрезанное, измененное масштабирование и изображение в оттенках серого в виде тензора 256X256X3 или вектора с числовыми функциями в виде массива numpy или фрейма данных.

Вот что вам нужно знать об этих представлениях:

  1. Модели очень тесно связаны с их представлением данных. Любое небольшое изменение формата или даже распределения данных одного из измерений данных может вызвать дрейф модели.
  2. Большая часть «мозга» модели происходит от развития этого представления входных данных; специалистам по данным необходимо поддерживать возможность итерации по этому представлению, не требуя изменений API в восходящем направлении.
  3. Создание этого представления принципиально отличается от вызова API-интерфейса forward () в нейронной сети - оно включает в себя императивный код, преобразования и т. Д. В некоторых случаях оно может включать операции ввода-вывода для обогащения или загрузки дополнительных данных и «логику науки о данных» для подготовки.

Отсюда следует:

  1. Точка входа в конвейер вывода должна быть достаточно высокого уровня - либо объект бизнес-домена (например, транзакция), либо объект «области данных» (например, IP-адрес).
  2. Задача создания представления находится в рамках конвейера вывода
  3. Создание представления следует рассматривать отдельно от прогноза.

Конвейер логического вывода

  1. Business-API вызывается для получения прогноза.
    API сосредоточен вокруг бизнес-домена - сущности и концепции, относящиеся к бизнес-задаче.
    В качестве примера представьте себе систему онлайн-платежей, которая обрабатывает транзакцию. В рамках потока может потребоваться оценка транзакции на предмет подозрения в мошенничестве. Business API получит объект транзакции и вернет оценку или перечисление, представляющее вероятность мошенничества.
  2. Необязательно - Business API может потребоваться преобразовать ввод бизнес-домена в домен данных.
    Продолжая пример обнаружения мошенничества, модель обнаружения мошенничества может вообще не интересоваться транзакциями, а только IP-адресами отправителя. Эта адаптация бизнес-домена к «домену данных» в некоторых случаях может быть «пустой», а в других может включать в себя различные операции, такие как проекция, обогащение и т. Д.
  3. Входные данные для представления - принимает входные данные «Data domain» и преобразует их в « Модель представления »данных.

    В случае классического машинного обучения это преобразование включает
    вычислительные возможности.
    Здесь выходной Домен модели будет кадром данных с числовыми характеристиками, готовым для прогнозирования. В случае модели компьютерного зрения это может означать предварительную обработку изображения, обрезку или транспонирование и упаковку в массив чисел или тензор.
  4. Predict API вызывается в представлении модели.
    По крайней мере, для этого нужно взять сериализованный файл модели, прочитать его (обычно заблаговременно) и использовать его для выполнения вычислений по входному вектору.
    В некоторых случаях работа модели более сложна и требует императивного кода.
  5. Прогнозирование до ответа (пост-обработка) - принимает прогноз и преобразует, если необходимо, обратно в Бизнес-домен. Например, оценка модели мошенничества должна быть преобразована в одну из следующих меток «не мошенничество / подозрительно / очень подозрительно / неуверенно», которую может интерпретировать клиент.

Любая из этих задач может отклонять ввод или работать неправильно.

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

Эти ошибки и сбои также необходимо распространить обратно в "бизнес-домен", как правило, с понятным для человека объяснением.

Конвейер вывода - разложение на сервисы

Итак, как вы разложите этот конвейер на службы? какова ответственность каждого сервиса и API? каковы основные соображения?

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

  1. Науки о данных или инженерные навыки - многие компании имеют команду, занимающуюся только наукой о данных, с небольшим опытом или без опыта работы с сервисами в производственной среде. Но они хотят, чтобы команда отвечала за выпуск своих моделей в производство, без «передачи» никому.
  2. Тесная связь между представлениями и моделями -
    Даже малейшее изменение в распределении объекта может привести к смещению моделей.
    Для достаточно сложных моделей создание такого представления может означать наличие большого количества данных конвейеры, базы данных и даже восходящие модели. Урегулировать эти отношения нетривиально, мягко говоря
  3. Уникальные характеристики масштаба / производительности - как правило, часть конвейера pred () является чисто вычислительной, что является довольно уникальным в среде обслуживания.
    Во многих случаях часть рабочего процесса представление больше связана с вводом-выводом (особенно, когда вам нужно обогатить ввод, загрузив данные / функции или получив изображение / видео, которое вы пытаюсь предсказать дальше).

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

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

Встроенный шаблон вывода

В этом шаблоне вы упаковываете модель ML + код внутри своей бизнес-службы.

Когда использовать?

  1. Модель используется одной бизнес-службой
  2. Конвейер вывода (включая преобразование и прогнозирование) не слишком сложен / дорог в вычислении.
  3. Специалисты по науке о данных, работающие над моделью, очень привязаны к бизнес-сфере (возможно, даже встроены в сервисную группу).

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

Проблемы

  • Де-факто команда DS является частью группы бизнес-обслуживания и нуждается в тесной интеграции.
  • Бизнес-сервис теперь подвергается уникальным требованиям модели к вводу-выводу / масштабированию.
  • Теперь конвейер CI / CD должен включать тесты на основе машинного обучения, которые сильно отличаются от тестов бизнес-логики ...

По моему опыту, это относительно необычная закономерность.

Шаблон вывода единой службы

Здесь модель развертывается в выделенном сервисе, к которому (разные) бизнес-сервисы обращаются с помощью API «ввода данных». Сервис инкапсулирует вычисление признаков, прогнозирование и преобразования вывода.

Это вариант здравого смысла. По умолчанию используется.

Когда использовать?

  • Требуется повторное использование модели
  • Логика трансформации не слишком сложна / затратна

Проблемы

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

См. раздел ниже «Общий шаблон службы вывода», в котором обсуждаются некоторые подходы, используемые для решения этой проблемы.

Шаблон вывода микросервисов

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

Здесь допустим любой шаблон микросервисов: центральный оркестратор, конвейер, синхронный или асинхронный.

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

Примеры

Хорошим примером систематического разделения конвейера является использование магазинов функций.

При таком подходе вычисление функций выполняется отдельными службами или конвейерами данных.
Результаты сохраняются в «хранилище функций».

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

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

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

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

Когда использовать

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

Проблемы

  1. Функции и модели тесно связаны, поэтому разделить их сложно. Например, единственная действительно эффективная и окончательная методология тестирования для обеспечения того, чтобы модели и функции хорошо работали вместе, требует их совместного тестирования (в нашем случае интеграционный тест).
  2. В результате повышение эффективности от этого повторного использования достигается в основном, когда новые модели используют функции / код предварительной обработки, который уже развернут / отработан.
  3. Верно и обратное: выпустить модель, основанную на новых функциях, сложнее с несколькими службами.

Преодоление технических проблем - путем развертывания «общих служб логического вывода»

Как бы вы ни смотрели на это, какой-то артефакт команды DS должен превратиться в сервис в производственной среде, и у этой службы должен быть конвейер CI / CD, API, ведение журнала, мониторинг и т. Д.

Паттерн «встроенная модель» решает эту проблему, фактически встраивая DS dev. жизненный цикл внутри артефакта инженерной команды; как мы уже говорили, у этого есть ограничения.

Итак, как получить DS для развертывания в производственной среде без необходимости управлять собственными службами или иметь большие инженерные навыки?
Введите шаблон «общий вывод».

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

Недавно этот шаблон появился также в решении SaaS / с открытым исходным кодом.

Общий рабочий процесс вывода

  • Специалисты по обработке данных развертывают «упакованную модель» (по сути, файл весов модели и несколько минимальных файлов / метаданных Python), и их использует общий сервис. Форма пакета может быть записной книжкой jupyter или файлом .tar / .zip с артефактами.
  • вышестоящие клиентские службы вызывают общий API
  • Общий API делегирует «упакованную модель», собирает ответ и возвращает его клиентской службе.

Вот пример клиентского кода, необходимого для вызова модели CV, развернутой с использованием общей инфраструктуры TensorFlow Serving:

Data: {"signature_name": "serving_default", "instances": ...  [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0]]]]}
headers = {"content-type": "application/json"}
json_response = requests.post('http://localhost:8501/v1/models/fashion_model:predict', data=data, headers=headers)
predictions = json.loads(json_response.text)['predictions']

Вот пример того, как упаковать артефакт модели PyTorch для развертывания в AWS SageMaker.

Преимущества

  1. Специалистам по данным не нужно кодировать и владеть производственной службой
  2. API вывода был разработан опытными инженерами в Google, Databricks или Amazon.
  3. Многие из этих инструментов предлагают интересные функции, такие как автоматическая перезагрузка модели (которая упрощает развертывание новой модели), сине-зеленые решения для медленного масштабирования модели и многое другое ...

Проблема 1. Обработка сложных конвейеров вывода

Что происходит, когда конвейер вывода должен включать императивный код для создания представления модели или агрегирования результатов модели?

Фреймворки «универсального вывода» решают эту проблему, позволяя вам предоставить
собственный код и даже внешние зависимости вместе с файлом весов вашей модели.

Ваш код реализует несколько ловушек для вызова общей службы вывода:

  1. Метод Init () - при загрузке сервиса этот хук позволит вам загрузить файл весов модели и выполнить любую тяжелую инициализацию.
  2. Во время вызова службы платформа вызовет ваш код в следующей последовательности: pre_process (), предсказать (), post_process ()

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

  1. Трудно втиснуть сложные конвейеры в API pre_process (), предсказать (), post_process ().
  2. Вам по-прежнему нужны инженерные возможности для разработки, тестирования и оптимизации этого конвейера.
  3. Служба, в которой вы размещаете свой код, не была настроена для вашей рабочей нагрузки, и, вероятно, будет сложно настроить ее производительность в соответствии с вашим конкретным вариантом использования.

Проблема 2. Некачественные и непрозрачные интерфейсы

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

Как вы заполняете тензор из файла .bmp? вам нужно использовать байты изображения? возможно, загрузить его как изображение PIL? вы ожидаете какой-либо конкретной кодировки? и т.п.

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

Когда использовать общий вывод в реальной жизни

Я думаю, что главное преимущество этого паттерна в том, что

  1. Вы абсолютно настаиваете на том, чтобы DS развертывала свои модели независимо.
  2. Вы планируете иметь гораздо больше выпусков моделей, чем выпусков изменений функций / представлений.

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

  1. В качестве «службы» в «шаблоне вывода единой службы» -
    , но только в том случае, если ваша обработка очень проста и у вас очень мало инженеров.
  2. Как микрослужба Predict в «шаблоне вывода микросервисов» -
    Убедитесь, что эта служба предоставляется не «конечному клиенту», а другому микросервису вывода.

Общий вывод о стероидах - многомодельный общий вывод

Я считаю, что этот шаблон проектирования в некоторой степени уникален для служб вывода.

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

Сервер Multi-Model автоматически «обнаруживает» новые модели и их пакеты. Затем он предоставляет уникальный URL-адрес для каждого.

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

Это также создает проблему, как выполнять балансировку нагрузки и планирование мощности, когда рабочая нагрузка потенциально очень неоднородна - например, если у каждой модели разные SLA, объемы и требования к вычислениям / вводу-выводу.

Обслуживание нескольких моделей - это не анекдот - крупнейшие платформы и наборы инструментов поддерживают его из коробки, например TensorRT (от NVIDIA), TensorFlow Serving (от Google) и Sagemaker от Amazon.

Итак, в чем же смысл этого шаблона проектирования?
Если бы мне пришлось угадывать, я бы сказал:

  1. Закон Конвея - продолжая линию отделения инженерии от DS, вы можете создать одну центральную группу инженеров, которая будет управлять логическим выводом во всех сценариях использования науки о данных.
  2. Использование вычислительных ресурсов - подключение графических процессоров к серверам стоит дорого, а оставлять их без дела - большая трата. Разместив разные модели на одном сервере, вы сможете повысить коэффициент использования графического процессора.

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

Резюме

Развертывание служб логического вывода - все еще относительно новая дисциплина со своим уникальным набором проблем.

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

С достаточным количеством компромиссов и множеством новых разработчиков. практики жизненного цикла, это вполне возможно.

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