Привет! Меня зовут Катерина Цаплина, я программный эксперт курса «MLOps для разработки и мониторинга моделей», и это вторая статья цикла о том, как компании реализуют MLOps. В предыдущей части мы разбирали, какие архитектурные подходы скрываются за MLOps: от workflow-фреймворков до managed-сервисов и внутренних платформ.
В этой статье хочу разобрать один из самых известных платформенных кейсов — Michelangelo компании Uber. Он ценен тем, что наглядно показывает, как ML-платформа вырастает из практических задач и затем эволюционирует вместе с изменением сценариев: от классического ML к deep learning и LLMOps.
Поговорим о том, как устроена платформа, какие сущности и слои в ней ключевые и почему этот пример остаётся полезным. Посмотрим на Michelangelo через призму российских реалий, порассуждаем о связи между зрелостью ML в компании и сложностью корпоративного ландшафта, а также о том, когда платформа действительно становится оправданной.
Дисклеймер: это будет разговор прежде всего о платформенной основе и архитектурной логике, а не попытка детально разобрать каждый компонент по отдельности — иначе текста хватило бы ещё на несколько статей.

Внутренние системы Uber нередко получают имена исторических фигур. Микеланджело был не только художником и скульптором, но и архитектором: он участвовал в проектировании купола собора Святого Петра, работал над укреплениями Флоренции — то есть создавал решения, в которых художественный замысел был неотделим от инженерного расчета. Для платформы, которая должна собирать множество компонентов в единую, устойчивую систему, такое имя подходит очень хорошо.
Michelangelo считается одной из первых промышленных ML-платформ. Uber запустил её в 2015 году, когда машинное обучение уже работало в ключевых сценариях бизнеса: прогнозировало время прибытия, помогало с динамическим ценообразованием, спросом, рекомендациями и антифродом. Но по мере роста числа таких моделей стало понятно: недостаточно просто построить модель. Нужно ещё надёжно внедрять её в работу, поддерживать и масштабировать.
Ключевая идея платформы
По замыслу Michelangelo должна была стать внутренним Machine Learning as a Service. Логика здесь простая: продуктовые команды должны сосредоточиться на данных, признаках и качестве моделей, а платформа — взять на себя инфраструктурную часть работы.
В такой модели одной из ключевых метрик становится time-to-market — время от идеи до реального запуска модели в продакшен. Чем меньше ручной работы, согласований и разрозненных процессов, тем быстрее команда может проверить гипотезу и довести её до рабочего сервиса. Michelangelo как раз и стал инструментом, чтобы сократить этот путь.
Прямой цифры «Michelangelo сократил time-to-market на X%» у Uber в открытых материалах нет, но логика платформы постоянно описывается через ускорение итераций, снижение ручного труда и более быстрый путь от модели до production.
Архитектура Michelangelo
Uber не публикует единую детальную схему всей современной Michelangelo. В открытых материалах встречаются обзорные диаграммы ранней версии платформы, а более поздние публикации показывают только отдельные её части. Поэтому дальше опираемся на наиболее полную публично доступную версию архитектуры — она позволяет увидеть главное: из каких блоков складывается ML-платформа.
Например, в одной из первых статей Meet Michelangelo: Uber’s Machine Learning Platform приводится такая схема:

Схема не самая контрастная и местами выглядит так, будто её проектировали для людей с очень хорошим зрением. Но при всей своей визуальной аскетичности она хорошо показывает базовую логику ML-платформы: как в единую систему собираются ключевые этапы жизненного цикла модели — от данных и признаков до обучения, инференса, деплоя и мониторинга. По этим блокам и будем двигаться дальше.
Советую открыть картинку в отдельной вкладке, чтобы было легче ориентироваться, — я буду отсылаться к ней в следующих разделах статьи. Термины, которые можно найти на схеме, выделю жирным.
Базовые слои: offline и online
В Michelangelo с самого начала были разделены офлайн- и онлайн-контуры. В офлайн-контуре готовят данные, рассчитывают признаки, обучают и проверяют модели — здесь на первом плане длительные вычисления, работа с историческими данными и воспроизводимость. Онлайн-контур отвечает за работу модели в сервисе и выдачу предсказаний по запросу, а значит, требует низкой задержки, устойчивости, масштабирования и предсказуемого поведения под рабочей нагрузкой.
На практике такое разделение реализуется по-разному. Иногда офлайн и онлайн живут в одной общей инфраструктуре, но используют разные сервисы, очереди задач или пулы ресурсов. Иногда их разводят и на уровне инфраструктуры — по разным вычислительным узлам, средам или слоям платформы, чтобы тяжелые задачи обучения и пакетной обработки не влияли на сервисы предсказаний.
Например, обучение модели не должно забирать у онлайн-контура все GPU и замедлять сервис предсказаний. Массовый пересчет признаков не должен ухудшать время ответа рабочего сервиса. А запуск новых экспериментов и переобучения не должен напрямую влиять на уже работающую версию модели.
Для промышленной ML-платформы важно не только само наличие двух контуров, но и то, как они связаны. Модель, обученная в офлайн, должна попадать в рабочую среду в понятном и воспроизводимом виде, а признаки считаться одинаково и при обучении, и при реальном использовании. Иначе модель в продакшене начинает вести себя не так, как на этапе проверки.

