Як вивести ML в продакшн. Основні етапи, поради та корисні інструменти

💡 Усі статті, обговорення, новини про AI — в одному місці. Приєднуйтесь до AI спільноти!

Усім привіт. Мене звати Кирил Трусковський, я працюю в компанії Georgian та викладаю курс ML in Production у Projector. Georgian — це VC фонд із власним R&D департаментом. Він допомагає компаніям із нашого портфоліо примножити ROI в кілька разів завдяки додаванню value до їхніх продуктів з допомогою машинного навчання.

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

Стаття буде корисною, якщо ви:

  • Розробник і хочете змінити чи розширити напрямок роботи, або ж перейти в ML-домен.
  • Data Scientist, Junior або Middle ML-розробник і прагнете навчитися впроваджувати й розширювати ML-моделі у продакшні та стати Full-Stack Data Scientist.

ML model lifecycle

Для початку розглянемо цикл життя моделі машинного навчання: що це таке та навіщо він нам взагалі. Є багато варіантів, як його представити. Наприклад, популярні варіанти від Google та Neptun, або ж мій найулюбленіший від Мартіна Файлера з його статті Continuous Delivery for Machine Learning.

Це далеко не всі варіанти, але сьогодні зупинимося на спрощеному.

А далі дуже просто розглянемо, які етапи проходить ML-продукт.

Data

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

Наприклад, ви можете витратити місяці на експерименти з архітектурами й отримати приріст у 2–3 % своєї таргет-метрики. Тоді як додавши даних для вашої моделі, зазвичай, можна отримати приріст у кілька разів більший.

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

  • Data lakes, або складати дані просто в object storage. Як варіант, s3 або minio.
  • Data warehous. Може бути проста база даних, реляційна чи ні.
  • Data Mesh. Усе популярнішй підхід, про який є дуже гарна лекція. У ній йдеться про ситуацію, коли ви відокремлюєте дані з інфраструктурою в окремі, децентралізовані продукти.

До того ж, вам треба буде засетапити ETL-процеси й те, як ви будете додавати дані в систему та працювати з ними надалі. Два найпопулярніші інструменти, які ми використовуємо — Spark та Kafka, або ж їхні комерційні аналоги.

Звичайно, усе залежить від масштабу. Але з мого досвіду, компанія в 50–100 людей обробляє ~20—50 ТБ у місяць, і цим займається окрема Data Engineering team.

Мені дуже подобається ця візуалізація знань та навичок дата-інженера, де ви можете побачити, які зараз найактуальніші тули, та обрати корисні для себе. Якщо ж хочете розібратися в теорії фундаментально, то одна з найкращих книжок, що я читав на цю тему, — Designing Data-Intensive Applications.

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

Найпопулярніші інструменти для розмітки, які ми використовували:

  • Для комп’ютерного зору — CVAT та Scalabel.
  • Для розмітки тексту — Prodigy.

Крім того, чудові добірки:

А також тули для керування версіями ваших датасетів:

Юзкейс, який ми також інколи бачимо, це додавання Feature Store. Загалом — це ML-орієнтована база даних для повторного використання ML-фіч.

Деякі приклади Feature Store:

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

Experiments

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

І хоча 99% коду й результатів ви відкинете, бо це природа цього етапу, оформити його в масштабований і reproducible flow буде непоганою ідеєю.

Разом з інструментами для менеджменту даних ми зазвичай використовуємо темплейти для експериментів. Дуже популярний спосіб — pytorch-lightning. Цей фреймворк дозволяє не концентруватися на деталях: як експерименти будуть запускатись, як використовувати кілька GPU тощо. Pytorch-lightning може підійти не всім, і часто команди пишуть свої власні рішення або використовують темплейти.

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

  • TensorBoard — дуже популярний, має багато інтеграцій із різними фреймворками. Ви також можете використовувати TensorBoard.dev, щоб зберегти свої результати в клауді й не ділитися скриншотом у слаку з колегами. Проте вона часто важко скейлиться і з часом із нею стає важко працювати
  • Тоді ви можете перейти до MLflow Tracking, інструменту для менеджменту всього циклу ML-моделі. Частіше за все, використовується для експеримент-менеджменту, його потрібно підтримувати самостійно.
  • Найкращий варіант, як на мене, — почати з менеджерського рішення. Тобто інструмент для експериментів хтось менеджить та деплоїть за вас, їх не треба підтримувати та скейлети. Часто вони надають набагато кращий UX та набір функціоналу, ніж TensorBoard та MLflow Tracking, але можуть бути доволі дорогі. Найчастіше ми використовуємо: Weights & Biases та Comet.ml.

Окремо зауважу, що вам буде потрібно менеджити інфраструктуру для розробки моделей, наприклад, кластер з GPU. Ви можете почати з того, що дасте всім доступ для створення машин в AWS EC2 або його аналогах. Наприклад, дасте ssh доступ на ваш дедікейтет кластер. Проте з ростом команди та кількості експериментів це стане незручно. Різні експерименти можуть конфліктувати за ресурси, чи команда може забути видаляти мануально створені машини й ви будете втрачати кошти тощо.

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

