Почему в проектах машинного обучения накапливается технический долг, каковы главные факторы его появления и каким образом MLOps устраняет проблемы, связанные с разработкой, тестированием, развертыванием и сопровождением систем Machine Learning.
Скрытый технический долг в ML-системах
Технический долг означает дополнительные затраты, возникающие в долгосрочной перспективе, с которыми сталкивается команда, в результате выбора простых и быстрых вариантов вместо принятия решений, более правильных в долгосрочной перспективе. Для систем Machine Learning технический долг существует на системном уровне, а не на уровне кода. Поэтому традиционного подхода к техническому долгу, как и в разработке ПО, недостаточно для его устранения: нужны подходы, специфичные для ML.
Системный уровень в машинном обучении относится к общей архитектуре и дизайну ML-системы, а не к отдельным компонентам, таким как алгоритмы или данные. Прежде всего, сюда входят нефункциональные требования к системе: масштабируемость, производительность, надежность и ремонтопригодность. Это также включает интеграцию и координацию различных компонентов, таких как конвейеры данных, хранилище, вычислительная и обслуживающая инфраструктура. Еще важны варианты дизайна, связанные с развертыванием ML-модели: локально, в облаке или на периферии. При этом стираются границы системы: используемые пакеты ML приводят к созданию больших объемов связующего кода, который может блокировать систему, а обрабатываемые данные влияют на систему Machine Learning. Поэтому строгие абстрактные зависимости, полезные для согласованной производительности ПО, не очень подходят для ML-систем, которые применяются, когда строгая логика программного кода не может реализовать желаемое поведение без зависимости от внешних данных.
Модель машинного обучения состоит из сложных отношений между признаками выборочных данных. Определение и построение полезных отношений между этими признаками делает ML-модель мощной, но непригодной для изолированных улучшений. В Machine Learning работает принцип CACE (Change Anything Change Everything): изменение чего-либо меняет все. Это характерно не только к входным сигналам, но и к гиперпараметрам, настройкам обучения, методам выборки, порогам сходимости, выбору данных и остальным настройкам ML-системы. Чтобы устранить такую запутанность, можно изолировать модели как подзадачи или подмодели, обслуживая все системы, состоящие из них, как ансамбли. Альтернативой является наблюдение за изменениями в выходном поведении по мере их возникновения и применение стратегии автоматизированной разработки. Сложность увеличивается, когда несколько ML-системам сильно зависят друг от друга. В этом случае можно добавить дополнительные фичи к базовой модели, чтобы использовать простую модель, способную различать случаи.
Технический долг растет при использовании данных не по назначению, что в классической разработке ПО решается ограничением видимости. В Machine Learning также помогает предоставление доступа к данным и моделям только определенным пользователям и командам, а также тщательное управление этими разрешениями.
Поскольку системы машинного обучения сильно зависят от данных, необходимо версионирование входных сигналов, которые меняются со временем. Стратегия управления версиями должна быть такой, чтобы исходная версия сигнала сохранялась при создании измененной версии до тех пор, пока все измененные версии не будут обнаружены и протестированы во всех системах. Кроме того, следует оперативно устранять устаревшие фичи, которые полезны при обучении, но со временем стали нерелевантны для реальных вычислений. Здесь же можно вспомнить про мультиколлинеарность — корреляцию независимых переменных, которая затрудняет оценку и анализ общего результата, повышая размерность модели и сложность вычислений. Справиться с этим позволяют оценки с исключением одной функции (LOFO, Leave One Feature Out).
Этот подход экспериментально находит релевантные и полезные фичи и выбирает их. Например, есть Python-модуль для LOFO под названием lofo-importance. Он вычисляет важность набора функций на основе выбранной метрики для выбранной модели путем итеративного удаления каждой фичи из набора и оценки производительности модели с помощью схемы проверки, в зависимости от выбранной метрики. LOFO сначала оценивает производительность модели со всеми включенными входными фичами, затем итеративно удаляет одну фичу за раз, повторно обучает модель и оценивает ее производительность на проверочном наборе. Затем сообщается среднее значение и стандартное отклонение важности каждого признака. Если модель не передается в качестве аргумента LOFO Importance, она будет запускать LightGBM в качестве модели по умолчанию.
ML-модель следует обновлять с течением времени, не всегда возможно предположить поведение системы до выпуска в производство. Здесь возникают прямые и скрытые петли обратной связи. Петли прямой обратной связи непосредственно влияют на поведение самой модели. Проблема здесь в моделях обучения с подкреплением, где не только оптимизируются решения на основе предыдущих наблюдений, но и изменяется для каждой ситуации. Этот подход плохо масштабируется в зависимости от размера пространства действий. Справиться с проблемой помогает рандомизация или изоляция некоторых данных от внешних влияния. Скрытые петли обратной связи означают, что две отдельные системы скрытым образом влияют друг на друга, что также случается при сильной связанности различных ML-моделей.
Технический долг в системах Machine Learning растет не только из-за данных и алгоритмов их обработки. Антипаттерны разработки ПО также вносят свою лепту. Одним из таких антишаблонов является склеивающий код, который используется для соединения моделей, ETL-конвейеров и других частей системы. Это увеличивает количество зависимостей и мешает вносить изменения. Поэтому лучше включать внешние пакеты в API так, чтобы повторно использовать одни и те же функции и настраивать их специально для потребностей. Впрочем, реальная система может в конечном итоге состоять из 5% кода машинного обучения и 95% связующего кода. Поэтому может быть дешевле создать чистое нативное решение, а не повторно использовать универсальное.
Разработка и ETL-конвейеров для доставки данных к ML-моделям требует дорогостоящих сквозных интеграционных тестов, увеличивая накладные расходы на инфраструктуру машинного обучения. Дополнительную сложность в сопровождении вносит разномастный набор множества языков программирования для реализации задач ETL-конвейера.
Системы машинного обучения поставляются с множеством настраиваемых параметров, таких как параметры обучения, количество фичей, правила преобразования данных и пр. Количество этих конфигураций может быть очень велико, и у каждой из них есть свои факторы сбоя, которые не всегда известны и могут быть заранее устранены. Поэтому для эффективного управления конфигурациями должно быть возможно увидеть разницу между нескольким вариантами, а также найти неиспользуемые или избыточные настройки. Наконец, все конфигурации должны пройти полную проверку кода и быть проверены в репозитории.
Устранить или хотя бы сократить все эти долги помогает концепция непрерывного управления и сопровождения ML-систем под названием MLOps. Далее рассмотрим, как она адаптирует идеи непрерывной доставки готового продукта к области Machine Learning.
MLOps как DevOps для Machine Learning
Прежде чем рассматривать MLOps как DevOps для машинного обучения, вспомним ключевые идеи этой концепции. Одной из них является непрерывная доставка (Continuous Delivery), которая автоматизирует подготовку изменений программного кода для производственного развертывания. Для этого разработчики ПО совместно используют кодовую базу, интегрируют свой код в основную ветвь и выпускают программный продукт. Это обеспечивает лучшее качество ПО, повышает производительность и эффективность процессов разработки.
Родственной концепцией является непрерывная интеграция (Continuous Integration), которая позволяет разработчикам постоянно объединять свои изменения кода в общий репозиторий, автоматизированное выполняя сборки и тестирование. Основными целями непрерывной интеграции являются более быстрое обнаружение и устранение проблем, повышение качества ПО и сокращение времени для проверки и публикации новых обновлений. Непрерывная поставка расширяет непрерывную интеграцию, распространяя все изменения кода в тестовую или производственную среду после процесса сборки.
Конвейер непрерывной доставки — это последовательность шагов, которые необходимо выполнить для доставки новой версии ПО с большей точностью, надежностью и устойчивостью. Для запуска конвейера непрерывной доставки изменения исходного кода передаются в репозиторий. Затем выполняется сборка, когда исходный код упаковывается в виде пакетов и исполняемых файлов вместе со всеми зависимостями. Далее проводятся автоматические тесты, чтобы убедиться, что код работает должным образом. Наконец, когда исполняемый экземпляр ПО успешно прошел все автоматические тесты, он готов к развертыванию в рабочей среде.
В проектах машинного обучения реализация CI/CD имеет следующие трудности:
- проблема воспроизводимости, т.к. ML-проекты чаще всего являются экспериментальными. Чтобы повторно использовать код и дублировать производительность ML-модели в одном и том же наборе данных, необходимо обеспечить отслеживание и поддержание воспроизводимости всех этапов и компонентов системы.
- проблемы тестирования, т.к. проверить следует не только исходный код, но и данные, а также математические алгоритмы в дополнение к обычным модульным и интеграционным тестам.
- проблема развертывания многоэтапного конвейера, который автоматически переобучает и запускает другую службу в рабочую среду для работы ML-системы. Этот конвейер усложняет процесс непрерывной доставки, требуя автоматизации этапов обучения и проверки новых моделей перед развертыванием.
Решить все эти проблемы позволяют специализированные MLOps-инструменты, такие как MLflow, Kubeflow, BentoML, а также средства управления ETL-конвейерами типа Apache AirFlow, Dagster, Kedro и другие фреймворки, которые мы регулярно рассматриваем. Таким образом, для использования машинного обучения в реальных проектах требуется нечто большее, чем просто развертывание модели Machine Learning в производстве. Настроив систему непрерывной доставки для машинного обучения, можно быстро выполнять итерации на основе изменений в данных и бизнес-среде, а также автоматически разрабатывать, тестировать и выпускать новые реализации ML-конвейера.
Как избавиться от технического долга в проектах аналитики больших данных, используя современные инструменты MLOps, вы узнаете на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники