Промисловий Machine Learning: 10 принципів розробки

Промисловий Machine Learning: 10 принципів розробки

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

І, часом, кожен програміст-початківець, будь він пристрасним стартапером або рядовим Full Stack або Data Scientist, рано чи пізно приходить до усвідомлення того, що є певні правила програмування і створення софту, які сильно спрощують життя.

У цій статті я коротко опишу 10 принципів того, як варто програмувати промисловий machine learning, щоб його можна було легко вбудувати в додаток/сервіс, ґрунтуючись на методиці 12-factor App, запропонованою командою Heroku. Моя ініціатива – це підвищити впізнаваність цієї методики, що може допомогти багатьом розробникам та людям із Data Science.

Ця стаття – це пролог до серії статей про промисловий Machine Learning. У них я далі розповідатиму про те, як, власне, зробити модель і запустити її в продакшн, створити для неї API, а також приклади з різних областей та компаній, які мають вбудований ML у їхні системи.

Принцип 1. Одна кодова база

Деякі програмісти на перших етапах через лінощі розібратися (або з якихось своїх міркувань) забувають про Git. Забувають або від слова зовсім, тобто кидають файли один одному в драйві / просто кидають текст / відправляють голубами, або не продумують свою роботу, і роблять commit кожен у свою гілку, а потім і в майстри.

Цей принцип свідчить: майте одну кодову базу та багато розгортань.

Git можна використовувати як у production, так і в research and development (R&D), в якому він використовується не так часто.

Наприклад, у R&D фазі Ви можете залишати комміти з різними методами обробки даних та моделями, щоб потім вибрати найкращий і легко продовжити працювати з ним далі.

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

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

Принцип 2. Чітко оголошуйте та ізолюйте dependencies

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

  • Чітко оголосити dependencies, тобто файл, в якому будуть прописані всі бібліотеки, інструменти, та їх версії, які використовуються у Вашому проекті та які мають бути встановлені (наприклад, у Python це можна зробити за допомогою Pipfile або requirements.txt. Посилання, що дозволяє добре розібратися: realpython.com/pipenv-guide)
  • Ізолювати dependencies спеціально для вашої програми під час розробки. Ви ж не хочете постійно змінювати версії та встановлювати заново, наприклад, Tensorflow?

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

Ваша програма також не повинна спиратися на системні інструменти, які можуть бути встановлені на певній ОС. Ці інструменти також потрібно оголошувати в маніфесті dependencies. Це потрібно для того, щоб уникнути ситуацій, коли версія інструментів (а також їх наявність) не збігається із системними інструментами певної ОС.

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

Наприклад, Ваш requirements.txt може виглядати так:

# Model Building Requirements
numpy>=1.18.1,<1.19.0
pandas>=0.25.3,<0.26.0
scikit-learn>=0.22.1,<0.23.0
joblib>=0.14.1,<0.15.0

# testing requirements
pytest>=5.3.2,<6.0.0

# packaging
setuptools>=41.4.0,<42.0.0
wheel>=0.33.6,<0.34.0

# fetching datasets
kaggle>=1.5.6,<1.6.0

Принцип 3. Зміни

Багато хто чув про історії, коли різні хлопці-девелопери випадково завантажували код на GitHub у відкриті репозиторії з паролями та іншими ключами від AWS, прокидаючись наступного дня із заборгованістю 6000$, а то й з усіма 50000$.

Промисловий Machine Learning: 10 принципів розробки

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

Альтернатива цьому - це зберігати зміни в змінних середовищах. Докладніше про змінні середовища Ви можете прочитати тут.

Приклади даних, які зазвичай зберігаються в змінних середовищах:

  • Імена доменів
  • API URL/URI's
  • Публічні та приватні ключі
  • Контакти (пошта, телефони тощо)

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

Наприклад, якщо ви використовуєте Kaggle API для проведення тестів (наприклад, завантажуєте дотаює і проганяєте через нього модель, щоб протестувати при запуску, що модель працює добре), то приватні ключі від Kaggle, такі як KAGGLE_USERNAME та KAGGLE_KEY треба зберігати в змінному середовищі.

Принцип 4. Сторонні служби

Ідея тут — це створювати програму таким чином, щоб не було відмінностей між локальними та сторонніми ресурсами щодо коду. Наприклад, можна підключити як локальну MySQL, так і сторонню. Те саме стосується і різних API, таких як Google Maps або Twitter API.

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

Так, наприклад, замість того, щоб вказувати щоразу шлях до файлів з датасетами всередині коду, краще скористатися бібліотекою pathlib і оголосити шлях до датасетів у config.py, щоб не залежно від того, яким сервісом Ви використовуєтесь (наприклад, CircleCI), програма змогла дізнатися шлях до датасет з урахуванням будови нової файлової системи в новому сервісі.

