Теневой запуск модели: как собрать отчёт до переключения трафика

При теневом запуске новая модель получает копии запросов, а пользователю отвечает текущая версия. Соберём парный отчёт расхождений и разберём, что он позволяет проверить до переключения.

Живой поток без нового решения для пользователя

Модель прошла отложенный тест, но на продакшне остаются неизвестные детали: редкие категории, реальные размеры запросов, стоимость получения признаков и нагрузка. Теневой, или shadow, запуск отправляет часть живого потока кандидату параллельно с текущей версией. Его ответы сохраняются для анализа, а решение продукта продолжает принимать основная модель.

До запуска договоритесь о копировании входа. Если новая модель запрашивает признаки позже и получает уже обновлённое состояние, разность прогнозов смешает различие моделей и данных. По возможности сохраняйте единый снимок входа либо точные версии признаков. Для каждой пары нужны общий request id, две версии, время, статус и прогноз.

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

Сначала проверяем полноту пар

Ниже два журнала: основная модель ответила на четыре запроса, кандидат — на три. Соединяем по id и считаем долю изменившихся решений только среди пар. Отсутствующие ответы выводим отдельно. Если их молча удалить из отчёта, медленный или падающий кандидат может выглядеть благополучно на лёгком остатке потока.

Используем фиксированный порог 0,5. Средняя абсолютная разность score помогает оценить масштаб изменения, а переключение решения — его операционную частоту. Истинных исходов пока нет, поэтому эти числа показывают различие поведения, а не превосходство качества.

production = {"a": .10, "b": .49, "c": .80, "d": .70}
shadow = {"a": .12, "b": .52, "c": .79}
paired = sorted(production.keys() & shadow.keys())
missing = sorted(production.keys() - shadow.keys())
changed = [k for k in paired if (production[k] >= .5) != (shadow[k] >= .5)]
mean_delta = sum(abs(production[k]-shadow[k]) for k in paired)/len(paired)
print("paired:", len(paired), "missing:", missing)
print("changed:", changed, "mean absolute score delta:", round(mean_delta, 3))
assert missing == ["d"] and changed == ["b"]
assert len(paired) == 3

В отчёте три пары, один пропущенный ответ и одно изменение решения — запрос b. Его балл перешёл с 0,49 на 0,52. Начните ручной просмотр с таких переходов, крупнейших разностей и ошибок кандидата. Сохраняйте знаменатели по сегментам: доля расхождений на десяти редких запросах и на миллионе обычных имеет разную устойчивость.

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

Когда придут фактические исходы, присоедините их к обеим версиям по сохранённым id и повторите сравнение качества на общих объектах. Для запаздывающей метки заранее определите дату созревания. До этого момента можно проверить корректность входов, доступность и поведение, но выбрать лучшую модель только по сходству со старой нельзя: полезный кандидат как раз может давать другие ответы.

Завершите shadow-этап конкретным решением: устранить ошибку входа, собрать больше меток, перейти к ограниченному реальному трафику или отклонить кандидата. Критерии следующего шага задайте до запуска и сохраните в отчёте. Это превращает живую проверку в этап внедрения с понятным результатом.

Для следующего шага пригодится мониторинг до прихода правильных ответов.

В платном курсе «ML Engineer / Data Scientist: табличные модели в продакшн» вы соберёте REST API и научитесь контролировать качество и дрейф табличной модели. Сохранённые прогнозы и метрики нужны для сравнения кандидата с рабочей версией на одинаковых запросах. Откройте программу курса.

Продолжить на практике

  • ML Engineer / Data Scientist: табличные модели в продакшн ↗

    Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.