Всем хорошего дня! На связи с вами Домклик #MLOps, и эта статья будет полезна тем, кто интересуется построением внутренней платформы.

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

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

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

Feature Platform: что это и как работает

В Домклик есть сервис оценки недвижимости: мы умеем предсказывать стоимость продажи или покупки вторички, новостроек, домов, участков, а также цену сдачи в аренду.

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

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

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

С платформой взаимодействуют исследователи данных (data scientist-ы) и production-системы. Она становится связующим звеном между командами, которые создают модели, и системами, которые эти модели используют.

Верхнеуровнево платформа состоит из нескольких ключевых компонентов: Feature Store, Feature Pipelines, Feature SDK, Feature Management. Разберём каждый из них подробней.

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

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

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

  • Онлайн-хранилище — это место для хранения данных, к которым нужен быстрый доступ, и для запросов, по которым есть SLA на ответ в пользовательские системы.

Feature Pipelines — компонент, отвечающий за трансформацию данных и генерирование фич в разных режимах: по расписанию, по триггеру, по запросу, батчем или по одной записи. 

Это не конкретный инструмент, а целый набор. Например:

  • оркестратор — Airflow, Dagster и другие;

  • вычисления — с помощью Python-фреймворков, таких как Pandas, NumPy, Polars;

  • или трансформация в SQL с использованием распределённого движка.

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

Feature Management — компонент, который отвечает за observability и операционные метрики. Он позволяет настроить мониторинг различных жизненных показателей моделей и фич: актуальности, качества данных и других ключевых метрик. Кроме того, помогает отслеживать потоки данных и связи между источником и конечным результатом.

Что может использоваться в качестве инструментов:

  • самописные решения;

  • системы, такие как OpenMetaData или DataHub;

  • для контроля качества данных: библиотеки, такие как Soda, Great Expectations и другие.

Дальше расскажу, из чего можно собрать платформу и какие нюансы нужно учитывать при проектировании.

Проектирование Feature Platform

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

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

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

Нюансы проектирования

Основная особенность проектирования заключается в том, что платформа будет сочетать два вида архитектур:

  • многослойную — LSA (Layered Scalable Architecture), такую как DWH, Data Lake, Data LakeHouse и другие;

  • и ту, что в production-среде.

Нужно будет соединить эти два мира в одну рабочую схему.

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

  • разные профили нагрузки: OLAP (аналитические запросы) против OLTP (транзакционные запросы);

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

Архитектура платформы

На следующем уровне детализации всё становится чуть сложнее — появляется больше блоков. Тем не менее, это всё те же ключевые компоненты:

Рассмотрим отдельно офлайн- и онлайн-контуры.

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

Типовые процессы в офлайн-контуре:

  • сбор, подготовка, исследование данных;

  • проверка гипотез;

  • аналитика;

  • обучение моделей;

  • пакетный расчёт.

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

Онлайн-контур включает в себя потоковую обработку данных и саму production-среду. В центре — онлайн-хранилище.

Задачи в этом контуре чуть проще, но критичнее по времени:

  • Формирование предсказаний для клиента: например, когда мы возвращаем цену квартиры.

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

  • Лёгкие агрегации: можно делать поверх уже подготовленных фич, если это быстрые операции.

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

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

Рынок платформ

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

Feast — открытый фреймворк от команды Tecton. Основная платформа Tecton платная, но Feast можно использовать бесплатно, в том числе в облаках. 

Hopsworks — одна из самых первых платформ с фреймворком. Также предлагает как платную, так и бесплатную версии.

Featureform — открытый фреймворк, который появился относительно недавно, но уже предлагает базовую реализацию Feature Store.

Все они предлагают open source-реализацию для Feature Store. 

Плюсы open source-решений:

  • Коннекторы к некоторым хранилищам.

  • API для получения фич: можно использовать «из коробки».

  • Интерфейс: можно посмотреть, какие фичи есть, как считаются, кто их использует.

  • Минимальный мониторинг: есть возможность настроить базовое отслеживание.

  • SDK для метаинформации по фичам.

