Шесть лет назад я занимался стартапом FscoreLab, мы разрабатывали ML-системы для кредитного скоринга. Тогда я ещё слыхом не слыхивал о термине MLOps, да я и не уверен, что он вообще существовал. Однако, необходимость определённых практик и процессов, которые сейчас относят к MLOps, стала быстро понятна уже тогда. Один из самых важных уроков того времени - если модель обучить, задеплоить и отправить в свободное плавание, то рано или поздно, постепенно или внезапно, но случится что-то не очень хорошее. Да, сейчас от этого "откровения" хочется зевать - написана тонна книг и статей, запилена куча полезных инструментов, но в то время пришлось собирать систему ML-мониторинга опытным путём из подручных материалов. Состояла она из следующих компонентов:

  • Flask-SQLAlchemy для записи в БД информации о запросах и предиктах

  • Dash для создания удобного браузера для БД с фильтрами и поиском, доступного даже с телефона ночью (с некоторыми клиентами у меня была разница во времени в 10 часов)

  • Flask-Mail и cron для отправки ежедневных и еженедельных отчётов о сделанных предсказаниях и полученных запросах

  • Sentry, засылающий алерты об ошибках в Слак

  • Jupyter-ноутбучек, в котором раз в какое-то время забирались данные из БД и в pandas-датафрейме прогонялось несколько простых ассертов (например, что не появилось новых, неизвестных значений в какой-то колонке) и строилось несколько графиков. Впоследствии этот процесс был автоматизирован

MLOps через еще 6 лет...
MLOps через еще 6 лет...

Материал является адаптированной версией с моего ТГ-канала Варим ML

Эта с виду шаткая конструкция нормально справлялась со своими задачами, много лет служила верой и правдой и спасла нас от немалого количества фейлов, а наших клиентов - от некорректных предиктов и потерянных денег. В Цельсе мы долгое время были заняты гонкой за метриками и выходом хоть в какой-нибудь прод, поэтому понадобилось немало времени, прежде чем мы привели нашу систему мониторинга в порядок, а некоторых важных компонентов в ней не хватает до сих пор. Да, материалов про мониторинг много, но личный опыт и конкретные инструменты - это всегда приятно, да и многие статьи написаны вендорами MLOps-решений и не всегда объективны ????

Чем отличается мониторинг ML-систем?

Систему ML-мониторинга часто изображают в виде подобной пирамиды:

https://www.evidentlyai.com/blog/ml-monitoring-metrics
https://www.evidentlyai.com/blog/ml-monitoring-metrics

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

Глобально у ML-систем есть несколько нюансов, осложняющих их мониторинг:

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

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

  • Мониторинг качества работы ML-систем часто затруднён из-за delayed target - ведь чтобы узнать правильность предсказания нужно либо дождаться ground truth (например, вернул ли человек займ вовремя), либо разметить данные.

  • Часто ML-метрики тяжело привязать к бизнес-метрикам. Например, система может выдавать достаточно точные предикты, но если ей никто не пользуется или пользуется не так, как задумывалось, то бизнес-эффект будет сведён на нет.

  • Какие-то показатели, которые хочется мониторить (например, медиана или мода тензора), не вычисляются в ходе работы системы. Чтобы не замедлять работу системы, их расчёт нужно производить в отдельных пайплайнах, что усложняет архитектуру системы.

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

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

  • Разнообразие входных данных - сколько производителей рентген-аппаратов есть, много ли у них настроек, как сильно друг от друга визуально отличаются исследования разных людей?

  • Критичность решений, которые принимаются с помощью ML-системы - система предназначена для детекции рака или определения степени плоскостопия?

  • Автономность системы - каково участие системы в процессе постановки диагноза?

  • Количество, разнообразие и стабильность внешних источников входных данных - используем ли мы для предсказания какую-то внешнюю информацию о пациенте (возраст, пол, вес)? Откуда она приходит, сообщат ли нам об изменениях?

  • Новизна и степень решённости задачи - детекция лиц персонала на проходной больницы или детекция новообразований мозга?

  • Сложность системы и количество компонентов - есть ли у нас каскад моделей, которые зависят друг от друга?

  • Тип входных данных - табличные, текстовые, картинки, видео, звук?

  • Возраст ML-системы - был ли недавно новый большой релиз, сколько уже времени система работает в продакшне?

Давайте перейдём к более подробному обзору видов мониторинга ML-систем.

Классический мониторинг

Это показатели, связанные с инфраструктурой и корректной работой приложения:

  • Ошибки выполнения кода

  • Нагрузка - количество запросов во времени

  • Скорость работы - latency, throughput

  • Утилизация ресурсов - CPU, GPU, RAM, жёсткий диск, сеть

  • Error rates - проценты запросов с разными типами ошибок (не смогли найти целевой орган, не смогли прочитать DICOM-файл и другие)

Для классического мониторинга в Цельсе мы используем Sentry с алертами в Mattermost, Grafana, даш Кубернетеса, телеграм-бот для алертов инфры и другие известные всем инструменты.

Мониторинг данных

Техническое качество входных данных

Входные данные постоянно меняются, и очень часто это происходит по сугубо техническим причинам:

  • Изменение схемы данных - внешний источник обновил схему или формат данных

  • Источник данных сломался - поступают неверные данные, например, NaNы

  • Сломался предыдущий компонент в каскаде - другая ML-модель отдаёт неверный предикт или неверно работает препроцессинг изображений

  • Неверный инпут от пользователей - опечатка в тексте, которую мы не провалидировали

Рано или поздно эти проблемы начнут сказываться на качестве работы модели, поэтому лучше обнаружить их как можно быстрее:

  • Валидировать схему и формат входных данных. Это включает в себя как простые проверки типа отсутствия NaN-значений, так и более сложные доменные вещи - например, проверка, что размер целевого органа на исследовании лежит в заданных пределах. Для создания таких "ожиданий" от данных можно использовать либу Great Expectations.

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

