Налаштування A/B-тестування ML-моделей у продакшені

Модель поводиться в продакшені інакше, ніж на стенді, і розходження версій коштує дорого. Ми налаштовуємо контур A/B-тестування ML-моделей під ключ: тіньове та канареечне розгортання, зрозумілі метрики, регламент відкату. Скорочуємо частку ручних перевірок і час на випуск нових версій у рази.
Часті запитання

Чому A/B-тестування ML-моделей ламається в продакшені

Найдорожчий збій в A/B-тестуванні ML-моделей — не падіння сервісу, а впевнена відповідь не тією моделлю. У реєстрі лежить потрібна версія, але ознаки на вході збирає інший код, довідники оновлено окремо, і розбіжність версій моделі між контурами спливає через тижні після запуску.

Друга поломка — метрики. Тестування моделей у продакшені порівнює контроль та експеримент на різних зрізах: в одному контурі вікно агрегації ширше, в іншому викиди відфільтровано інакше.

Нестабільні метрики дають розкид більший за сам ефект моделі, і експеримент закривають за шумом, а не за результатом.

Третя — невідтворюваність. Через місяць уже ніхто не відновить, які ознаки, версії довідників і пороги стояли на момент заміру.

Навіть коли версії артефактів логуються в MLflow, у реєстрі зберігається модель, а не повний контекст її запуску — порівняти експерименти post factum нічим.

І четверта — відкат моделі. Якщо попередній артефакт не збережено разом із конфігурацією, повернення перетворюється на ручну збірку під тиском: якість падає просто зараз, а відновлення займає години. Ціна затримки вимірюється часткою зіпсованих рішень користувача за цей час.

Розбираємо, як це закривається: незмінні версії моделі та ознак, єдиний шар розрахунку метрик для обох контурів і відкат однією операцією.

Вимірювані ефекти: затримка, відкати, частка ручних перевірок

Керований контур змінює сам цикл: гіпотеза перевіряється на контрольній і тестовій групах до того, як версія поїде на всю аудиторію.

Перемикання частки трафіку стає операцією в налаштуваннях експерименту, а не окремим релізом, тому час від гіпотези до викатки моделі скорочується з днів до годин — узгодження замінює регламент.

Частка ручних звірок падає з тієї ж причини: метрики рахуються на одному розміченому зрізі для обох груп, значущість ефекту перевіряється автоматично, а аналітик дивиться лише спірні сегменти.

Те, що раніше потребувало щоденних вивантажень і зведення таблиць вручну, перетворюється на звіт, який оновлюється сам.

Окремо зникає клас відмов, який коштує найдорожче: «тиха» деградація на вузькому сегменті та викатка версії, навченої на застарілому зрізі.

Порогова метрика якості зупиняє розкатку і повертає попередню версію автоматично — час відновлення вимірюється хвилинами, а простій через помилку перестає бути подією на весь день.

MLflow у цій схемі відповідає за відтворюваність: кожна версія моделі прив'язана до параметрів, даних і метрики, тому результат експерименту можна переперевірити, а відкат — це перемикання на зафіксовану попередню версію, а не збірка заново. Ефект від експерименту стає вимірюваним до викатки, а не за фактом інциденту.

Варіанти розкатки: тіньовий запуск, канарковий, поетапний

Режим випуску обирають не за зручністю, а за тим, яку частку трафіку допустимо віддати новій моделі і наскільки дорого коштує помилка на живому запиті.

Тіньовий запуск відповідає на питання «чи збігається нова модель із поточною», канаркова розкатка — «чи не деградує продукт на реальних користувачах», поетапний випуск — «який із варіантів виграє за метрикою».

Обмеження режимів упираються в маршрутизацію запитів і в спосіб збору метрик. Поки метрика не прив'язана до версії моделі та до когорти, будь-яке порівняння підходів перетворюється на набір здогадів.

Режим Коли підходить Обмеження
Тіньовий запуск Перенесення логіки на нову модель, перевірка якості на реальному трафіку без впливу на відповідь Варіант не впливає на видачу, тому продуктові метрики щодо нього не збираються; потрібен дублювальний контур і запас за ресурсами
Канаркова розкатка Модель уже навчена, але потрібна страховка від деградації на живих запитах Потребує автоматичного відкату й розмітки метрик за когортами; на малій частці трафіку статистика набирається повільно
Поетапний випуск Потрібна перевірка ефекту за сегментами й порівняння версій із накопиченням даних Триває довше; без контролю однорідності груп порівняння втрачає сенс

На практиці режими комбінують: тіньовий запуск як допуск до живого трафіку, канаркова розкатка як страховка, поетапний випуск як спосіб зібрати статистику за сегментами.

Етапи впровадження: від аудиту до передачі в експлуатацію

