Проектируем собственную inhouse Feature Platform
Всем хорошего дня! На связи с вами Домклик #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, на котором пишем микросервисы.
Таким образом, архитектура собрана из того, что есть, и упрощается во много раз. С этим легче начинать, проще масштабировать и удобнее работать:
Предполагаемый сценарий работы с платформой
Теперь определим, как команде с этим взаимодействовать. Я покажу возможный сценарий, который можно использовать как основу.
Предлагаем следующий подход:
Исследуем данные. На этом этапе у команды уже есть опыт, и мы умеем с этим работать.
Обучаем модель. Здесь всё понятно: формулируем задачу, выбираем подход, готовим модель.
Готовим витрину. Делаем это один раз.
Пишем пайплайн. Тоже один раз.
Трансформируем модель в инференс. Она будет работать в проде.
Настраиваем обновление данных из офлайн-хранилища в онлайн-хранилище.
Выпускаем модель. Всё готово, она уходит в прод.
После релиза мы должны увидеть всю цепочку в 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-решение платформы развивает в нас самое классное: не только помогает с технической точки зрения, но и меняет культуру, процессы и мышление команды.
Мы заложили фундамент и почувствовали, что платформа работает. А если дойти до полноценного продукта, то можно ускорить разработку ещё сильнее и сделать работу в компании намного лучше.