Автор: Кирилл Трусковский

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

Моя основная задача в команде R&D — внедрить модели машинного обучения в производство. Используя свой опыт в этом и читая курс ML в производстве в Project, я расскажу о жизненном цикле моделей ML и инфраструктуре для моделей машинного обучения.

Эта статья будет полезна, если вы:

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

Жизненный цикл модели машинного обучения

Начнем с жизненного цикла модели машинного обучения: что это такое и зачем оно нам нужно. Есть много вариантов, как это преподнести. Например, популярные версии от Google и Neptune, или моя любимая от Мартина Фаулера в его статье Continuous Delivery for Machine Learning.

Это не единственные варианты, но сегодня мы остановимся на простых.

В оставшейся части этого блога мы поэтапно рассмотрим этот жизненный цикл:

Данные

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

Эта часть жизненного цикла, скорее всего, займет большую часть ресурсов. Улучшение любой части модели не окажет такого большого влияния, как улучшение данных. Например, вы можете потратить месяцы на эксперименты с архитектурой и получить 2–3% целевых показателей. С другой стороны, очистка данных может дать прирост производительности в несколько раз больше.

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

  • Озера данных, или просто сохранять данные в объектном хранилище. Например, s3 или минио.
  • Хранилище данных. Это может быть простая база данных, реляционная или нет.
  • Сетка данных. Все более популярный подход. Вот очень хорошая лекция об этой концепции. Он касается ситуации, когда вы разделяете данные инфраструктуры на отдельные децентрализованные продукты.

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

Конечно, все зависит от масштаба. По моему опыту, компания из 50–100 человек обрабатывает ~20–50 ТБ в месяц, и обычно этим занимается отдельная команда инженеров данных.

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

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

Наиболее популярные инструменты разметки, которые мы используем:

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

А также инструменты для управления версиями ваших наборов данных:

Юзер-кейс, с которым мы тоже иногда сталкиваемся, — дополнение к Feature Store. Это база данных, ориентированная на машинное обучение, для повторного использования функций машинного обучения.

Некоторые примеры Feature Store:

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

Эксперименты

Получив данные, можно приступать к проверке гипотез и переходить к экспериментам. На этом этапе часто важна скорость итерации: сколько гипотез вы можете проверить и сколько экспериментов вы можете провести.

Хотя вы отклоните 99% кода и результатов, из-за характера проб и ошибок на этом этапе было бы неплохо спроектировать его в масштабируемом и воспроизводимом потоке.

Наряду с инструментами управления данными мы обычно используем шаблоны для экспериментов. Очень популярен метод питорч-молния. Этот фреймворк позволяет вам не работать с низкоуровневыми деталями: как будут проходить эксперименты, как использовать несколько графических процессоров и так далее. Pytorch-lightning может подойти не всем, и команды часто пишут собственные решения или используют шаблоны, такие как фреймворк The Data Science Lifecycle Process.

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

Несколько вариантов включают:

  • TensorBoard очень популярен и имеет множество интеграций с различными фреймворками. Вы также можете использовать TensorBoard.dev, чтобы сохранить свои результаты в облаке и не делиться скриншотом в slack с коллегами. Однако его часто трудно масштабировать, и со временем с ним становится трудно работать.
  • Затем вы можете переключиться на MLflow Tracking, инструмент для управления всем циклом ML-моделей. Часто он используется для управления экспериментами. Это инструмент с открытым исходным кодом, который вы можете поддерживать самостоятельно или использовать управляемое решение от Databricks.
  • На мой взгляд, лучший вариант — начать с управляемого решения. Это потому, что вам не нужно поддерживать и поддерживать его. Часто управляемые решения обеспечивают гораздо лучший UX и набор функций, чем TensorBoard и MLflow Tracking, но могут быть довольно дорогими. В основном мы используем Weights & Biases и Comet.ml.
  • Есть новое открытое решение для управления экспериментами, которое мне тоже очень нравится: AIM.