Feature layer (слой работы с признаками)
Из разделения контуров почти сразу вытекает следующая задача: как сделать так, чтобы модель в обоих режимах опиралась на согласованные признаки. Именно поэтому одним из ключевых слоёв Michelangelo с самого начала стал слой работы с признаками.
Исторический контекст здесь важен: в середине 2010-х ещё не было привычных нам решений для feature store. Паттерн централизованного управления признаками тогда ещё только формировался, так что Uber здесь был скорее в роли первопроходца и строил этот слой сразу как часть своей ML-платформы — не как теоретическую архитектурную идею, а как ответ на практические проблемы.
В ранней архитектуре он был разделен на два хранилища:
Hive Feature Store для обучения, аналитики и расчета признаков вне реального времени.
Cassandra Feature Store для online-сценариев, где признаки нужно быстро передать в модель при запросе.
Позже этот слой развился в Michelangelo Palette — и это уже не просто хранилище, а централизованная система управления признаками. В ней можно задавать определения признаков, источники данных, зависимости, расписание пересчета и правила публикации в офлайн- и онлайн-контуры.
Зачем вообще нужен такой слой? Прежде всего, чтобы избежать расхождения между обучением и работой модели после запуска. Но не только. Он также нужен для переиспользования признаков между разными моделями, для единых определений и правил расчета, для прозрачности зависимостей и для того, чтобы новые модели не приходилось каждый раз собирать с нуля вокруг своей локальной логики данных.
Например, при обучении признак «среднее число поездок за 7 дней» могли рассчитать одним способом и на полных исторических данных, а в рабочем сервисе другим способом, на более свежем и частично неполном наборе. В результате модель начинает получать не совсем те же признаки, на которых ее обучали, и качество предсказаний может заметно просесть.
Обучение как управляемый процесс
Если feature layer в Michelangelo отвечает за работу с признаками, то следующий вопрос — как на платформе происходит само обучение модели.
На ранней схеме этот слой представлен довольно крупными блоками: обучение (Train Models) и оценка модели (Eval Models). Но в более поздних материалах Uber описывает его уже через сущности Pipeline и PipelineRun. Это важный архитектурный сдвиг: обучение перестаёт быть набором скриптов и становится управляемым процессом внутри платформы.
Pipeline задает сам процесс: какие шаги нужно выполнить, как готовятся данные, как обучается и проверяется модель. PipelineRun — конкретный запуск с зафиксированными параметрами, входными данными, артефактами и результатами. У дата-сайентиста может быть один Pipeline для переобучения модели, а каждый новый запуск — отдельный PipelineRun с новым срезом данных или другими гиперпараметрами.
Как именно платформа «знает» все это? Она хранит метаданные о процессе обучения. В ней явно описан сам Pipeline, а каждый PipelineRun регистрируется как отдельный объект со своими шагами, параметрами, статусами и результатами. За счёт этого платформа может видеть, какой процесс был запущен, из каких этапов он состоял, в каком состоянии находится и что получилось на выходе.
Такой подход даёт три ключевых свойства: воспроизводимость, стандартизацию и управляемость. Можно восстановить, как была получена конкретная версия модели, перестать каждый раз собирать обучение вручную и видеть статусы и историю запусков. По сути, здесь уже начинает проявляться логика control plane — управляющего слоя платформы.
Хранение моделей и переход к управляемому деплою
Когда процесс обучения становится платформенной сущностью, следующим шагом становится управление самой моделью после обучения. Уже на ранней схеме у Michelangelo есть отдельный Model Repo. Это важный признак зрелости: модель перестаёт быть просто файлом, который кто-то вручную передаёт дальше, и получает стандартную точку регистрации и использования.
Но для промышленной эксплуатации одного хранилища моделей недостаточно. Нужно управлять версиями и ревизиями, параметрами выполнения, ресурсами, обновлениями и самим процессом выкладки. Поэтому в более зрелой архитектуре Uber описывает этот слой уже через сущности InferenceServer и Deployment.
Здесь, как и в случае с Pipeline и PipelineRun, снова начинает проявляться логика control plane — управляющего слоя платформы. Если совсем просто, платформа начинает работать не только с самой моделью как файлом или артефактом, но и с описанием того, как именно она должна быть запущена в production, с какими настройками и в каком состоянии должна находиться.
InferenceServer отвечает за общий способ запуска модели как сервиса: как она поднимается и как с ней работает внешний мир. Deployment — за конкретную выкладку этой модели: какую версию запустить, с какими ресурсами и как дальше ею управлять.
Без такого слоя команда просто отдает модель, а дальше все зависит от ручных шагов и локальных договоренностей. С InferenceServer и Deployment платформа уже сама хранит важный контекст. Например, у одной модели может быть несколько версий и если команда меняет нужную версию или параметры выкладки, платформа не просто получает новую команду, а сама переводит сервис в нужное состояние и проверяет, что все действительно обновилось как надо.
Здесь происходит ещё один важный архитектурный переход: деплой модели перестает быть ручной операционной процедурой и становится описываемым и отслеживаемым процессом внутри платформы.
Control plane: переход к более зрелой платформенной архитектуре
Теперь можно посмотреть на Pipeline, PipelineRun, Model, InferenceServer и Deployment не по отдельности, а как на часть более общей архитектурной логики. Речь идёт о control plane — управляющем слое платформы, который связывает отдельные компоненты в единую систему.
Важно, что такой слой появился в Michelangelo не сразу. В ранних публичных описаниях Uber платформа показана скорее как набор ключевых функциональных блоков для данных, обучения, хранения моделей и предсказаний. В более поздней архитектуре поверх этих компонентов уже появляется этот единый слой управления.
Если совсем просто, control plane отвечает не за запуск и исполнение сервисов, а за управление: хранит описание объектов, отслеживает их состояние и понимает, что должно происходить дальше. Платформа работает уже не просто с файлами, джобами и сервисами, а с сущностями, которые можно единообразно описывать, запускать, обновлять и контролировать.
Это удобно представить на простом рабочем сценарии:
Команда создает Project для задачи прогнозирования спроса.
Внутри него описывает Pipeline — процесс подготовки данных, обучения и проверки модели.
Каждый конкретный запуск фиксируется как PipelineRun со своими параметрами и результатами.
Успешный результат регистрируется как Model.
Затем для неё задается InferenceServer, то есть способ, которым модель будет работать как сервис.
После этого создается Deployment, где уже указано, какую версию модели нужно вывести в рабочий контур, с какими ресурсами и в каком состоянии должна находиться выкладка.
В этом и состоит главное изменение: команда работает уже не через скрипты и ручные договоренности, а через понятные объекты платформы. Это делает путь от эксперимента до продакшена более прозрачным: меньше ручной координации, понятнее версии, статусы и результаты. А для платформы в целом это означает больше порядка и управляемости.
Пока масштаб небольшой, многое еще можно координировать вручную. Но когда моделей и выкладок становится много, ручной подход быстро начинает давать сбои. Именно здесь control plane становится особенно важен.

