Круговорот данных для ML-моделей: как мы Human-In-The-Loop строили
Как технологии Machine Learning используются в Kolesa Group
Технологии Machine Learning используются в Kolesa Group с 2017 года. В компании есть отдел ML & Operations, где 3 ML-инженера и 2 MLOps-инженера разработали и вывели в продакшен уже несколько десятков ML-моделей, которые улучшают работу продуктов Kolesa Group.
В этой статье Денис Крумко, MLOps-инженер Kolesa Group, через призму реальных рабочих кейсов расскажет о следующем:
• Как выстроить и развивать платформу для работы с данными для ML-моделей;
• Что такое Label Studio и как с ним работать;
• Принцип Human-In-The-Loop;
• Результаты эксперимента и что будет дальше.
Как выстроить и развивать платформу для работы с данными для ML-моделей
Любая модель начинается с данных
Для обучения хорошей ML-модели требуется очень много данных, и при этом их для начала кто-то должен «разметить». Разметка — это проставление для объектов определённых лейблов, чтобы потом ML-модели могли сами анализировать новые объекты и выдавать вердикты. Можно для этого брать готовые датасеты из интернета или платить за разметку в аутсорсе. Но учитывая региональные особенности наших продуктов, не всегда получится найти хорошие данные в интернете. Поэтому мы в компании делаем необходимую в задачах разметку для моделей сами.
Проблем с поиском данных для разметки у нас нет, потому что миллионы наших клиентов выкладывают свои объявления на Kolesa.kz, Krisha.kz и Avtoelon.uz. Ежедневно пользователи компании подают 77 тысяч объявлений, которые нужно проверять на корректность. Такой огромный поток информации обрабатывает отдел модерации из 31 человека. Каждый год поток объявлений увеличивается, бизнес растёт, а отдел модерации численно прирастает минимально. Масштабироваться и эффективнее бороться с некорректными объявлениями им помогает наш отдел ML & Operations.
Наши ML-модели умеют искать людей на фото, определять вотермарки, искать дубликаты, закрашивать номер авто и многое другое. В службе заботы о пользователях модели используются для оценки разговоров операторов, чтобы дать лучший сервис для наших клиентов.
1. Начнём строить пайплайн
Для начала определимся с основными этапами, которые должны быть в пайплайне по разработке ML-моделей:
- получение исходных данных;
- разметка данных;
- обучение модели на лейблах;
- релиз модели в продакшен.
Вопрос с данными у нас решён, они уже централизованно лежат в нашем S3 Хранилище Ceph. Но приступать к их разметке ещё рано. Потому что сначала данные нужно правильно сохранить. Но зачем сохранять то, что уже и так лежит в хранилище, почему просто не брать данные для разметки оттуда? С этим мы в команде уже немного обожглись, поэтому у меня для вас есть правило: «Не доверяйте «чужим» данным».
Это особенно актуально, если у вас большая компания: много команд и проектов, чаще всего с разными политиками хранения данных. Ваши коллеги могут и не знать, что нельзя было удалять бакет, данные из которого сейчас использовались при разметке. Поэтому старайтесь делать копии файлов в свои бакеты, где вы сможете отвечать за сохранность данных. Здесь действует простой принцип — созданная разметка без исходных файлов не несёт для нас пользы.
Теперь, когда данные надежно хранятся, то мы можем приступить к их разметке. Где мы будем это делать?
2. Выбор своего «героя»
Теперь нужно выбрать подходящий инструмент для разметки. Всё как в ролевых играх: есть выбор из нескольких героев, но идеального варианта нет. Один умеет только махать мечом, другой — могущественный маг, но здоровья нет…
Было бы круто, если на рынке было только 3 инструмента для разметки…
Если вы посмотрите список Awesome Data Labeling, то увидите почти полсотни утилит и сервисов с целью добавления лейблов для данных. Этот список курирует компания Human Signal, которая разрабатывает свой инструмент под названием Label Studio. Мы в итоге на нём и остановились.
Что такое Label Studio и как с ним работать
Label Studio (далее Студия) — это open-source инструмент с web-интерфейсом, доступный всем у кого есть браузер: клиентам ничего устанавливать не нужно.
Если интересно, то маскот Label Studio — это опоссум, а не крыса
Бэкенд Студии легко запускается через готовый Docker-образ, либо устанавливается через одну команду «pip install label-studio». Потому что весь бэкенд там написан на Python, на фреймворке Django, а фронтенд — на React JS.
«Killer feature» для нас оказалась гибкость Студии. Обычно инструменты для разметки заточены под computer vision и гораздо реже под разметку текста, аудио или видео. А Label Studio может работать с широким спектром видов данных, которые нам нужны в задачах.
В этом нам помогает так называемый интерфейс разметки. Мы создаём в Студии проекты под разные задачи, и для каждого проекта можем описать следующее:
- как данные должны отображаться;
- какие инструменты для разметки должны быть.
И таких инструментов разметки там десятки.
Так мы настраиваем интерфейс разметки
Сам интерфейс настраивается кодом — JSX элементами от Label Studio. По сути, вы собираете страницу на HTML, только используете другой набор тэгов. Здесь можно добавить собственные CSS-стили для каждого проекта.
Главное, что этот интерфейс можно менять, даже когда разметка уже активно ведётся. Например, модераторам не хватало поля с номером телефона клиента, и при наличии поля в данных его легко можно добавить в настройке интерфейса.
Модераторы инструментом тоже довольны, потому что он прост и понятен. Просто заходим в Label Studio, нажимаем кнопку «Начать разметку» и нам выдаются задачи из общей очереди.
1. Встраиваем Label Studio в пайплайн
Теперь пора встраивать нашего «опоссума» в пайплайн. Мы хотим, чтобы данные автоматически попадали в Студию на разметку, а готовая разметка должна из неё доставаться.
Первая задача решается легко, там из коробки поддерживаются S3-хранилища, однако выгрузка происходит только вручную — по нажатию кнопки в интерфейсе или по вызову через API. Уже здесь возникают сложности, что автоматизировать процессы придётся через cronjob-задачи, чтобы данные постоянно подгружались на разметку.
Что же касается готовой разметки, мы не сразу нашли оптимальный способ эту разметку доставать. Вариантов есть несколько:
а) Ручной экспорт
Экспортировать разметку вручную можно через интерфейс, доступен десяток разных форматов (JSON, CSV, YOLO и т.д.). Удобно для тестирования, но пайплайн на этом не построишь.
б) Экспорт в S3
Есть возможность выгружать разметку в виде таких же JSON-файлов, но сразу в S3-хранилище. Однако мы заметили, что каждая такая синхронизация приводит к скачкам потребления RAM, при этом память после этого не возвращается. Возможно, в будущих версиях утечки памяти починят.
Такие скачки можно будет наблюдать в Grafana
в) Выгрузка по API
Почти все действия в Студии дублируются через вызовы в API и можно просто выгружать все лейблы постранично. Но API возвращает все данные без возможности фильтрации.
г) Данные из БД
Всегда остается вариант доставать данные напрямую из базы данных, потому что созданная разметка также сохраняется в собственную БД Label Studio. Поддерживаются PostgreSQL и SQLite, но использовать SQLite для продакшена — это крайне плохая идея. Для удобства получения данных из БД можно использовать CDC-инструменты, например, Debezium или Kafka Connect.
д) Webhooks
Это самый подходящий нам вариант, который есть в Label Studio, потому что вебхуки вызываются сразу при создании разметки. Вебхуки настраиваются отдельно в каждом проекте Студии. Встаёт один вопрос: кто их будет обрабатывать?
2. Обработчик вебхуков
Здесь появляется наш первый простейший ETL-микросервис, написанный нами на Go. Он получает по HTTP от Label Studio вебхук с разметкой, трансформирует его. Затем складывает как сообщение в RedPanda, которая используется как общая шина данных для общения микросервисов.
Обработчик вебхуков отбрасывает лишние поля, потому что в запросе приходит, например, огромный код интерфейса разметки проекта, который нам не нужно хранить.
Пример части вебхука с координатами номера авто. Полный код вебхука занял бы половину статьи
Но есть и обратная проблема. Некоторых данных в запросе не хватает, например, кто является автором разметки. Для нас важно знать кто из модераторов создал разметку, потому что это позволяет нам оценивать качество разметки. Поэтому приходится по API запрашивать у Студии данные о пользователе и добавлять их в сообщение перед отправкой в RedPanda.
3. Хранение разметки и обучение моделей
После отправки полученной разметки в шину данных (Redpanda, Apache Kafka и т.п.), дальнейшая задача вашей инфраструктуры — как с этими данными поступать.
Можно положить данные в хранилище, чтобы спустя время, когда данные накопятся в достаточном количестве, можно было начать процесс переобучения модели ML-инженером. Именно так мы поступаем с нашей разметкой в компании. У нас есть ещё один микросервис, который сохраняет разметку в MongoDB, решает проблемы дубликатов, фильтрации и разметки из других источников. Вместе с сервисом у нас есть CLI утилита, которая позволяет эти данные из БД доставать.
С другой стороны можно реализовать непрерывный процесс автоматического переобучения и деплоя моделей по мере поступления разметки. Но такая задача требует как механизмов слежения за метриками модели, так и автоматического деплоя моделей после переобучения. Надеюсь, что это будет то, к чему мы в итоге придём.
На данный момент для автоматизации деплоя наших моделей мы используем MLflow, про который мы писали в статье «Одиссея ML-модели: от обучения до продакшена».
Принцип Human-In-The-Loop
Нужно понимать, что релиз ML-моделей — это не game over. Мы должны отслеживать, хорошо ли они справляются со своей задачей в продакшене.
В этот момент у нас происходит закольцовывание пайплайна, когда мы понимаем, что вердикты моделей — это тоже данные. Если мы их правильно соберём и положим в хранилище, то затем сможем загрузить их в Label Studio в качестве отдельного проекта и отправить на повторную проверку.
Так мы превращаем пайплайн в цикл
Люди проверяют результаты моделей, находят замечания, модели на этих данных переобучаются, происходит новый релиз, и так по кругу. Это особенно важно для CV-моделей, где сложно выделить какую-то цифровую метрику для валидации. Так и выстраивается цикл под названием Human-In-The-Loop, потому человек здесь является очень важным звеном.
Можно возразить, что этот процесс называют Active Learning. Я считаю, что это дело терминов, главное понимать как весь процесс устроен, поэтому я не акцентирую внимание на самой фразе «Human-In-The-Loop», просто мы решили именно так называть разработанный пайплайн. Когда весь процесс был продуман и построен, мы начали его внедрение в продуктах.
Первый эксперимент
В начале 2024 года у нас в компании проводился первый показательный эксперимент, который мы между собой называли «Постмодерация Крыши». Он был полностью построен на рельсах нашего пайплайна с использованием Label Studio.
Мы запустили в продукте krisha.kz группу моделей по модерации объявлений: поиск скриншотов, людей на фото и т.д. При этом мы не просто сделали релиз и ушли пить кофе, а вели активный процесс «постмодерации» — т.е. перепроверки вердиктов моделей.
Так, примерно за 3 недели команда из 14 модераторов смогла проверить 52 тысячи фотографий в Label Studio. Давайте посмотрим, как всё это работало.
Так работал процесс постмодерации
От общего объёма всех брался 1% объявлений и отправлялся на автомодерацию ML-моделям. Если они находили на фото что-то запрещённое, то объявление уходило на ручную модерацию. Если со всеми фото в объявлении было всё OK, то оно сразу уходило в лайв.
Задачей отдела модерации было перепроверить все фото из лайва и постараться найти на них то, что не смогли найти ML-модели. 1% объявлений может показаться простой задачей, но на деле команде приходилось перепроверять несколько тысяч фотографий каждый день.
И заслуга нашей команды ML & Operations состоит в том, что за время эксперимента пайплайн работал без нашего вмешательства:
- фотографии автоматически забирались с krisha.kz раз в день;
- затем эти фото складывались в Ceph в отдельный бакет;
- запускалась синхронизация в проекте в Label Studio;
- модераторы проверяли новую порцию данных: по сути вели такую же разметку данных, добавляя лейблы вида «есть цена на фото» или «фото является скриншотом» и т.п.;
- готовая разметка сразу сохранялась в сервисе лейблов.
Давайте посмотрим, чего мы этим добились.
Результаты эксперимента и что будет дальше
1. Меньше времени на разметку
Раньше разметка могла вестись в Google-таблице и проверка небольшого датасета могла занимать месяц. Сейчас мы видим по логам, что один модератор тратит на разметку 3-5 секунд. Раньше результат в 50 тысяч проверенных фото за пару недель казался нереальным.
2. Меньше ручной работы
Пайплайн по большей части уже автоматизирован. Да, загрузка данных в Label Studio у нас сейчас работает на простом cronjob. Переобучение большинства моделей всё ещё происходит в зависимости от бизнес-требований продукта, но есть модели, которые автоматически переобучаются по периодам. За время построения пайплайна мы сильно прокачали навыки работы с RedPanda и развернули и внедрили ряд инструментов для Stream Processing.
3. Аналитика работы моделей
Главное, что мы впервые узнали, как наши модели работали «в бою»: какой у них precision и recall, и можем ли мы теперь выпускать их на больший процент данных. Плюс у нас уже есть готовый датасет для дообучения моделей.
Я вам рассказал только про один такой эксперимент, однако у нас в компании много моделей, которые только предстоит интегрировать в наш Human-In-The-Loop. Поэтому работы у нас очень много. Например, «Постмодерация Крыши» уже перестала быть экспериментом, а стала настоящим бизнес-процессом и для модераторов, и для самого продукта.
Наша команда модерации уже начала постепенно переключаться с задач ручной модерации на задачи разметки данных. Думаю, со временем они будут помогать нам делать всё больше моделей для решения бизнес-задач.