Найчастіше для цього використовують Slurm, який можна комбінувати з таким пакетом. Або ж різновид платформи, що ґрунтується на Kubernetes. Є гарний кейс від OpenAI, як вони працюють з Kubernetes для тренування величезних моделей.

Pipelines

Отже, ви провели 100500+ тренувань, завалідували тонни гіпотез і вважаєте, що модель може приносити користь. Настав час загорнути її в процес для того, щоб тренувати в продакшені й ретренувати (доволі частий юзкейс, коли ви ретренуєте свою модель через певний проміжок часу).

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

Наприклад, коли остаточна модель має бути отримана в іншому середовищі: кластер вашого клієнта, продакшн, кластер, куди ви не маєте доступу тощо. Також гарна практика, якщо якийсь артефакт (в цьому випадку — ваги моделі) ви використовуєте в продакшені. Код, завдяки якому ви його отримали, має бути в проді також. З тестами й такими ж стандартами, як інший продакшн код. Хоча під час експериментів, для швидкості ви могли й не йти за найкращими інженерними практиками.

Як це зробити? Зазвичай, ми дотримуємося цих двох кроків: докеризація та використання pipelines бібліотеки.

Найпопулярніші pipelines бібліотеки, які ми використовували:

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

Дуже раджу прочитати цю статтю про те, як писати ML-пайплайни та який фрейморк обрати.

Deployment

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

Варіант 1. Не деплоїти модель взагалі :)

Jeff Atwood: «The best code is no code at all»

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

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

Варіант 2. Загорнути в пайтон фреймворк

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

Найчастіше використовуємо FastAPI (from Explosion, spaCy creators) через багато вбудованих фіч. Також популярні варіанти:

Flask — думаю більшість тих, хто вчить вебдевелопмент на Python, знайомі з ним.

Aiohttp (from python core contributors) — розробляється в Україні, та з його автором мені колись пощастило працювати разом. Він дуже корисний, якщо у вашому додатку потрібна асинхронність. Тільки будьте уважними, адже ML-моделі зазвичай CPU bound, тому з асинхронними фреймворками мають використовуватись обережно.

Варіант 3. Використати Inference server

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

Список далеко не повний. Ми часто використовуємо Seldon та TorchServe. Загальна ідея доволі проста — сконвертуйте свою модель у формат, який inference server може зрозуміти, і тоді він зможе задеплоїти її автоматично. Не треба писати свій вебсервер, а просто зберегти модель у певному місці в певному форматі. Такі фреймворки дають вам дуже багато додаткових фіч: система керування версіями для моделей, пояснення для результатів роботи ML-моделі, підтримка декількох моделей із коробки.

Варто зауважити, що жоден із цих варіантів не виключає інший. Важливо завжди балансувати та обирати, що саме вам потрібно для вирішення проблем бізнесу. Якщо ви стартап з 10 людей, то можливо, є речі, які зараз важливіші за inference server, і можна обійтися FastAPI. Якщо ж корпорація, де лише ML-департамент понад 100 людей, то дати всім один протестований та надійний спосіб делівері моделей — це справді гарна ідея.

Monitoring

Після того як задеплоїли модель, ми хочемо, щоб вона не деградувала. Для цього потрібно її моніторити. Головна різниця різниця між розробкою програмного забезпечення без ML-компоненти в тому, що класичного моніторингу логів та аптайму може бути недостатньо. Тобто цілком реальна ситуація, коли сервіс відпрацьовує добре, усі SLA виконані, модель віддає всі результати, але якщо проаналізувати їх — то результати зовсім неправильні. Ще гірше те, що така ситуація станеться не одразу, а через шість місяців після релізу.

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

Мені дуже подобається візуалізація з цього ресурсу, яка дає приблизне уявлення про проблему. Якщо ви хочете заглибитись у тему — серія з п’яти блог постів тут b1, b2, b3, b4, b5 буде гарним entry point.

Image Source

Якщо ж коротко, то вам потрібно:

  1. Моніторити якість даних. Від простих тестів: чи не змінилась схема даних, чи нема Null-значень у стовпчиках, де вони не мають бути тощо. До складних детекторів дрифту, які можуть сказати, чи стався у вас зсув датасету, як змінився розподіл між даними з продакшену та даними, на яких ви тренували модель. Такі детектори можуть буду і простими статистичними, й окремими ML-моделями.
  2. Моніторити якість моделі. Зазвичай, треба зберігати результати свого інференсу й діставати реальні лейбли для цих результатів, щоб будувати перформас моделі в реальному житті.

Ми використовуємо наступні тули:

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

Bonus: platforms

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

Але варто зауважити, що є багато платформ для ML, які стверджують, що покривають цикл машинного навчання end2end і мають підтримку кожного з кроків, що ми розглянули вище. Найчастіше з них ми використовуємо — AWS SageMaker та GCP Vertex AI.

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

Є хороша таблиця для порівняння різних платформ та рішень.

Summary

Отже, зробимо висновок, що розробка ML-моделей — це процес, який містить кілька компонентів: від роботи з даними та експериментів, до моніторингу та повернення до одного з попередніх кроків.

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

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

👍ПодобаєтьсяСподобалось19
До обраногоВ обраному8
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Підписатись на коментарі