Мониторинг как часть serving-контура
Как платформа понимает, что уже развёрнутая модель работает нормально? Michelangelo показывает зрелый подход: наблюдаемость встроена прямо в serving-контур, а не вынесена в сторону.
Уже на ранней схеме видно, что мониторинг входит в слой Deploy, Predict & Monitor. Это важный архитектурный признак: эксплуатация модели изначально рассматривалась не как простой запуск сервиса с предсказаниями, а как связка работы модели и постоянного контроля за её состоянием.
Со временем Uber развил эту идею ещё дальше. Речь идёт уже не только о технических метриках сервиса, ошибках и логах, но и об отдельном слое оценки качества ML-системы: как ведут себя признаки, не меняются ли их распределения, не деградируют ли предсказания и сохраняется ли качество модели в реальном продукте.
Именно в этом и состоит отличие обычного мониторинга сервиса от полноценной ML-наблюдаемости. Платформа должна видеть не только состояние инфраструктуры, но и состояние данных, признаков, предсказаний и итогового качества модели. То есть отвечать не только на вопрос «жив ли сервис», но и на вопрос «по-прежнему ли модель работает так, как от нее ожидают». Поэтому такая логика в идеале должна быть встроена в саму платформу, а не оставаться набором локальных решений отдельных команд.
Как Michelangelo эволюционировал вместе с задачами
По мере развития платформы менялось не только то, как модели запускаются и контролируются, но и то, какие задачи вообще нужно было поддерживать. Michelangelo довольно быстро перестал быть платформой только для классического машинного обучения.
На ранних этапах он хорошо закрывал типовые сценарии с табличными данными и пакетной обработкой. Но с ростом deep learning появились новые требования: обучение на ускорителях, распределенные вычисления, воспроизводимые окружения и более сложное управление ресурсами.
Здесь важную роль сыграл Horovod, разработанный в Uber. Он позволил эффективно обучать модели сразу на нескольких ускорителях и упростил распределенное обучение. В результате слой обучения перестал быть просто «запуском модели» и начал превращаться в полноценный вычислительный контур, который умеет работать с разными типами задач.
Дальше платформа продолжила двигаться в сторону универсальности. Появились свои механизмы управления задачами (например, Michelangelo Job Controller), а также интеграция с Ray — уже как с более общим слоем для выполнения распределенных вычислений. Это важный сдвиг: платформа учится поддерживать не один способ обучения, а разные типы нагрузок внутри единой архитектуры.
Параллельно менялась и эксплуатация моделей. Более зрелый Michelangelo — это уже не просто обучение и выкладка, а управляемый процесс с проверками, ограничениями и контролем. Платформа помогает понять, какую версию модели можно запускать, какие проверки она должна пройти и что именно сейчас работает в продакшене.
Именно в этом и проявляется зрелость: не в наличии отдельных инструментов, а в том, что вокруг жизненного цикла модели появляется понятный и контролируемый процесс.
Главный вывод здесь в том, что платформа ценна не сама по себе и не набором модных технологий. Ее сила в том, что по мере роста сложности она помогает не распасться на набор отдельных решений, а сохранить общий, управляемый контур работы с моделями.

