Привет, Хабр!

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

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

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

Инфраструктура для анализа данных в билайне

Для управления жизненным циклом и анализом данных у нас есть развесистая платформа по управлению данными c большим количеством инструментов. Данные хранятся в Hadoop-кластере. В билайне около 26 ПБ данных и они растут с интенсивностью 2-3 ПБ в год. Данные распределены по более, чем 20 тысячям hive-витрин.

Обрабатываем данные мы как правило с помощью Spark на движке yarn (менеджер ресурсов), либо с помощью hive, используя hiveql.

Для управления приложениями и сервисами мы используем Kubernetes.

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

Data Mesh в билайне

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

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

В таком подходе есть как плюсы, так и минусы.

Из плюсов:

  • домены хорошо знают свои данные и витрины получаются более информативными;

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

А вот минусы:

  • возрастающая нагрузка на команды по поддержке витрин данных и соответствующих процессов;

  • необходимость пользоваться коммунальными инструментами: документировать свои витрины, использовать стандарты при разработке API, использовать общие инструменты анализа качества данных и т.д.

У билайна много данных и много компетентных инженеров, поэтому подход Data Mesh для нас оптимален.

Кратко о MLOps-конвейере

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

MLOps (Machine Learning Operations) — это совокупность DevOps-подходов для создания решений с машинным обучением. Цель практик MLOps — оптимизация подходов к разработке в области анализа данных и в идеале создание единого конвейера разработки ML-решений. Подробнее можно почитать тут.

Продуктовой команде с задачами в области анализа данных по запросу предоставляется DS-кабинет, который по сути является определенным неймспейсом kubrenetes с развернутыми в нем Jhub и Mlflow и настроенными квотами, которые этой команде выделены (делается это с помощью ArgoCD). В Jhub можно поднимать инстансы Jlab, Vscode. Трекать эксперименты в Mlflow, сохранять модельки в Mlflow storage. Код экспериментов хранится и версионируется в Gitlab.

Для деплоя моделек с целью вычисления скоров на кластере используем оркестратор Argoworkflow с преднастроенными для этого докер-образами и интеграцией с Mlflow. Пайплайн вычислений на кластере делаем с помощью pySpark джоб.

Как это происходит и какой отпечаток накладывает Data Mesh подход

В Data Mesh подходе витрина может собираться из самых разных источников, которые могут находиться в разных доменах. Например, из желтого домена собираются витрины 1 и 2 для соответствующих моделей.

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

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

Итак, мы поняли, что проблема в желтом домене. Команда — владелец модели — сообщает домену, что у него что-то сломалось. Домен проводит работы по восстановлению корректности данных.

Но теперь важно понять, какие еще команды, продукты, ML-модели зависят от данных желтого домена. Решить эту задачу можно с помощью linеage.

Data lineage

Data lineage – это процесс отслеживания перемещения данных от их источника до конечных точек, включая все промежуточные этапы трансформации и обработки данных. Конечными точками могут быть витрины данных, дашборды, модели машинного обучения, сервисы.

Data lineage позволяет понять, откуда данные пришли, как они были изменены и куда были переданы.

Нам интересен lineage с конечными точками — ML-моделями. А именно нужны прозрачные связи между моделями и фичами, которые использует модель.

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

Уже более трёх лет, фактически с момента первого релиза, мы используем data catalog-инструмент Open Metadata или сокращенно OMD.

Open Metadata

На момент выбора инструмента (2021 год) с нашей точки зрения была следующая картина. Был ряд data catalog-инструментов, но не все из них соответствовали нашим ожиданиям.

OMD нас удовлетворял, но был один нюанс: его только что зарелизили, и ещё не было опыта его эксплуатации. Но ребята из OMD были убедительны, и мы выбрали его как data catalog инструмент.

Open Metadata — это хранилище метаданных с открытым исходным кодом, которое может стать местом аккумуляции информации о данных и их использовании в компании. Этот молодой инструмент был запущен во второй половине 2021 года. В мае 2023 года был крупный релиз с версии 0 на 1.

Составные части OMD:

  • UI;

  • бэкенд - API OMD;

  • Airflow;

  • Elasticsearch;

  • Postgres.

В OMD реализовано большое число коннекторов, которые позволяют:

  • сохранять информацию о схемах различных хранилищ (Oracle, MySQL, GreenPlam, Hive, Postgresql и другие). В версии 1.2. более 30 хранилищ данных;

  • сохранять информацию о дашбордах в различных BI системах (Qlik Sense, PowerBI, Superset, Metabase и др);

  • сохранять информацию об ETL-пайплайнах (Airbyte, Airflow, Nifi и другие)

  • выполнять проверки качества данных. 

