Model Serving
Model serving — це коли натреновану модель ставлять за інтерфейс, що відповідає на запити. Щойно модель натреновано, її подача — це задача затримки й вартості, а вже потім машинного навчання. Сам інференс зазвичай є найменшою частиною часу відповіді, залізо тут — це залізо для пропускної здатності, від якого просять роботу на затримку, а те, що більшість команд моніторить — точність, — саме те, чого наживо не видно. На цій сторінці — шлях запиту, три форми подачі й чому зазвичай виграє найдешевша, батчинг і правильний сигнал масштабування, як викотити нову версію, не ставлячи на неї все, і за чим стежити, коли правда приходить із запізненням на тижні.
- Повільна частина
- Рідко модель
- Масштабувати за
- Глибиною черги
- Точність наживо
- Не спостережна
Модель — не повільна частина
Спитайте команду, куди йде їхня затримка подачі, — і більшість скаже, що в модель, бо модель — це те, що вони збудували й що профілюють. Потім хтось інструментує весь шлях і знаходить відповідь в іншому місці: сервіс витратив на забір ознак, потрібних моделі, більше часу, ніж на саму модель. Це нормальний результат, а не дивовижний, — і він змінює те, що варто оптимізувати першим.
Практична дисципліна — міряти шлях, а не виклик. Обгорніть кожен крок відрізком трасування — прийом, забір ознак, препроцес, інференс, постпроцес, серіалізація — і дивіться на процентилі, а не на середнє, бо середнє ховає саме ті запити, на які скаржаться користувачі. І задайте бюджет у мілісекундах, перш ніж обирати архітектуру: бюджет вирішує, чи можете ви взагалі дозволити собі мережевий стрибок до сховища ознак, а це питання проєктування, а не тюнінгу.
Три форми подачі — і зазвичай виграє найдешевша
Перш ніж будувати сервіс, дайте відповідь на менше питання: чи мусить передбачення робитися, поки користувач чекає? Дуже багато — ні. Якщо множина обʼєктів, про які ви передбачаєте, відома наперед і змінюється повільно — клієнти, товари, рахунки, — можна рахувати передбачення за розкладом, писати їх у таблицю, а застосунок хай читає рядок. Це не компроміс, а архітектура подачі без p99, без автомасштабування й без холодного старту.
Пакетна (наперед)
Порахувати все вночі, записати в таблицю, на запит читати рядок. Найдешевше і в роботі, і в експлуатації. Не годиться лише тоді, коли вхід не відомий наперед.
Онлайн (на запит)
Сервіс, що бере вхід і повертає передбачення. Потрібен, коли вхід приходить разом із запитом: пошуковий запит, кошик, форма. Усе складне на цій сторінці — саме про цю форму.
Потокова
Передбачення чіпляються до подій у потоці: оцінка шахрайства пишеться на кожну транзакцію. Затримка важлива, але ніхто не дивиться на спінер, — і це значно добріше обмеження.
Гібрид поширений і вартий того, щоб знати його як патерн: рахуйте дорогі частини за розкладом і поєднуйте їх із входами часу запиту в дешевому фінальному кроці. Система рекомендацій, що вночі оцінює кожного користувача проти кожного товару, а потім переранжує кількасот найкращих зі свіжим контекстом сесії, робить саме це — і перетворює неможливий бюджет затримки на легкий. Тягніться до цього раніше, ніж до більшої машини.
Батчинг, прискорювачі й правильний сигнал масштабування
GPU — це залізо для пропускної здатності. Воно виходить на свою паспортну продуктивність, роблячи ту саму операцію одразу над багатьма рядками, а один запит на один рядок використовує його малу частку, займаючи весь пристрій. Тому середовища подачі роблять динамічний батчинг: потримати запити, що прибувають, кілька мілісекунд, згрупувати те, що зʼявилося, і виконати як один батч. Ви міняєте малу обмежену затримку на кратне зростання пропускної здатності, а максимальне очікування — це число, яке ви задаєте, а не сподівання.
| Сигнал | Про що він каже | Вердикт |
|---|---|---|
| Завантаження CPU | Наскільки зайнятий хост усім, окрім інференсу на прискорювачі. | Стандартний — і хибний для подачі на GPU: пристрій насичується, поки CPU на 20%. |
| Глибина черги / очікування | Скільки запитів чекає на місце, — а це й є означення «не встигаємо». | Сигнал, що справді відповідає болю користувача. Масштабуйтеся за ним. |
| Запитів на секунду | Темп надходження без знання про те, наскільки дорогий кожен запит. | Придатний, коли вартість запиту однорідна; оманливий, щойно розмір входу коливається. |
| Завантаження прискорювача | Наскільки зайнятий пристрій, — але він може бути на 100% зайнятий батчем із одного. | Добрий для діагностики марнування, поганий як самостійний тригер масштабування. |
Ще два числа вирішують рахунок. Час завантаження моделі задає, наскільки боляче обходиться подія масштабування: багатогігабайтна модель, що вантажиться на пристрій девʼяносто секунд, означає, що автомасштабування не встигне за сплеском, — тож ви або закладаєтеся на пік, або тримаєте теплу потужність. І памʼять, а не обчислення, зазвичай обмежує, скільки моделей влізе на один пристрій, — тому подача кількох малих моделей з одного середовища виконання, кожна зі своєю версією, часто виявляється найдешевшим із знайдених рішень.
Викотити версію, не ставлячи на неї все
Нова версія моделі — це не виправлення бага, а зміна поведінки одразу на всіх запитах, і її офлайн-оцінка є передбаченням про те, як вона поводитиметься, а не спостереженням. Тож питання розгортання — не «чи вона краща», а «як ми дізнаємося ціною, яку переживемо». На це відповідають чотири механізми, і вони поєднуються.
Тінь
Слати справжній трафік у нову версію й викидати її відповіді, порівнюючи офлайн. Нульовий ризик для користувача — ловить затримку, падіння й skew, поки це нікого не зачепило. Ціна: подвійний інференс.
Канарка
Скерувати малу частку трафіку в нову версію й дивитися на експлуатаційні метрики. Відповідає на «чи вона виживає у проді», а не «чи вона краща»: для цього потрібен експеримент.
A/B-експеримент
Рандомізований поділ, виміряний за бізнес-метрикою, із заявленою тривалістю й розміром вибірки. Єдиний механізм, що відповідає, чи модель справді краща для користувачів.
Закріплений відкат
Попередня версія лишається завантаженою й доступною, а жива версія — це значення конфігурації. Тоді відкат займає секунди й не потребує, щоб тренувальний пайплайн досі працював.
Порядок, що працює: тінь, потім канарка, потім експеримент — кожен наступний дорожче перервати. Дві деталі важать більше, ніж здається. Подавайте обидві версії з одного середовища виконання, здатного тримати кілька версій одночасно, — тоді перемикання є рішенням маршрутизації, а не розгортанням. І записуйте версію моделі на кожному передбаченні, яке ви логуєте: без цього розслідування через три тижні не розділить дві популяції, і проведений експеримент стане неаналізовним.
За точністю не постежиш — стежте за тим, що можна
Ось незручний факт, що формує моніторинг моделей. Точність потребує міток, а мітки приходять пізно: мітка відтоку — після завершення періоду підписки, мітка шахрайства — після повернення платежу, мітка рекомендації — після вікна повернення товару. Тижнями єдине чесне твердження про живу модель — що ви не знаєте, як добре вона працює. Тож дашборд навколо точності дає панель, яка або порожня, або застаріла, і команди вчаться її ігнорувати.
Спостерігати негайно можна все, окрім результату, — і цього корисніше, ніж звучить. Три шари в порядку, у якому вони ловлять проблеми:
- Експлуатаційний: процентилі затримки, частка помилок, глибина черги, насичення. Ламається першим — і тоді однозначно.
- Входи: розподіл кожної ознаки проти тренувального зрізу плюс частка порожніх значень і небачених категорій. Саме тут заявляє про себе зміна вище за течією.
- Виходи: розподіл передбачень і, для класифікаторів, оцінок. Модель, чия частка позитивів подвоїлася за ніч, каже вам щось іще до появи будь-якої мітки.
- Бізнес-проксі, що розвʼязуються швидко, — клікабельність, частка прийняття, частка ручних скасувань операторами — як найраніший сигнал, скорельований із результатом, якого ще не виміряти.
Антипатерни, які варто назвати
- Передбачення, залоговані без версії моделі, вектора ознак і мітки часу, — після чого будь-яке пізніше питання лишається без відповіді.
- Онлайн-сервіс, збудований для входів, відомих ще звечора, який платить за p99, що нікому не був потрібен.
- Препроцесинг, переписаний усередині сервісу замість спільного з тренувальним пайплайном, — skew за побудовою.
- План відкату, що означає перетренування, бо попередній артефакт перезаписано, а дані вже пішли далі.
- Алерт про дрейф без власника й без визначеної дії, який вимикають протягом місяця після першого сезонного хибного спрацювання.
Коли це застосовувати
Застосовуйте, коли
- Передбачення, чий вхід існує лише в момент запиту — запит, кошик, завантажене зображення, — де попередній розрахунок неможливий.
- Модель, чию поведінку треба міняти без розгортання — через вказівник на версію й відкат, що триває секунди.
- Кілька моделей або версій на спільному залізі, де одне середовище виконання для всіх дешевше за окремий сервіс на кожну.
- Скрізь, де передбачення живить рішення, яке доведеться пояснювати згодом, бо саме на подачі пишеться лог.
Уникайте, коли
- Обʼєкт передбачення, відомий наперед і повільно змінний: рахуйте за розкладом і читайте рядок.
- Окрема платформа подачі заради однієї малої моделі, яку виклик бібліотеки всередині наявного сервісу тягне за частку ціни.
- Подача в реальному часі, узята тому, що це сучасно, коли ніхто не записав бюджет затримки, який вона має витримати.
- Будувати її раніше за моніторинг: модель, якої не видно у проді, — це модель, яку не можна безпечно змінювати.
Було корисно?
Поділіться з тим, хто працює над тією ж задачею.