Принцип 5. Складання, реліз, runtime

Багатьом людям з Data Science корисно качати навички написання софту. Якщо ми хочемо, щоб наша програма якомога рідше «падала», і якнайдовше працювала без збоїв, нам потрібно розділити процес релізу нової версії на 3 етапи:

  1. етап збірки. Ви перетворюєте Ваш голий код з окремими ресурсами на так званий пакет, який містить весь необхідний код та дані. Цей пакет і називається збиранням.
  2. етап релізу - До складання тут ми підключаємо наш config, без якого ми не змогли б випустити нашу програму. Тепер це повністю готовий для запуску реліз.
  3. Далі йде етап виконання. Тут ми випускаємо програму за допомогою запуску необхідних процесів з нашого релізу.

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

Для завдання релізу створено безліч різних сервісів, в яких Ви можете записати процеси для запуску самі в файл .yml (наприклад, в CircleCI це config.yml для забезпечення самого процесу). Wheely чудово створює пакет для проектів.

Ви зможете створювати пакети з різними версіями вашої machine learning моделі, а потім пакетувати їх і надсилатися до потрібних пакетів та їх версій, щоб використовувати звідти функції, які Ви написали. Це допоможе Вам створити API для Вашої моделі, а Ваш пакет можна розмістити, наприклад, на Gemfury.

Принцип 6. Запускаємо Вашу модель як один чи кілька процесів

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

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

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

Щоб запустити модель як кілька процесів, можна створити .yml файл, в якому ви вкажете необхідні процеси та їх послідовність.

Принцип 7. Утилізованість

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

Тобто ваш процес із моделлю повинен:

  • Мінімізувати час запуску. В ідеалі час запуску (від моменту, коли було подано команду запуску до моменту, коли процес прийде в робочий стан) повинен мати трохи більше кількох секунд. Кешування бібліотек, описане вище, - це одна з методик зменшення часу запуску.
  • Завершуватиметься коректно. Тобто фактично припиняється прослуховування порту сервісу, і нові запити, подані до цього порту, не будуть оброблятись. Тут вже потрібно або налаштовувати непоганий зв'язок з DevOps інженерами, або самому розуміти, як це працює (бажано, звичайно, друге, але зв'язок підтримувати треба завжди, у будь-якому проекті!)

Принцип 8. Безперервне розгортання/інтеграція

У багатьох компаніях використовують поділ між командами розробки програми та її розгортання (додаток, що робить доступним для кінцевих користувачів). Це може сильно уповільнювати розробку софту та прогресу у його покращенні. А також це псує культуру DevOps, де розробка та інтеграція, грубо кажучи, об'єднані.

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

Це дозволить:

  1. Зменшити час релізу в десятки разів
  2. Зменшити кількість помилок через несумісність коду.
  3. Також це дозволяє знизити навантаження на персонал, оскільки розробники та люди, які розгортають додаток, — тепер одна команда.

Інструменти, які дозволяють із цим працювати - CircleCI, Travis CI, GitLab CI та інші.

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

Мінімізуйте відмінності!

Принцип 9. Ваші логі

Logs (або «Логи») — це записані зазвичай у текстовому форматі події, що відбуваються всередині програми (потік подій). Простий приклад: «2020-02-02 – рівень системи – ім'я процесу». Вони створені для того, щоб розробник міг буквально бачити, що відбувається, коли програма працює. Він бачить хід процесів, і розуміє, чи він такий, як сам розробник задумував.

Цей принцип говорить про те, що не варто зберігати свої логи всередині вашої файлової системи - їх потрібно просто виводити на екран, наприклад робити це в стандартному виведенні системи stdout. І за потоком у такий спосіб можна буде стежити в терміналі під час розробки.

Чи означає це, що не потрібно зберігати логи зовсім? Звичайно, ні. Просто цим не повинна займатися Ваша програма — залиште це стороннім сервісам. Ваша програма може лише перенаправити логи в певний файл або термінал для перегляду в реальному часі або перенаправити його в систему для зберігання даних загального призначення (наприклад, Hadoop). Ваша програма не повинна зберігати або взаємодіяти з логами.

Принцип 10. Тестуйте!

Для промислового machine learning ця фаза дуже важлива, тому що Вам потрібно зрозуміти, що модель працює правильно і видає те, що Ви хотіли.

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

Не забувайте ставити однаковий seed для deep learning моделей, щоб вони не видавали різні результати.

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

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

Джерело: habr.com

Додати коментар або відгук