На схеме из статьи From Predictive to Generative – How Michelangelo Accelerates Uber’s AI Journey хорошо видно, как менялся фокус платформы: от классического predictive ML и раннего Michelangelo 1.0 — к deep learning в Michelangelo 2.0, а затем и к более позднему повороту в сторону Generative AI.
Почему Michelangelo важен как индустриальный пример
Для российского контекста Michelangelo важен не потому, что его нужно буквально повторить — большинству компаний не нужен и не окупится масштаб Uber. Его главная ценность в другом: он показывает саму логику платформизации и то, во что платформенный слой может со временем вырасти.
Главное — не размер платформы, а её применимость и логика взросления.
Для российских компаний, особенно крупных и выросших не из диджитал-среды (например промышленных, финансовых, телеком- и логистических) это особенно важно, потому что ML здесь часто развивается в гетерогенном корпоративном ландшафте, где внутри одной компании сосуществуют разные контуры.
Где-то команды работают в более свободном исследовательском режиме, где-то — в жестко регламентированном; у одних есть свои инженерные ресурсы, у других все завязано на отдельные инфраструктурные команды и внешние процессы. В итоге проблема обычно не в нехватке инструментов, а в отсутствии общего способа работы.
В таких условиях платформа часто начинается не со сложной системы управления, а с более простого общего слоя: реестра проектов и моделей, базовых стандартов жизненного цикла, типовых пайплайнов, шаблонов деплоя, общих точек мониторинга и понятных правил вывода модели в рабочую среду. Уже этого часто хватает, чтобы сделать разработки более видимыми, сократить дублирование, лучше использовать инфраструктуру и снизить стоимость поддержки.
И это тоже нормальная зрелая стадия. Во многих компаниях именно такой уровень платформизации оказывается самым разумным и с инженерной, и с экономической точки зрения. А если масштаб и сложность действительно растут, платформа может дальше развиваться в сторону более зрелой модели с control plane.