Порядок робіт будуємо так, щоб помилку в схемі було видно до запуску на реальному трафіку, а не через тиждень розбору метрик. Кожен етап закінчується перевірюваним артефактом — тоді вмикання не перетворюється на «увімкнули й дивимося».

  1. Аудит схеми експерименту. Дивимося, яка метрика вважається цільовою, де і на якому обсязі трафіку вона збирається, чи достатньо спостережень, щоб розрізнити версії.

    Перевіряємо, чи не перетинаються групи з іншими запущеними експериментами і чи немає зміщення в тому, як події потрапляють у сховище.

  2. Розмітка трафіку. Визначаємо одиницю рандомізації — користувач, сесія або запит — і спосіб закріплення: та сама ознака дає стабільну групу при повторних візитах. Фіксуємо частку трафіку на експеримент і правила виключення, щоб у порівняння не потрапили службові запити.

  3. Налаштування контуру. Розгортаємо сервіс порівняння: він приймає запит, адресує його потрібній версії моделі, а передбачення та ознаку версії пише в лог. Тіньовий режим дає змогу прогнати нову версію на живому трафіку, не впливаючи на відповідь користувачу.

  4. Контрольні перевірки. Проганяємо A/A-тест на однорідність груп, звіряємо розподіл ознак між гілками, перевіряємо поведінку при відмові однієї з версій і при недоступності сервісу порівняння.

    Метрику на обох гілках рахуємо за одним і тим самим правилом — інакше різниця буде в розрахунку, а не в моделі.

  5. Передача в експлуатацію. Віддаємо команді регламент запуску й зупинки, опис відкату, панель із метриками та налаштування оповіщень. Документуємо розмітку й конфігурацію контуру, щоб наступний експеримент запускався без нас.

Артефакти передачі: схеми, політики доступу, регламенти

Після здачі контуру в команди замовника залишається комплект артефактів, за яким нові A/B-тести запускаються самостійно — без відновлення логіки з листування та пам'яті інженерів. Нижче перелік того, що передаємо і навіщо кожен документ потрібен у роботі.

  • Конфігурації контуру. Файли розгортання та параметри середовищ: тестове й продуктивне відрізняються лише значеннями, тому новий варіант моделі піднімається копіюванням конфігурації, а не збіркою заново.
  • Схеми потоків даних. Шлях від запиту до запису метрики: де фіксується варіант, як рахується цільова метрика, де розходяться вибірки. За схемою новий інженер розбирається в контурі за годину.
  • Політики доступу. Розмежування ролей: хто змінює частку трафіку на варіант, хто зупиняє тест, кому доступні сирі логи. Експеримент не можна зламати випадковою правкою.
  • Регламент експерименту. Обов'язкові кроки: гіпотеза, цільова метрика, мінімальний обсяг вибірки, критерій зупинки та порядок відкату на контрольну модель.
  • Шаблон звіту. Єдина форма фіксації результату: версії порівнюваних моделей, період, метрики за групами, висновок і рішення — продовжувати, доопрацьовувати або закривати.
  • Інструкції та навчання. Розбір контуру з командою замовника та короткі пам'ятки з типових операцій: запуск тесту, зупинка, відкат, читання звіту, додавання нової метрики.

Такий комплект знімає залежність від підрядника: зміни в контур вносяться за документованими правилами, а не за усними домовленостями. Обговоримо задачу — повернемося з планом робіт і складом артефактів під ваш контур.

Кейс: прибрали розбіжність версій між контуром і продакшеном

Замовник викочував кілька моделей на місяць, а контур навчання й продакшен жили окремим життям. Артефакти переносили скриптами, ознаки перезбирали руками, і розбіжність версій між середовищами спливала вже на живому трафіку.

Сліпа викатка без розбиття аудиторії не давала помітити деградацію раніше, ніж просідали метрики продукту.

До перебудови дві-три ручні звірки на тиждень забирали в інженера по півдня, відновлення після інциденту розтягувалося на годину з гаком, а відкат доводилося запускати руками майже в чверті викаток.

Що змінили

Обидва середовища звели до єдиного реєстру моделей на MLflow: версія, набір ознак і якість на контрольній вибірці прив'язані до одного артефакту, а переведення в продакшен відбувається лише через автоматичну перевірку маніфесту.

Викатку перевели на розбиття трафіку 5/95 з автооткатом за ключовою метрикою замість сліпої заміни всієї моделі. Рішення логуються разом із версією, тому розбір збою починається з готової картини, а не з ручної звірки логів.

Через квартал ручні звірки скоротилися до однієї планової, розбіжності версій між контуром і продакшеном не відтворювалися жодного разу, а відновлення займало хвилини: відкат спрацьовував сам за порогом.

Частка шляхів, покритих автоматичними перевірками перед викаткою, зросла з третини до дев'яти десятих.

Що робити, якщо модель уже в продакшені, а розмітки немає?

Відсутність розмітки під експеримент блокує не порівняння версій, а відсутність керованого перемикача між ними. Якщо модель уже в продакшені, спочатку відокремлюємо її від коду сервісу: версія моделі та її параметри мають підставлятися з конфігурації, а не бути вшитими у виклик.