OMD в билайне агрегирует следующую информацию:

  • большинство витрин у нас построены в Hive, в некоторых командах используется PG, есть oracle, в OMD попадает информация о схемах, указанных БД;

  • есть инфа по топикам Kafka;

  • в качестве BI-инструмента мы используем Qlik sense, в OMD содержится информация о дашбордах;

  • в качестве ml model storage у нас Mlflow, данные о модельках попадают в OMD.

Подключение новых источников в OMD

Посмотрим на механизм интеграции OMD с источниками. OMD использует pull based-стратегию загрузки данных. В качестве примера мы взяли Mlflow инстансы.

Для загрузки данных используется Airflow.

 

Можно выполнять подключение вручную через UI: в UI мы создаем ingestion с необходимыми кредами и нажимаем кнопочку deploy. После этого создается DAG в Airflow, и он запускается по расписанию для считывания метаданных. Также подключения можно добавлять через API OMD. 

После успешного подключения OMD забирает данные из БД mlflow раз в сутки по дефолтным настройкам.

В UI OMD это выглядит вот так.

В разделе ml models мы видим инстансы Mlflow разных продуктовых команд. Видим, в какой команде привязан инстанс Mlflow, какому инстансу Postgresql он соответствует, краткое описание.

Теперь посмотрим, как выглядит lineage в OMD.

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

Для ряда хранилищ реализован парсинг журнала запросов и восстановление связей из них. Список хранилищ с такой фичей:  BigQuerySnowflakeMSSQLRedshiftClickhouseDatabricksPostgres.

В OMD реализована возможность автодобавления связей при использовании Airflow в качестве оркестратора ETL-процессов. Сейчас мы в процессе тестирования этой фичи.

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

Интеграция lineage в DS workflow

Мы ставили перед собой цель влиться в workflow работы DS безболезненно для процесса разработки ML-решений. Далее о том, как мы это сделали.

Рассмотрим workflow работы DS (рисунок ниже). Построение данных выполняется либо DS-ом, либо аналитиком с помощью Spark или Hive. Эксперименты проводятся в JHub, логируются в Mlflow; модельки складываются в Mlflow storage, код кладется в Gitlab.

Сервинг моделей выполняется с помощью Argoworkflow, если вычисления проводятся на кластере. Либо поднимается REST API или gRPC-сервисы с помощью оператора SeldonCore.

Напомним, что в Mlflow попадает немного информации о моделях: название модели, тип, описание, версия. Нам важно наличие фичей и их связей с витринами, что автоматически не подтягивается OMD.

Опишем, как мы добавляем lineage в OMD (рисунок ниже). DS строит модель на определенной витрине данных. В процессе анализа данных и обучения модели остаются нужные модели колонки — фичи.  По неймингу витрин и столбцов мы получаем их UUID из OMD API, который будем использовать в дальнейшем. Из них формируем конфиг для добавления lineage в OMD.

DSы хранят код в гите и пользуются для ML-проектов некоторым шаблоном. Yaml попадает в определенную директорию в коде проекта.

При обновлении папки с конфигом тригерится CI-пайплайн, который исполняет скрипт обновления (или отрисовки нового) линейджа соответствующей ML-модели на основе конфига.

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

Вот что происходит в ролике выше.

 

В разделе ML-models видим, как и ранее, все команды с Mlflow, выбираем одну из них, выбираем загруженную модель из mlflow, погружаемся в нее, выпадают все фичи, от которых она зависит. Перемещаемся в lineage. Здесь видим связи модели с витринами. Есть возможность раскрыть более глубокие связи модели с предагрегатами витрин, если такие связи есть в OMD. Также можно посмотреть конкретные столбцы, от которых зависит модель. Для этого клацаем на одну из таблиц предагрегатов, справа всплывут все столбцы, от которых зависит модель. Теперь выберем одну из фичей и забьем ее в поиск. Нам выдадут все модельки, которые зависят от данной фичи или от фичи, которая близка к ним по имени. В данном примере мы видим фичу, близкую по имени. 

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

Расследование инцидентов 

Как теперь выглядит наш флоу работы с инцидентами по деградации модели.

Наблюдаем снижение метрики модели. Аналитики по lineage в OMD восстанавливают зависимости витрин с фичами для модели и начинают искать в них причину деградации. После обнаружения оповещается домен и начинаются работы по исправлению. Одновременно с этим в OMD прослеживаются остальные зависимости продуктов от этого домена и выполняется оповещение клиентов домена. Раньше мы это сделать не могли и многие продукты просто не знали, что один из их источника может быть сломан.

Эффект и планы 

Бизнес-эффект мы получили следующий: при возникновении инцидента время устранения последствий сократилось в среднем в 4 раза.

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

Что ещё не сделано: нет удобных нотификаций. Надо делать, прорабатываем.

Что хотим еще попробовать в OMD. Интересен функционал Data Quality как универсальный инструмент для продуктовых команд. Интересно автоматизировать lineage витрин в airflow через предоставляемый функционал от OMD.

Комментарии (0)