Canary deployment ML: почему выкат новой модели ломает прод
Новая версия модели уезжает в прод одним тегом на весь трафик — так выглядит самый частый сбой выката. Оффлайн-проверки пройдены, отложенная выборка даёт нужное качество, релиз уходит на 100% запросов. Через полчаса мониторинг показывает деградацию прогнозов: растёт доля отказов в скоринге, редкие сегменты просели сильнее остальных, а в логах уже ответы новой модели по всем клиентам.
Откатить такую выкатку нечем. Если релиз публикуется поверх предыдущего тега в реестре образов, прошлый артефакт перезаписан, и «вернуть как было» превращается в пересборку из исходников и повторную валидацию. Пока это идёт, прод-контур отвечает моделью, которой никто не доверяет, и каждый час работы стоит доверия пользователей.
Дело не в том, что модель плохая. Прод-контур отличается от тестового: другой поток запросов, дрейф признаков, неравномерные сегменты, задержки внешних источников данных. Метрика на статичной выборке ничего не говорит о поведении на живом трафике — значит, риск прод-контура ограничивают до выката, а не разбирают после.
Canary deployment как раз про это: новая версия получает малую долю трафика, обычно 1–5%, предсказания сравниваются с эталонной моделью по сегментам и распределениям, а расхождение выше порога автоматически возвращает предыдущую версию. Разделение потока и правила отката описываются декларативно — в оркестраторах уровня Kubernetes это уровень манифестов, а не ручных действий дежурного. Ниже разбираем, как такой контур собирается и что нужно зафиксировать до первого выката.
Управляемый выкат модели: измеримый эффект для продукта
На канареечном выкате меняется не только процедура релиза — меняется то, что команда видит и на что успевает среагировать. Ниже — эффекты, которые проявляются уже в первых циклах, и метрики, по которым их проверяют.
Доля ошибочных ответов и наблюдаемость модели
Пока новая версия принимает 1–5% трафика, её показатели считаются отдельно от стабильной: доля отказов, распределение предсказаний, задержка, смещение входных данных. Сравнение идёт не «на глаз», а по эталонному срезу, зафиксированному до релиза, — расхождение видно на первых сотнях запросов, а не через неделю по отзывам пользователей. Наблюдаемость закрывает то, чего нет в обычном мониторинге сервиса: качество ответа, а не только факт ответа. Сбор и разбивка метрик по версиям модели строятся на Prometheus с алертами на порог расхождения.
Время отката и ушедший класс отказов
Возврат веса на стабильную версию — это изменение конфигурации маршрутизации, а не пересборка и повторный деплой: откат занимает минуты и не требует участия всей команды. Уходит целый класс отказов — массовое ухудшение качества после релиза, когда плохие ответы получают сразу все пользователи. При этом трафик под наблюдением не нулевой: канареечная доля даёт достаточную статистику, чтобы решение об откате или расширении принималось по данным, а не по интуиции.
Стоимость сбоя падает не за счёт «более аккуратных релизов», а за счёт ограниченного радиуса поражения: ошибка остаётся на нескольких процентах запросов и гасится до того, как дойдёт до всей аудитории.
Схемы маршрутизации трафика для ML: сравнение режимов
Выбор схемы определяется тем, что именно проверяют: устойчивость сервиса или качество ответов модели. Ниже — четыре режима, между которыми реально выбирают команды, и их ограничения.
| Вариант | Когда подходит | Чем ограничен |
|---|---|---|
| Канареечный выкат по доле трафика | Нужна проверка на живых пользователях при контролируемом риске: новая версия получает малую долю запросов, дальше доля наращивается по метрикам | Требует автоматического отката по метрикам, иначе доля растёт «на глаз»; на редких классах ответов статистика набирается медленно |
| Теневой режим | Копия боевых запросов идёт на новую модель, ответы клиенту не возвращаются — качество сравнивают на реальном распределении | Двойная нагрузка на сервис модели; нельзя оценить, как новый ответ влияет на поведение пользователя |
| Сине-зелёное переключение | Нужен мгновенный перевод всего трафика после прогона проверок, например при несовместимом изменении формата ответа | Нет промежуточных долей: откат — это полный возврат, нужен прогрев новой среды |
| Ручное переключение | Редкие релизы и разбор инцидентов, когда решение осознанно принимает дежурный | Зависит от человека: нет градации доли, время реакции равно времени до того, кто заметил проблему |
Что решают правила маршрутизации
Доля трафика — не единственный рычаг: распределение задаётся правилами по идентификатору клиента или заголовку запроса, чтобы одна сессия не прыгала между версиями. Для моделей это принципиально: расхождение ответов двух версий пользователь замечает сразу, а метрики качества размываются, если сравнивать разные когорты. Поэтому долю обычно фиксируют на когорте, а сравнение ведут по сопоставимым срезам трафика.
Как мы внедряем управляемый выкат: этапы инженерных работ
Выкат ML-модели отличается от релиза обычного сервиса: новая версия может отвечать быстро и без ошибок, но давать менее качественные предсказания. Поэтому долю трафика привязывают не только к доступности, но и к сигналам качества, а переключение ведут ступенями.
- Аудит выката. Разбираем, как версии модели попадают в продакшен: где лежат артефакты, как выбирается активная версия, можно ли увести часть трафика на новую. Отмечаем места, где нет обратного пути.
- Схема маршрутизации. Определяем, где делится поток — балансировщик, шлюз или сервис инференса, — и как задаётся доля трафика: меняется на ходу или требует перезапуска.
- Сигналы качества модели. Согласуем метрики сравнения версий: доля отказов инференса, время ответа, распределение предсказаний, бизнес-метрика на размеченном срезе. Для каждой — порог и минимальный объём наблюдений.
- Правила переключения. Фиксируем в конфигурации стартовую долю, шаг и паузу между ступенями, условия автоматической остановки выката.
- Проверка на трафике. Ведём канареечную версию на малой доле, сверяем сигналы с базовой и наращиваем ступенями. Для быстрого набора статистики добавляем теневой прогон на исторических запросах.
- Регламент отката. Прописываем, какой сигнал и чей триггер возвращает предыдущую версию, за какое время проходит откат и как проверяется целостность после него.
- Передача. Отдаём схему маршрутизации, конфигурацию правил, панель метрик и регламент отката, проводим разбор с командой.
Комплект поставки: конфигурации, схемы и регламенты отката
Настройка канареечного выката (canary deployment) для ML-моделей — это не разовая правка в конфиге, а набор артефактов, которые остаются у вашей команды. Через месяц сопровождения инженеры на стороне заказчика сами меняют доли трафика, читают метрики и откатывают версию без нашей помощи.
- Конфигурации выката — файлы с описанием версий, шагов наращивания доли трафика и порогов, при которых выкат останавливается автоматически.
- Схема потоков данных — от входного запроса до логирования предсказаний: где трафик расходится на две версии, как сравниваются ответы, где хранятся признаки.
- Политики доступа — разграничение ролей: кто меняет веса, кто видит метрики, кто имеет право на откат. Отдельные области видимости для боевого и тестового контуров.
- Наблюдаемость — дашборды по качеству модели и служебным метрикам, алерты на расхождение между стабильной и канареечной версией.
- Регламент отката — критерии срабатывания, порядок действий, ответственный за решение и целевое время возврата к стабильной версии.
- Документация — инструкции по развёртыванию, чек-лист перед релизом, описание окружений и типовых сбоев.
- Передача знаний — разбор архитектуры с вашей командой и запись сессии, чтобы поддержка не зависела от нас.
Кейс: перевод рекомендательной модели на канареечный выкат
Как было до внедрения
Рекомендательная модель обновлялась раз в две-три недели, и каждый выкат шёл сразу на весь трафик — промежуточной проверки на живой аудитории не было. Качество в проде непрерывно не измерялось: ориентировались на офлайн-замеры перед релизом, а про деградацию узнавали по падению заказов, чаще всего ночью. Дежурный откатывал вручную — полтора-два часа на диагностику и возврат версии, три-четыре таких случая в месяц.
Что изменили и что получилось
Трафик разделили: 5% на новую версию, затем 25%, затем весь поток — продвижение только при выполнении условий. Онлайн-метрики качества (доля кликов по рекомендациям и попадание релевантных товаров в первую выдачу) сверяются с контрольной группой каждые несколько минут. Порог качества задан заранее: уход метрики ниже контрольной на два процентных пункта или рост доли отказов запускает автоматический откат. Веса переключает Kubernetes — возврат на предыдущую версию идёт без участия человека.
Метрики до и после: ночные аварии — было три-четыре в месяц, стало ноль за квартал. Цикл выпуска сократился с двух-трёх недель до одной, потому что проверка на 5% потока занимает часы и не требует ручных согласований. Откат — с двух часов работы дежурного до нескольких минут по сигналу. Доля выкатов, доехавших до полного трафика без откатов, выросла примерно до девяти из десяти: модель доходит до пользователей быстрее, а деградация отсекается на малой доле аудитории.
Чем канареечный выкат отличается от теневого режима?
Теневой режим запускает новую модель на копии боевого трафика: она считает предсказания параллельно с текущей, но её ответы не уходят пользователю. Влияния на пользователей нет — запросы обслуживает прежняя версия, а расхождения считаются на тех же самых входах. Сравнение выходит честным по данным, но односторонним.
Главное ограничение теневого режима — нет обратной связи модели. Мы видим ошибки, задержки и дрейф входных данных, но не видим, как меняется поведение людей при новых ответах. Доля принятых подсказок, повторные запросы, глубина сессии остаются за кадром — теневик ловит техническую деградацию, но не отвечает, стало ли продукту лучше.
Канареечный выкат отдаёт новой модели реальную долю трафика — обычно единицы процентов — и повышает её по мере подтверждения метрик. Влияние на пользователей здесь есть, зато появляется настоящая обратная связь: продуктовые показатели считаются на тех же запросах, что и раньше, и их можно сравнивать с прежней версией напрямую.
Выбор схемы определяется ценой ошибки и обратимостью результата. Если ответ модели проверяет человек или он не виден клиенту, начинают с малой доли канареечного выката. Если ошибка заметна и плохо откатывается, сначала прогоняют теневой режим на реальных данных, а уже потом открывают трафик. Условия отката задаются заранее и срабатывают автоматически — тогда сравнение режимов не превращается в ручное дежурство у графиков.
Технические сомнения: откат, качество данных, нагрузка
Перед включением канареечного деплоя на боевом ML-сервисе всплывают одни и те же сомнения: кто и как откатывает, как отделить деградацию модели от сезонности данных и не придётся ли перерабатывать сервис.
Ручной откат — это долго и рискованно?
Ручной откат безопасен, если это переключение доли трафика на предыдущий артефакт модели, а не пересборка сервиса. Обе версии живут одновременно, веса правятся одним конфигом, возврат занимает десятки секунд. Право нажать закреплено за ролью, а автотриггер по метрикам качества страхует.
Как отличить деградацию модели от сезонности данных?
Метрику считаем на одинаковом срезе: обе версии получают запросы в одной пропорции по каналам, регионам и часам. Параллельно следим за дрейфом входных данных — сдвигом распределения признаков. Если входы поехали и качество упало следом, это расхождение обучающей выборки с боевым потоком, а не сезонность.
Нужна ли переработка сервиса под разделение трафика?
Обычно нет. Если сервис не хранит состояние между вызовами, а модель поставляется отдельным артефактом, разделение делает шлюз — по доле или служебному заголовку. Переработка нужна там, где версия вшита в код или вывод идёт внутри долгого процесса с накопленным состоянием.
Как канареечная версия влияет на нагрузку?
Она забирает долю запросов, поэтому её пул считаем отдельно, с запасом под пик. Если ресурсов впритык, включаем теневой режим: версия получает копию запросов, не влияя на ответ пользователю, а качество считаем офлайн — нагрузка на сервис остаётся предсказуемой.
Обсудим вашу задачу выката: вернёмся с оценкой и планом
Оценка внедрения выходит точной, когда есть исходные данные. Опишите задачу: что за сервис, как сейчас выкатывается новая версия модели и что в вашем понимании считается неудачным релизом. Сверим это с вашим контуром и вернёмся с планом работ, а не с общими формулировками.
- Схема сервиса: откуда идёт трафик, где стоит балансировщик, куда пишутся ответы модели и логи.
- Текущий порядок выката: вручную или автоматически, кто переключает версию и по какой команде.
- Требования к качеству: какие метрики считаются ухудшением и на каком объёме запросов это уже видно.
- Правила отката: за какое время версия должна быть возвращена и кто принимает решение о возврате.
- Ограничения контура: где живут данные, допустимо ли направлять часть трафика на новую модель.
- Состав команды и окна изменений, чтобы план работ не конфликтовал с текущими релизами.
- Доступы и роли для настройки наблюдаемости — кто смотрит метрики и кто на них реагирует.
Из этого собираем план работ с этапами, ролями и точками контроля, а следующие шаги фиксируем после короткого разбора вашего контура. Напишите нам и обсудите задачу — вернёмся с оценкой и планом.