Далі на вході сервісу з'являється тонкий шар маршрутизації, який за однією ознакою запиту вирішує, яка версія його обробить.

Поки розмітки немає, спираємося на непрямі сигнали: логи рішень, відгук користувачів, частка ручних правок після відповіді моделі, розподіл передбачень за класами та зсув цього розподілу в часі.

Цього достатньо, щоб упіймати деградацію та розбіжність версій, а повноцінний набір перевіркових прикладів досоздається пізніше — уже під зібраний потік реальних запитів.

Варіант Коли підходить Обмеження
Тіньовий режим Не можна ризикувати якістю відповіді користувачу Дві версії рахуються паралельно, потрібен запас потужності
Канарковий запуск Потрібно швидко впіймати явну відмову на малій частці трафіку Показує збої, але майже не розрізняє якість
A/B за часткою трафіку Метрика вимірювана й накопичується за дні, а не місяці Потребує стійкого розподілу запитів за групами

Перехід робимо поступовим: одиниці відсотків трафіку на нову версію, витримка на вибраній частці, потім крок угору.

На кожному кроці порівнюємо ті самі сигнали, що збирали до запуску, і тримаємо готовим відкат — повернення версії за конфігурацією, без перезбирання й зупинки сервісу.

Міграція без зупинки виходить саме з цього: маршрутизація живе окремо від моделі, тому підміна версії займає секунди і не перериває обробку запитів.

Поріг зупинки задаємо заздалегідь і у вимірюваних величинах: просідання цільової метрики, зростання частки помилок, розбіжність розподілів вище допустимого. Якщо поріг пройдено — трафік повертається на попередню версію автоматично, а не за дзвінком чергового.

Часті технічні сумніви замовників та інженерів

Сумніви на цьому етапі зазвичай технічні: чи вистачає даних, чи не спотворює картину сезонність, що робити з паралельними правками правил і моделі. Нижче — короткі відповіді про те, як ми закриваємо ці місця в розмітці експерименту.

Чи вистачить трафіку для достовірних метрик?

Рахуємо не загальний трафік, а кількість цільових подій у кожній групі. Мінімальний розмір вибірки визначаємо до старту — від очікуваного ефекту та розкиду метрики. Якщо подій менше, звужуємо метрику або подовжуємо вікно спостереження, а не підганяємо тест під красиву цифру.

Чи не спотворить картину сезонність?

Розбиття йде за стабільним ідентифікатором користувача, тому обидві групи потрапляють в одні й ті самі дні, акції та пікові години.

Порівняння йде паралельно в одному вікні, а результат переперевіряємо на сусідніх періодах — ефект, який тримається лише в одному тижні, у висновки не йде.

Що робити, якщо одночасно змінюються правила й модель?

Один експеримент — одна зміна. Якщо міняти обидва відразу, ефект не розділити: незрозуміло, що дало приріст, а що його з'їло. Розносимо правки на послідовні етапи або плануємо схему з перевіркою спільного впливу, щоб оцінити внесок кожного фактора.

Кому доступні результати і що з безпекою даних?

Звіти дивимося за ролями: продуктовій команді — зрізи за сегментами й метриками, інженерам — події у сховищі для розбору. Персональні дані у звітність не потрапляють, ідентифікатори псевдонімізовано, вивантаження обмежене політикою доступу й логується.

Обговоримо задачу: як ми почнемо роботу над контуром

Щоб контур A/B-тестування моделей не перетворився на череду переробок, починаємо з розбору того, що вже працює.

Від вас — доступ до репозиторію інфраструктури, до поточної схеми виведення моделей у продакшен і до вивантаження за цільовою метрикою за минулі періоди: без цього не порахувати розмір груп і тривалість вікна спостереження.

Порядок перших кроків:

  • описуємо поточний шлях моделі: де зберігаються версії, хто перемикає трафік між ними, що вже логується;
  • фіксуємо цільову метрику та метрики-обмежувачі, які не мають просісти за жодного результату тесту;
  • вибираємо одиницю рандомізації — клієнт, сесія або запит — і спосіб закріпити її за групою, щоб користувач не перескакував між варіантами;
  • узгоджуємо схему розрахунку: частки трафіку, мінімальний значущий ефект, критерій дострокової зупинки;
  • проєктуємо відкат: однією командою весь трафік повертається на контрольну модель за лічені хвилини;
  • додаємо спостереження за дрейфом вхідних даних і за розбіжністю розподілів між групами;
  • розмічаємо обсяг робіт: де потрібні зміни в коді виведення, а де достатньо конфігурації.

За підсумками розбору повернемося з оцінкою та планом: склад етапів, строки за кожним, зона відповідальності нашої команди та вашої. Наступний крок — опишіть задачу, і ми призначимо розбір.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142