Но при этом есть субъективные недостатки:

  • Зависимость от сторонних облачных решений. Если инфраструктура расположена в собственном контуре, и вы всё поддерживаете сами, и у вас есть сильная DevOps-команда, то open source-решение вам просто не нужно, потому что его придётся дорабатывать под себя.

  • Отсутствие модульности. Платформы чаще всего монолитны — нельзя взять один нужный модуль, придётся брать сразу всё.

  • Хаос в функциональности. С чем-то мы работаем, с чем-то — нет, и это нужно постоянно транслировать всей команде. Поддерживать такое состояние сложно: придётся часто напоминать, с чем работаем, а с чем нет. Например, часть библиотеки может не поддерживать какие-то сценарии просто потому, что её не тестировали, или вообще не используется, и, как следствие, могут возникать непредсказуемые побочные эффекты.

  • Инфраструктурные накладные расходы. Некоторые решения предполагают наличие инфраструктуры, которой у вас может не быть. Например, Hadoop. Разворачивать его только ради Feature Store мы бы не хотели.

  • Негибкое масштабирование инференса. Хочется иметь гибкое масштабирование инференса, потому что нагрузка может распределяться неравномерно — на одни модели высокая, на другие — минимальная. Поэтому важно направлять ресурсы точечно, только туда, где они действительно нужны. Это особенно актуально, если в production-кластере ограничено количество ядер или машин, что часто бывает в условиях экономии или быстрого роста сервисов.

Итак, если не open source, то как тогда спроектировать подходящую архитектуру?

Архитектура в идеальном и реальном мирах

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

Требования к системе и MVP

Не дорабатывать open source. Мы не хотели тратить ресурсы на доработку чужих решений.

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

Быстрая обработка данных. Инкрементальные данные объёмом 5–50 ГБ должны обрабатываться менее чем за час.

Один инференс — один микросервис. У нас production микросервисная архитектура.

Структурированные данные. У нас много табличных данных, много SQL. Это даст простоту и прозрачность, в отличие от сложной логики, написанной на Python.

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

Поддержка высокой нагрузки в production. Нагрузка в проде на конкретный микросервис может достигать 250 RPS. Мы хотим выделять больше ресурсов именно тому микросервисe, которому это необходимо, например, для сервиса модельной оценки, а не для чат-бота.

Если учесть все нюансы, то схема архитектура платформы станет такой:

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

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

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

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

  • Технологии оффлайн-контура. У нас уже есть Greenplum, он отлично подходит для аналитического хранилища. Мы можем хранить в нём фичи и не ходить далеко за сырыми данными. Решение очевидное — берём его.

  • Оркестрация пайплайнов и batch-расчёт — Airflow. Airflow у нас уже настроен, пайплайны пишутся в нём. Нас устраивает — значит, используем.

  • Предобработка данных и генерация фичей — dbt + Python. Мы уже работаем с Python. Берём его и чтобы упростить работу с предобработкой данных на SQL, добавляем dbt.

  • Обучение моделей Kubeflow. Для этого у нас уже используется Kubeflow. Оставляем.

  • Data Lineage OpenMetaData. Мы выбирали между DataHub и OpenMetaData, и по совокупности факторов остановились на последнем.

  • Хранилище метаинформации PostgreSQL. PostgreSQL — стандарт в нашей компании. Используем его как хранилище метаинформации по фичам. Простой, понятный, привычный выбор. Этого хватит.

Технологии онлайн-контура

  • OLTP-хранилище. Выбираем именно то хранилище, которое нужно под профиль запроса в эксплуатации. У нас это PostgreSQL, Redis, Elasticsearch как хранилище для эмбеддингов.

  • Микросервис для инференса — Python. Берём Python, на котором пишем микросервисы.

Таким образом, архитектура собрана из того, что есть, и упрощается во много раз. С этим легче начинать, проще масштабировать и удобнее работать:

