A/B-тестирование ML: где ломается продакшен
Самая частая картина: новую версию модели выкатывают в продакшен целиком, одним релизом, поверх старой. Сравнивать не с чем — прежняя версия уже не получает трафик, а офлайн-оценка на отложенной выборке показывает одно, тогда как живая система живёт по другим правилам. Спор о том, стало ли лучше, решается не измерением, а тем, кто громче настаивает.
Расхождение метрик почти всегда приходит из смещения выборки. Отложенная выборка собрана на прошлых данных, а живой трафик меняется: приходят новые сегменты, меняется доля пользователей с историей, иначе ведут себя редкие запросы. Контроль качества модели по одной средней цифре это скрывает — метрика выросла в целом, а на целевом сегменте просела.
Рабочая схема — долевое A/B-тестирование ML на живом трафике: часть запросов уходит на новую версию, часть остаётся на контрольной. Пользователь закрепляется за ветвью на всю сессию, иначе сравнение версий модели размывается переключениями. Теневой режим и канареечный выкат дают то же измерение без риска: теневая копия считает ответы, не влияя на выдачу, а канареечная доля растёт по мере подтверждения метрик.
Тогда выкат модели в продакшен опирается на измерение, а не на мнение: видно прирост на целевом сегменте и цену — задержку и долю отказов. Как это закрывается на практике — ниже.
Что даёт управляемое сравнение моделей на потоке
Цикл проверки гипотез ускоряется
Раньше новая версия модели ждала ближайшего релиза, а результат оценивали по косвенным признакам и жалобам. Сейчас трафик делится на группы прямо в рабочем контуре, и время до оценки результата измеряется днями, а не неделями. За тот же период команда успевает проверить больше гипотез и быстрее закрывает тупиковые ветви.
Сравнение групп пользователей вместо споров
Обе версии получают сопоставимые потоки запросов, а поведение аудитории сравнивается по заранее согласованным срезам. Это убирает аргумент «мне кажется, новая модель отвечает лучше»: решение опирается на разницу между группами, а не на впечатление от нескольких показательных примеров.
Единая метрика качества
Шкала фиксируется до старта — доля успешно закрытых сценариев, точность ответа на контрольном наборе, глубина взаимодействия. Одна метрика на все итерации позволяет сравнивать версии между собой и видеть, какой шаг дал прирост, а какой создал лишь видимость работы.
Доля проигрышных выкатов падает
Пока сравнение идёт на части аудитории, ошибка проявляется до того, как затронет всех. Слабая версия снимается с потока и не доходит до полного релиза — класс отказов, когда «улучшение» незаметно ухудшало качество, уходит из процесса.
Форматы раскатки: теневой режим, канареечный, полный A/B
Выбор режима раскатки — это в первую очередь выбор цены ошибки. Теневой прогон её не создаёт, канареечный выпуск ограничивает её долей трафика в тесте, а полный A/B-тест ставит на кон всю аудиторию. Разница между форматами — не в «продвинутости», а в том, какие ограничения вы готовы принять: доступность данных, срок наблюдения и требования к откату.
| Вариант раскатки | Когда подходит | Ограничения |
|---|---|---|
| Теневой режим | Нужны метрики новой модели на живом трафике без влияния на ответы пользователю; исторических данных мало | Обратной связи по целевой метрике нет — решения модели ни на кого не влияют, расхождение с офлайн-оценкой остаётся невидимым |
| Канареечный выпуск | Модель прошла офлайн-проверку, нужен контроль на узкой доле трафика с быстрым возвратом на прежнюю версию | Малый сегмент даёт широкие доверительные интервалы, редкие сценарии в него не попадают |
| Полный A/B-тест | Нужно доказать прирост целевой метрики на репрезентативной выборке | Долгий срок наблюдения, требуется согласованная схема разбиения и единая логика логирования признаков |
На практике форматы не конкурируют, а выстраиваются в цепочку: теневой прогон отсекает явные отказы, канареечный выпуск проверяет устойчивость под живой нагрузкой, полный A/B-тест отвечает на вопрос о приросте. Ключевое условие перехода на следующий шаг — единый набор метрик во всех режимах и работающий откат на предыдущую версию на каждом из них. Иначе результаты несопоставимы, и решение о раскатке придётся принимать на глаз.
Как это выглядит на живом потоке, мы разбирали в Разборе раскатки рекомендательной модели — там же видно, почему после теневого прогона контроль на доле трафика всё равно обязателен.
Этапы внедрения: от аудита данных до передачи контура
Внедрение A/B-тестирования моделей — это не установка библиотеки, а последовательность, где каждый шаг опирается на предыдущий. Пропущенный аудит данных оставляет схему эксперимента без опоры, и выводы потом нечем защитить. Порядок работы у нас такой.
- Аудит данных. Смотрим, какие события логируются, с какой задержкой доходят, где теряется доля исходов и есть ли исторический срез для офлайн-прогона. Без этого нельзя ни посчитать метрику, ни оценить срок теста.
- Схема эксперимента. Фиксируем основную метрику, метрики-ограничители, гипотезу, минимальный различимый эффект и критерии остановки — до старта, а не после первого взгляда на цифры.
- Разбиение на группы. Распределяем по идентификатору пользователя, а не по запросу: иначе один человек попадает в обе группы и сравнение размывается. До запуска проверяем баланс групп по срезу истории.
- Настройка контура. Настраиваем маршрутизацию доли трафика и логирование версии модели вместе с решением. Каждый показ должен связываться с исходом, иначе разбор расхождений упирается в догадки.
- Проверка на пилоте. Запускаем на малой доле трафика и смотрим технические ошибки, время ответа, дрейф входных данных. Расширяем только после того, как контур ведёт себя стабильно.
- Передача контура. Отдаём регламент запуска новых версий, дашборд, доступы и порядок остановки эксперимента. Команда заказчика ведёт следующий тест сама.
Конфигурации, схемы и регламенты эксперимента
Эксперимент управляем, когда всё, что определяет его поведение, лежит в файлах и регламентах, а не в голове инженера. Ниже — минимальный комплект, который остаётся у заказчика вместе с работающим контуром: по нему прогон можно повторить, остановить или откатить без участия нашей команды.
- Конфигурация эксперимента — доли трафика между контролем и вариантами, горизонт наблюдения, минимальный размер выборки, критерий досрочной остановки и правило признания победителя.
- Карта метрик — одна целевая с направлением изменения, защитные метрики, которые не должны просесть, и разбивка по сегментам, где эффект может отличаться.
- Схема потоков трафика — как запрос попадает в вариант, где фиксируется распределение и кто отвечает за то, что один и тот же пользователь остаётся в своей группе.
- Правила доступа к данным — кто и на каком основании видит сырые события, где лежат обезличенные срезы, как проверочная разметка отделена от обучающей выборки.
- Документация контура — состав сервисов, зависимости, точки стыковки с хранилищем и мониторингом, порядок штатного запуска и остановки.
- Регламент отката — триггеры (просадка защитной метрики, рост отказов, расхождение распределения), ответственный, время до возврата на контроль и порядок разбора.
- Журнал прогонов — гипотеза, версия модели, период, результат, решение о раскате и его автор.
Каждый пункт — рабочий артефакт: его читают при передаче смены и при разборе инцидента, а не только на приёмке. Комплект обновляется вместе с контуром — иначе через пару итераций документация расходится с реальностью, и откат превращается в ручную археологию.
Кейс: как мы убрали расхождения между версиями модели
Что было на входе
Заказчик — сервис с моделью ранжирования в продакшене. Команда выкатывала новую версию раз в две недели и каждый раз получала спорный результат: на одном сегменте модель выигрывала, на другом проигрывала, а решение принималось по среднему по всему трафику. Доля откатов на новых версиях держалась на уровне 6–8%, а на разбор одной гипотезы уходило около трёх недель — эффект успевал устареть раньше, чем тест закрывался.
Что изменили
Мы развели два разных вопроса: «модель действительно лучше?» и «трафик поделён честно?». Появилась стратификация потока по ключевым сегментам, фиксация случайности разбиения, теневой прогон новой версии на всём трафике до того, как её увидит часть пользователей, и защитные метрики — время ответа и доля пустых выдач — с автоматической остановкой теста при просадке. Критерий остановки задавался заранее, поэтому решение о раскатке перестало зависеть от того, кто громче настаивает.
Что стало
Доля откатов на новых версиях снизилась с 6–8% до 2%, а разброс эффекта между сегментами стал виден до раскатки, а не после. Время от гипотезы до решения сократилось с трёх недель до шести дней. Устойчивость проверяли повторными прогонами: знак эффекта совпадал в девяти запусках из десяти, тогда как раньше результат менялся от запуска к запуску. Подход не изобретён нами — стратификация групп и защитные метрики подробно разобраны в материалах Microsoft Research по построению платформ экспериментов, мы адаптировали их под масштаб и структуру данных заказчика.
Чем A/B-тестирование ML отличается от канареечного релиза
A/B-тестирование ML отвечает на вопрос «стало ли лучше», канареечный релиз — «не сломалось ли». Первый сравнивает версии модели по пользовательской метрике, второй страхует выкат от регресса. Канареечный этап с порогами по ошибкам пропустит модель, которая работает стабильно, но теряет конверсию.
Разница начинается с единицы наблюдения. Канареечный релиз оперирует экземплярами сервиса и долями трафика — ему хватает агрегатов за минуты. В A/B-тестировании ML единица — пользователь или сессия, закреплённая за группой: если один и тот же трафик уходит в обе ветки, возникает смещение выборки, и эффект модели не отделяется от эффекта аудитории.
Решение по результату теста тоже принимается по-разному. Канареечный релиз закрывается автоматикой: выход за пороги по отказам и задержкам даёт откат, иначе доля расширяется. A/B-тестирование ML требует заранее выбранной метрики, расчёта мощности и окна наблюдения — обычно недель, чтобы поймать недельный цикл поведения.
| Критерий | A/B-тестирование ML | Канареечный релиз |
|---|---|---|
| Цель | сравнить качество версий | исключить регресс |
| Единица наблюдения | пользователь, сессия | экземпляр сервиса, доля трафика |
| Решение | статистика по метрике | пороги по отказам |
| Данные | недели наблюдения, ровный поток | минуты, агрегаты |
Ограничения по данным расходятся: на слабом потоке A/B-тестирование ML не набирает мощности, а канареечный релиз стартует на малой доле и статистики не копит. На практике их совмещают — сначала канареечный этап, затем A/B на остальной аудитории; метрики обоих этапов держим в одном трекере экспериментов, например в MLflow.
Вопросы по данным, метрикам и инфраструктуре тестов
Сомнения вокруг тестов повторяются: можно ли верить разнице между группами, что делать с задержкой разметки и стоит ли разворачивать свой контур экспериментов. Ниже — короткие ответы на то, что чаще всего всплывает на этапе оценки.
Сколько держать тест и как понять, что разница не случайна?
Размер выборки и минимальный значимый эффект фиксируем до старта, вместе с основной и защитными метриками. Держим тест до набора выборки и закрытия окна дозревания метки, не заглядывая в промежуточные срезы — иначе значимая разница находится почти всегда.
Метки приходят с задержкой — тесту можно верить?
Да, если окно наблюдения согласовано с горизонтом дозревания метки. Обе группы считаем в одном окне и пересчитываем итог после его закрытия, а не по первым дням, где часть событий ещё не доехала.
Нужен ли отдельный контур экспериментов?
Обычно нет: если разделение трафика, логирование показов и расчёт метрик уже работают, к ним добавляется версия модели и признак группы. Свой контур разворачиваем, когда решения нужно принимать быстрее, чем позволяет текущая аналитика.
Как добиться сопоставимости групп?
Делим по устойчивому идентификатору пользователя, а не по сессии или отдельному запросу, и до старта сверяем группы по ключевым срезам. Иначе разница в составе трафика читается как эффект модели.
Обсудим задачу: соберём план эксперимента под ваш поток
Чтобы план эксперимента был реалистичным, а не общим, нужны входные данные с вашей стороны. Достаточно описать текущий поток запросов, продуктовые метрики и ограничения — остальное уточним в переписке, а спорные места закроем гипотезами и отдельно пометим в плане.
- Как решение принимается сейчас: одна модель на весь трафик, ручные правила или предыдущий эксперимент — и что именно в нём не сработало.
- Какая доля трафика может уйти под тест и где точки входа: сервис онлайн-запросов, очередь, пакетный пересчёт по расписанию.
- Метрика успеха в двух слоях: бизнес-показатель (конверсия, доля отмен, время обработки) и техническая точность модели с разбросом по сегментам.
- За какой срок нужен вывод — дни или недели — и можно ли растянуть тест, если для значимого результата не хватает событий.
- Что есть по данным: логи прошлых версий, размеченная выборка, доступ к хранилищу и поля, которые нельзя выгружать наружу.
- Требования к откату: за какое время нужно вернуть прежнюю модель и кто принимает решение об остановке эксперимента.
- Кто со стороны заказчика согласует метрики и доступы — один ответственный или несколько команд.
В ответ вернём оценку объёма работ, порядок работ по этапам, схему разбиения трафика, критерии остановки и отката. Опишите задачу — соберём план под ваш поток и назовём сроки.







