Цю статтю написали Крістофер Леннан та Богдан Гірман.
TL;DR: Зміни в інфраструктурі є частиною вашої щоденної роботи, але зробити цей процес більш приємним — це ключ до успіху. Приймаючи кращі інженерні практики (DevOps, TDD, BDD, IaC тощо), ми показуємо, що управління більш ніж 100 пайплайнами — це не виклик для нас.
Вступ
У 2022 році команда з машинного навчання (MLE) в idealo взяла на себе всі сервіси рекомендацій з метою покращити рекомендації за допомогою потужностей машинного навчання.
Ця стаття обговорює три основні принципи проектування, які довели свою ефективність у сталому управлінні цими пайплайнами в AWS SageMaker:
- Розділення випусків пайплайнів і розгортань
- Ефективне тестування пайплайнів від початку до кінця
- Централізоване управління всьою інфраструктурою як кодом
Архітектура, що демонструє розділені випуски та розгортання пайплайнів з окремими Git репозиторіями для кожного пайплайну. Центральний репозиторій IaC забезпечує послідовне розгортання пайплайнів SageMaker через облікові записи AWS.
Розділення випусків пайплайнів і розгортань
У управлінні робочими процесами машинного навчання важливо зберігати баланс між гнучкістю та стабільністю. Для нашої команди розділення випусків пайплайнів і розгортань стало дуже корисним. Хоча це є загальним принципом у розробці програмного забезпечення, застосування його до пайплайнів SageMaker вимагало ретельного підходу та спеціальних інструментів.
Загальні переваги розділення
Розділення випусків і розгортань пайплайнів дає кілька переваг:
- Безперебійне відновлення: Якщо виникає проблема з розгортанням, ви можете повернутись до попередньої версії пайплайна без впливу на інші системи.
- Ізольовані збої: Проблеми в одному пайплайні не поширюються на інші, що забезпечує стійкість системи.
- Покращене тестування: Незалежне тестування випусків і розгортань пайплайнів забезпечує надійні робочі процеси та знижує ризики в продуктивному середовищі.
- Ітеративна розробка: Команди можуть працювати над оновленнями без необхідності негайного розгортання, що дає змогу краще й швидше проводити експерименти та валідацію.
Виклики з пайплайнами SageMaker
Пайплайни SageMaker добре інтегровані з AWS середовищами. Існує обмежена кількість варіантів для розгортання пайплайнів SageMaker. Розгортання пайплайну: SageMaker Python SDK і AWS CLI.
З SageMaker Python SDK досить легко розгорнути пайплайн, є безліч прикладів, і це добре документовано, але є кілька обмежень:
- Специфічні посилання на середовище: Вбудовані ресурси, такі як шляхи до S3 та посилання на ARN, обмежують переносимість.
- Відсутність масштабованості: Визначення пайплайнів, прив'язаних до конкретних AWS облікових записів, ускладнює масштабування на кілька середовищ.
Розгортання за допомогою AWS CLI дозволяє створити послідовні, незмінні та незалежні від облікових записів конфігурації пайплайнів, вирішуючи багато проблем, пов'язаних з тісно зв'язаними визначеннями.
Рішення для ефективного розділення
Зробити визначення пайплайнів незалежними від AWS облікових записів
Для розділення визначень пайплайнів від AWS облікових записів ми розробили спеціальний скрипт для динамічного видалення або заміни специфічних для облікових записів посилань (наприклад, шляхи до S3, ARNs) у JSON визначеннях пайплайнів.
Цей підхід гарантує:
- Переносимість (Portability): Пайплайни можуть бути безшовно передані між обліковими записами AWS без змін.
- Спрощене управління конфігураціями (Simplified Configuration Management): Деталі, специфічні для середовища, вводяться під час розгортання, що спрощує операції.
Завдяки використанню JSON визначень і інтеграції з Terraform, ми досягаємо:
- Незмінність (Immutability): Забезпечує стабільність і незалежність визначень пайплайнів від облікових записів.
- Контроль версій (Version Control): Дає можливість систематично відслідковувати та надійно повторювати конфігурації.
- Повторне використання (Reusability): Винесення специфічних для облікових записів деталей дозволяє використовувати JSON визначення в різних середовищах.
Вибір стратегії один репозиторій на один пайплайн (One-Repo-Per-Pipeline)
Ми організували нашу кодову базу з одним репозиторієм для кожного пайплайну. Така організація дозволяє нам:
- Забезпечити незалежне версіонування та цикли випусків для кожного пайплайну за допомогою вбудованих можливостей випуску GitHub.
- Ізолювати зміни в окремих пайплайнах, зменшуючи ризик перехресних збоїв між пайплайнами.
- Забезпечити високу якість випусків за допомогою всеосяжного CI/CD робочого процесу з GitHub Actions.
Конфігуровані параметри пайплайнів
Виробничі середовища часто мають різні вимоги до масштабування. Для вирішення цієї проблеми ми ввели конфігуровані параметри в наших визначеннях пайплайнів, такі як:
- Типи екземплярів (Instance Types): Забезпечує гнучкість у виборі обчислювальних ресурсів на основі вимог до навантаження.
- Паралельність (Parallelism): Налаштовує кількість одночасних задач для оптимізації використання ресурсів і часу обробки.
- Вікна огляду (Lookback Windows): Налаштовує історичний діапазон даних для навчальних або аналітичних завдань.
Винісши ці параметри, ми зробили наші пайплайни адаптивними до різноманітних виробничих вимог без необхідності змінювати код.
Ключові висновки
- Розділення випусків і розгортань пайплайнів дозволяє здійснювати безперебійне відновлення, ізолює збої та підтримує експерименти.
- Видалення специфічних для облікових записів ресурсів з визначень пайплайнів покращує переносимість і масштабованість.
- Незалежні репозиторії пайплайнів сприяють ізольованим змінам та спрощеному CI/CD процесу.
- Конфігуровані параметри роблять пайплайни адаптивними до різних виробничих потреб без зміни основних визначень.
Ефективне тестування пайплайнів від початку до кінця
Хоча розробка окремих пайплайнів є відносно простою, управління сотнями пайплайнів на великому масштабі часто призводить до складнощів. Одним із найбільших ризиків є те, що зміни в існуючому пайплайні можуть непередбачувано призвести до помилок. Тому ретельне тестування — не лише коду, а й самих пайплайнів — є абсолютно необхідним.
Пайплайни машинного навчання зазвичай дуже складні, оскільки їх кроки охоплюють все: від витягування даних і інженерії ознак до навчання моделі та оцінки, що вимагає широкого підходу до тестування. Це включає не тільки тестування коду, але й тестування перетворень даних, вихідних результатів моделей і інтеграцій пайплайнів.
Розробка через поведінку (Behavior-Driven Development): Тестування як специфікації
Для тестування кроків пайплайну ми прийняли підхід, орієнтований на поведінку, який розглядає тести як живі специфікації. Цей підхід без проблем інтегрується з pytest-bdd, фреймворком, що організовує тести в структурованому форматі. Ось як це працює:
- Given: Описує початковий контекст або налаштування.
- When: Визначає дію або тригер.
- Then: Перевіряє очікуваний результат.
Приклад сценарію BDD для тестування робочого процесу попередньої обробки даних, що демонструє, як сирі дані перетворюються на багаті ознаками виходи за допомогою структурованого підходу.
Ця структура забезпечує ясність і єдність, дозволяючи членам команди швидко розуміти і долучатися до тестів.
Організовуючи тести у вигляді функцій, сценаріїв та кроків, ми досягаємо:
- Повторне використання (Reusability): Кроки можуть бути повторно використані в кількох тестах, що зменшує дублювання коду.
- Послідовність (Consistency): Усі тести мають однакову структуру, що робить їх зрозумілішими та легшими в обслуговуванні.
- Простота (Simplicity): Тести стисливі, зосереджені на поведінці пайплайну, а не на деталях реалізації.
Тестування, орієнтоване на поведінку, спонукає нас:
- Розглядати кроки пайплайну як чорні ящики, перевіряючи вихідні дані на основі заданих входів.
- Уникати впровадження побічних ефектів у коді, що призводить до чистіших та більш передбачуваних пайплайнів.
Цей підхід безперешкодно інтегрується в процес розробки пайплайнів, забезпечуючи надійність і передбачуваність у наших робочих процесах.
Мокінг (Mocking) викликів AWS API з Moto
Тестування пайплайнів часто включає виклики AWS API, які можуть бути дорогими та викликати побічні ефекти. Наприклад, перед запуском тестів необхідно переконатися, що ресурси належним чином очищені, щоб уникнути дублікатів або конфліктів. Для вирішення цієї проблеми ми покладаємося на мокінг.
За допомогою бібліотеки moto ми:
- Симулюємо виклики AWS API без взаємодії з реальними сервісами.
- Прискорюємо процес розробки та тестування.
- Отримуємо кращий погляд на процеси пайплайнів, що дає змогу виконувати надійніші тести.
Moto — це бібліотека з відкритим вихідним кодом, яка активно підтримується, що робить її надійним рішенням для мокінгу викликів AWS API.
Інтеграційне тестування з AWS SageMaker Local Mode
Хоча тестування поведінки і мокінг покращують надійність тестів, важливо перевірити, що весь пайплайн працює як очікується. Спочатку ми проводили інтеграційні тести в dev/staging облікових записах, але цей процес був часозатратним через створення екземплярів, налаштування середовища та підготовку даних.
Рішенням стала AWS SageMaker Python SDK’s local mode, що дозволяє нам:
- Запускати пайплайни локально в середовищі розробки, наприклад, у GitHub action.
- Уникати очікування на розгортання хмарної інфраструктури.
- Швидко перевіряти інтеграції перед переходом до staging.
Це значно спростило та прискорило наше інтеграційне тестування, забезпечуючи безперешкодний перехід до staging середовищ.
Централізоване управління всією інфраструктурою як кодом
Після успішного створення та тестування більш ніж 100 пайплайнів ML, виникає наступне питання: Як їх розгорнути?
Декларативне розгортання
Підходи до розгортання зазвичай поділяються на три категорії: ручний, імперативний (наприклад, скрипти) та декларативний (наприклад, Terraform). Кожен має свої переваги та недоліки, але декларативний підхід вирізняється серед інших для управління інфраструктурою на великому масштабі. Інструменти, такі як Terraform, дозволяють застосовувати версіоновані, підлягаючі аудиту зміни, спрощують обробку складних залежностей та забезпечують послідовність між командами.
Зосереджуючись на інкрементальних змінах та підтримуючи чітку аудиторську трасу, декларативне розгортання дозволяє командам з упевненістю управляти системними оновленнями. Це особливо важливо при координації понад 100 пайплайнів, створених різними інженерами, де синхронізація та спрощена комунікація є вирішальними.
Комбінування GitOps з MLOps
GitOps надає структуровану основу для управління системами, визначаючи та контролюючи їх стан через Git. Основні принципи включають:
- Декларативна інфраструктура (Declarative Infrastructure): Визначення бажаних станів системи як код, що забезпечує відтворюваність і ясність.
- Контроль версій (Version Control): Використання Git як єдиного джерела правди, відслідковуючи всі зміни з чіткою аудиторською трасою.
- Автоматизовані розгортання (Automated Deployments): Автоматичне ініціювання розгортань на основі змін, зафіксованих у репозиторії.
Ми прийняли ці принципи для управління та розгортання ML пайплайнів, використовуючи централізований Terraform Git репозиторій і GitHub Actions. Ось як це працює:
-
Декларативні визначення пайплайнів (Declarative Pipeline Definitions)
Як було описано вище, пайплайни повністю визначаються декларативно через JSON визначення та Terraform конфігурації, що забезпечує послідовність та легкість модифікації.
2.
Централізоване джерело правди (Centralised Source of Truth)
Один Git репозиторій зберігає всі конфігурації пайплайнів і інфраструктури. Така централізація забезпечує повну видимість, авторитетний запис змін та можливість відкотитися до попередніх станів за потреби. -
Автоматизовані розгортання (Automated Deployments)
GitHub Actions автоматизує розгортання пайплайнів. Оновлення застосовуються тільки після того, як вони були зафіксовані та об'єднані, що забезпечує відповідність розгорнутого стану вмісту репозиторію.
Переваги GitMLOps
Цей підхід поєднує переваги GitOps та MLOps для досягнення значних переваг:
- Прозорість (Transparency): Централізація конфігурацій і змін у Git робить кожне оновлення відслідковуваним і зворотнім, забезпечуючи єдине джерело правди.
- Стабільність (Stability): Централізована автоматизація через GitHub Actions забезпечує послідовне розгортання у всіх середовищах, знижуючи ризик ручних помилок.
- Співпраця (Collaboration): Робочі процеси за допомогою pull-запитів сприяють ретельному код-рев’ю, сприяючи осмисленим обговоренням та зв’язуванню змін з завданнями або квитками (наприклад, у Jira).
- Відтворюваність (Reproducibility): Використання Terraform для керування ресурсами забезпечує швидке відновлення чи відтворення пайплайнів, мінімізуючи час простою.
- Обізнаність (Awareness): Історії комітів і pull-запитів дають чітке розуміння еволюції пайплайнів, спрощуючи налагодження і залучення нових співробітників.
Поєднуючи принципи GitOps з специфічними вимогами розгортання пайплайнів ML, ми побудували систему, яка є ефективною, надійною і легкою в управлінні, що дозволяє нашим командам зосереджуватися на вирішенні проблем, а не на обслуговуванні інфраструктури.
Висновки
Управління більш ніж 100 пайплайнами ML в idealo підкреслило важливість масштабованих і сталих практик. Ключові уроки включають цінність розділення випусків і розгортань пайплайнів для гнучкості, впровадження ретельного тестування від початку до кінця для забезпечення надійності та централізацію інфраструктури як коду для послідовності і відтворюваності.
Застосувавши принципи GitOps до специфічних проблем ML, таких як часті експерименти та динамічні дані, ми спростили операції і побудували систему, яка дозволяє інженерам зосереджуватися на наданні впливових рекомендацій з упевненістю.
Перекладено з: GitMLOps — How we are managing 100+ ML pipelines in AWS SageMaker