Предполагаемый сценарий работы с платформой

Теперь определим, как команде с этим взаимодействовать. Я покажу возможный сценарий, который можно использовать как основу.

Предлагаем следующий подход:

  1. Исследуем данные. На этом этапе у команды уже есть опыт, и мы умеем с этим работать.

  2. Обучаем модель. Здесь всё понятно: формулируем задачу, выбираем подход, готовим модель.

  3. Готовим витрину. Делаем это один раз.

  4. Пишем пайплайн. Тоже один раз.

  5. Трансформируем модель в инференс. Она будет работать в проде.

  6. Настраиваем обновление данных из офлайн-хранилища в онлайн-хранилище.

  7. Выпускаем модель. Всё готово, она уходит в прод.

После релиза мы должны увидеть всю цепочку в Data Lineage — от источника → через витрину и фичи → до модели в эксплуатации. Важно, чтобы было понятно, что и как устроено внутри.

Но не всегда всё идёт идеально. Сначала могут отсутствовать какие-то элементы. Это усложнит задачу, но, мне кажется, не стоит бояться. Лучше запустить MVP быстрее и доработать детали по ходу, чем пытаться сделать идеально на старте.

Вот примеры, чего не хватало нам:

  • Data Lineage. Сначала его не было. Внедрили позже, когда поняли, что и как устроено внутри архитектуры. Всё разложили, выбрали инструмент и только после этого сформировали слои с данными.

  • Каталог данных. Эта задача в процессе.

  • Механизм для формирования историчности изменений источника. Сейчас у нас нет нативного решения, планируем его разрабатывать. А пока обошлись тем, что было под рукой — простым скриптом на SQL, который делает то, что нужно.

  • Нативный механизм доставки данных из одной базы в другую. Сначала — просто DAG в Airflow. Позже можно будет улучшить.

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

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

Компетенции и культура в работе над платформой

Чтобы собрать платформу, кроме технических требований и процессов нужны команда, культура и компетенции. Это можно вырастить внутри компании или найти на рынке. Главное — понимать, что именно искать и что растить.

Какие компетенции понадобятся:

  • DataOps — чтобы разворачивать инфраструктуру под данные. Например, Greenplum, Airflow, или в каких-то случаях Trina.

  • Data Architecture — кто-то должен правильно разложить данные. Чем раньше вы выстроите архитектуру, тем меньше сложностей. Сокращаем свои потери в болоте.

  • Data Engineering — постоянная роль для человека, который будет отвечать за витрины и конвейеры для подготовки данных. В моей команде такого человека не хватало, и я нашла его на рынке. Он очень помог ускорить развитие платформы на стадии MVP.

  • MLOps — чтобы релизить и оптимизировать модели, отвечать за доставку, понимать, в каком формате и как работает модель, и чтобы этот пласт работы в целом был всегда под контролем.

  • ML-специалист — чтобы делать модельки.

Кроме навыков нужна культура. Как её вырастить в компании? Как понять, на каком она уровне?

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

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

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

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

Допустим, у нас есть данные по объявлениям, мы используем их в модели оценки недвижимости. Есть данные по сделкам, и мы хотим, чтобы другая команда видела, какую ценность мы из этого извлекаем. С помощью Data Lineage мы прозрачно показываем, откуда берём данные, как превращаем в фичи, как получаем предсказание. В результате пользователь видит, сколько стоит его квартира, и это положительно влияет на его опыт.

Итоги

Что у нас получилось уже на этапе MVP — и почему это круто:

  • Ускорили разработку новых моделей на 30 % с помощью MVP.

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

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

  • Повысили надёжность. Теперь мы можем на каждом этапе настроить нужное нам количество тестов, увидеть качество данных. Мы можем настроить, в том числе, data-дрифты и мониторить всё необходимое.

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

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

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

Мы заложили фундамент и почувствовали, что платформа работает. А если дойти до полноценного продукта, то можно ускорить разработку ещё сильнее и сделать работу в компании намного лучше.