Дрифты

Наверное, каждый так или иначе слышал о пресловутых data drifts:

https://wilds.stanford.edu/datasets/
https://wilds.stanford.edu/datasets/

Дрифты обычно делят на три типа:

  • Covariate drift - изменение распределения фичей, может происходить по естественным причинам (подключилась новая больница) и по техническим (изменился формат входных данных).

  • Target drift - изменение распределения целевой переменной. Например, изменился баланс классов "норма" и "патология" из-за начала эпидемии.

  • Concept drift - изменение связи между фичами и таргетами, оно может случаться постепенно, резко или с определённой периодичностью.

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

  • Мониторинг дрифтов можно осуществлять по сырым данным, их статистикам (например, средняя интенсивность пикселей), по промежуточным или финальным предсказаниям системы.

  • Дрифты можно детектировать по каждой фиче независимо (univariate) или по всему множеству сразу (multivariate). Во втором случае перед проведением стат-теста часто ещё проводят процедуру dimensionality reduction, а это можно делать тысячей разных способов.

  • Дрифты отличаются по степени воздействия на качество модели. Распределение фичи может измениться, но если она не особо значима для предсказания, то переобучение модели может не потребоваться.

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

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

На данный момент ни одно из специализированных решений (EvidentlyAI, alibi-detect, TorchDrift) для детекции дрифтов у нас не используется, но это прям в ближайших планах. Сейчас мы узнаём о каких-то изменениях входного потока данных:

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

  • С помощью чайка-мониторинга. По аналогии с чайка-менеджментом и чайка-код-ревью чайка-мониторинг - это рандомный ручной мониторинг. Лень кодить или пилить таски?Мможно посмотреть на случайные исследования из потока и предсказания наших систем.

Out-of-Distribution & Anomaly Detection

Нет, это не копьё в груди, а "артефакт исследования"
Нет, это не копьё в груди, а "артефакт исследования"

Часто в нашу систему залетают снимки, которые являются явными аномалиями. В своих выступлениях я рассказывал про рентген-снимки ножниц и канистр, есть и менее необычные случаи - сильные артефакты, стенты, грудные импланты. Если подобных исследований не было в обучающей выборке, или просто по объективным причинам (плохое качество изображения) система не сможет сделать корректное предсказание, было бы здорово уметь это детектировать:

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

  • Это помогает искать необычные примеры, которые нужно изучить или доразметить.

  • Это помогает быстрее детектировать технические проблемы во входных данных - например, неверная настройка аппарата.

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

https://arxiv.org/abs/2206.09426
https://arxiv.org/abs/2206.09426

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

  • ML-методы - отдельная модель для определения качества изображения или обрезки целевого органа или uncertainty-методы, часто используемые для активного обучения (confidence branch, learning loss, энтропия предсказаний).

  • Экстремальные значения. Наши ML-системы логируют информацию о запросах (например, свойства картинок, промежуточные и финальные предсказания) в ElasticSearch, откуда их легко достать в те же pandas-датафреймы. Затем можно посмотреть глазами на исследования с экстремально низкими или высокими значениями различных показателей. В ближайшем будущем мы планируем также попробовать специальные библиотеки типа PyOD или той же alibi-detect.

Мониторинг качества

Пользователям наших систем и бизнесу не очень интересно слушать про какие-то аут-оф-дистрибьюшны, имадж кволити и дрифты - им нужны МЕТРИКИ. На темы тестирования и измерения качества ML-систем я уже делал пару докладов - раз и два, а в рамках разговора про мониторинг главной особенностью оценки является тот самый delayed target, про который я писал выше. У нас эта проблема решается следующим образом:

  • Если есть доступ к финальному текстовому заключению врача, либо его фидбек в формате "лайк-дизлайк" (human-in-the-loop формат), это позволяет без сильной задержки считать часть классификационных метрик.

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

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

В некоторых случаях (как в кредитном скоринге) "разметку" за нас осуществляет окружающий мир - по истечении срока займа человек возвращает его или нет. Это создаёт довольно большой лаг между предсказанием и расчётом метрик. В данном случае стоит обратить своё внимание на стабильность предсказаний (есть ли сильные сдвиги во времени или по сравнению с предыдущими версиями системы и бейзлайнами). Ещё можно попробовать оценить изменение метрики в зависимости от изменения распределения данных. Например, если на определённом сегменте данных на тестах модель показывает не очень хорошие результаты, и доля этого сегмента при этом растёт, то мы можем ожидать снижение метрики.

Работа с инцидентами

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

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

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

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

  • Обнаружение - проблема обнаружена с помощью ручного/автоматического мониторинга или после жалобы от пользователей.

  • Поиск прямых причин - поиск триггера. Здесь нам весьма помогут логи и удобные инструменты для визуализации данных.

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

  • Долгосрочное решение - например, переобучаем модель на новых данных.

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

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

Как вы уже, наверное, поняли из всего поста, главная особенность ML-инцидентов - их "тихость". Система продолжит работать как обычно, но будет отдавать неверные предсказания из-за неверного конфига, бага, дрифта данных, изменения внешнего источника данных. Дополнительно осложняет ситуацию, что это может затронуть только часть пользователей, и в стандартных метриках мы не увидим особой просадки. Часто в таких случаях мы узнаём о проблемах случайно (привет, чайка-мониторинг) или после жалоб от пользователей.

Дополнительные материалы

Кое-какие дополнительные материалы для изучения:

Если вы хотите узнать ещё больше об организации процессов ML-разработки, подписывайтесь на наш Телеграм-канал Варим ML

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