Самые практические уроки: признаки, деплой и наблюдаемость
Признаки как общий слой. Проблемы очень часто возникают не из-за самой модели, а из-за того, что одни и те же признаки по-разному считаются на разных этапах. Проблема эта в целом универсальная, но в российских корпоративных условиях она нередко становится еще заметнее из-за уже упомянутого гетерогенного ландшафта данных. Когда данные приходят из разных источников, проходят через разные контуры и собираются по разным правилам, один и тот же признак очень быстро начинает жить в нескольких версиях.
Именно поэтому слой признаков со временем должен становиться не локальной логикой отдельных команд, а общим платформенным слоем. Это не значит, что компании сразу нужен большой и сложный feature store. Но к базовому принципу лучше прийти как можно раньше: у каждого признака должно быть понятное определение, должно быть ясно, кто за него отвечает, от чего он зависит, как и куда он публикуется и по каким правилам его можно переиспользовать.
Деплой как управляемый процесс. Следующий важный урок Michelangelo связан с тем, как модель попадает в продакшен. Идея здесь простая: деплой не должен быть набором ручных шагов и разовых договоренностей между командами. Он должен быть понятной и управляемой частью жизненного цикла модели.
На практике это значит, что у компании должен быть прозрачный процесс выкладки: понятно, какая версия модели куда поставлена, в каком окружении она работает, какие проверки прошла, кто за нее отвечает и как при необходимости быстро сделать обновление или откат.
Для российских компаний это особенно важно, прежде всего в крупных организациях, выросших не из диджитал-среды. Здесь деплой модели нередко проходит не через одну команду и не через одну систему, а через несколько контуров ответственности сразу: ML-команду, инфраструктуру, информационную безопасность.
В таких условиях важна платформа как общий слой стандартизации. Она помогает связать ML-разработку с остальной корпоративной средой: с требованиями безопасности, сетевыми ограничениями, изоляцией контуров, аудитом, хранением данных и правилами эксплуатации. Через платформу в компании появляются единые правила того, как модель оформляется, проходит проверки, выкладывается и сопровождается.

Наблюдаемость как часть архитектуры. Для ML недостаточно следить только за CPU/GPU, памятью, ошибками и задержкой. Нужно видеть состояние признаков, изменения входных данных, поведение предсказаний и сигналы деградации качества после деплоя.
Именно здесь начинается настоящая зрелость ML-эксплуатации. Компания должна различать хотя бы несколько уровней наблюдаемости: уровень инфраструктуры и сервиса, уровень данных и признаков, уровень самих предсказаний и уровень бизнес-эффекта, который модель должна поддерживать. Пока все это не связано между собой, мониторинг остается фрагментарным.
Для крупных компаний это особенно важно, потому что проблема обычно не в том, что мониторинга нет, а в том, что он разрозненный. Метрики инфраструктуры, логи сервисов, данные, сигналы качества, аудит и безопасность часто живут в разных системах и у разных команд. В итоге есть много наблюдений, но нет целостной картины.
Платформа же дает общий слой, через который все это можно связать и привести к единым правилам. Смысл урока Michelangelo как раз в этом: мониторинг должен быть не отдельной надстройкой, а частью самой платформы и жизненного цикла модели.
Тогда вопрос уже не только в том, какие метрики собирать, а в том, как объединить все эти сигналы в одну систему, где можно понять, что происходит с моделью: как работает сервис, что происходит с данными и признаками и как это влияет на результат.
Выводы
Этим разбором тема Michelangelo не исчерпывается. Платформа слишком большая, слишком многослойная и слишком долго развивалась, чтобы уместить её в одну статью без упрощений. Но как инженерный ориентир она остаётся полезной.
Есть, правда, нюанс: Uber почти не раскрывает Michelangelo через прямые финансовые KPI. Так что приложить к российским реалиям аккуратный финансовый подорожник в духе «вот здесь платформа отбилась за N месяцев» у нас, к сожалению, не получится.
Но хорошая новость в том, что большинству компаний не нужна платформа масштаба Uber.
Если компании нужно прежде всего упорядочить эксперименты, обучение и воспроизводимые ML-процессы без строительства большой внутренней платформы, более естественным выбором могут быть workflow-фреймворки.
Это особенно характерно для исследовательских команд, продуктовых ML-команд среднего масштаба и ситуаций, где сначала нужно организовать сам воркфлоу, а уже потом решать, нужен ли поверх него полноценный платформенный слой.
В следующей статье мы как раз разберем ещё два важных пути развития MLOps: managed-сервисы облачных провайдеров и workflow-фреймворки. И посмотрим, в каких случаях они оказываются уместнее, чем собственная внутренняя платформа.