Вам также потребуется управлять инфраструктурой для разработки моделей, такой как кластер с графическим процессором. Можно начать с предоставления всем доступа к созданию машин в AWS EC2 или его аналогах. Например, ssh предоставит доступ к вашему локальному кластеру. Однако с ростом команды и количеством экспериментов это станет неудобно. Различные эксперименты могут конфликтовать из-за ресурсов, или команда может забыть удалить созданные вручную машины, и вы потратите деньги и так далее.

В этой ситуации можно добавить централизованное решение. Это может снизить гибкость команды, но преимущества намного перевешивают затраченные усилия и ресурсы. В итоге все же стоит подумать о централизованном запуске экспериментов. Чаще всего для этой цели может использоваться Slurm, который можно совмещать с Submit It! упаковка. В качестве альтернативы Kubernetes также является популярным выбором. Есть хороший кейс от OpenAI, где они работают с Kubernetes для обучения огромных моделей, таких как GPT3 и другие.

Трубопроводы

Итак, вы провели более 100 500 экспериментов, подтвердили массу гипотез и считаете, что модель может быть полезной. Пришло время реструктурировать ваш код из специального обучения в чистый конвейер, который вы можете легко обучить снова, чтобы обучать в продакшене и переобучать (довольно распространенный вариант использования в продакшене).

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

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

Наиболее популярные библиотеки конвейеров, которые мы использовали:

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

Развертывание

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

Вариант 1. Не развертывайте модель вообще :)

Джефф Этвуд, соучредитель Stack Overflow: «Лучший код — это отсутствие кода».

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

Мы часто используем:

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

Вариант 2. Оберните фреймворк Python

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

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

В основном мы используем FastAPI (от создателей Explosion, spaCy) из-за множества встроенных функций.

Другие популярные варианты:

  • Flask — я думаю, что большинство людей, которые изучают веб-разработку на Python, знакомы с ним.
  • Aiohttp (от основных участников Python) разрабатывается в Украине, и мне однажды посчастливилось работать с его автором. Это очень полезно, если вашему приложению нужна асинхронность. Но будь осторожен! Поскольку модели машинного обучения обычно связаны с ЦП, асинхронные фреймворки Python, которые в основном основаны на библиотеках asyncio, их следует использовать с осторожностью! Подробнее об asyncio, его плюсах и минусах вы можете прочитать в этом туториале.

Вариант 3. Используйте сервер логических выводов

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

Самый популярный:

Этот список далеко не полный. Мы часто используем Seldon и KServe. Общая идея довольно проста — преобразовать вашу модель в формат, понятный серверу вывода, и тогда он сможет развернуть ее автоматически. Вам не нужно писать свой собственный веб-сервер, просто сохраните модель в определенном месте в определенном формате. Такие фреймворки дают вам массу дополнительных возможностей: систему контроля версий для моделей, пояснения к результатам ML-моделей и поддержку нескольких моделей из коробки.

Стоит отметить, что ни один из этих вариантов не исключает другого. Важно всегда балансировать и выбирать именно то, что нужно для решения бизнес-задач. Если вы стартап из 10 человек, то могут быть вещи, которые сейчас важнее, чем сервер вывода, и вы можете работать с FastAPI в качестве стартового. Но если вы работаете в корпорации, где в самом отделе машинного обучения работает более 100 человек, уместно предоставить всем проверенный и надежный способ доставки моделей. Seldon и KServe блестят в таких ситуациях!

Мониторинг

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

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

Мне очень нравится визуализация с этого ресурса, которая дает примерное представление о проблеме. Если вы хотите углубиться в тему — серия из пяти постов здесь b1, b2, b3, b4, b5 будет хорошей отправной точкой.

Короче говоря, вам нужно:

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

Для выполнения этих задач мы используем следующие ссылки:

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

Бонус: платформы

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

Стоит отметить, что существует множество платформ для машинного обучения, которые утверждают, что охватывают сквозной цикл машинного обучения и поддерживают каждый из шагов, которые мы обсуждали выше. Наиболее распространенными из них являются AWS SageMaker и GCP Vertex AI.

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

Есть хорошая таблица сравнения разных платформ и решений.

Краткое содержание

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

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

Это адаптация оригинальной статьи: https://dou.ua/forums/topic/36499/ из украинского технического журнала.