Зображення статті
## Чому ML-системи накопичують технічний борг швидше звичайного ПЗ
Технічний борг (technical debt) — метафора з фінансового світу: ви приймаєте «дешеве» рішення зараз, але потім платите «відсотки» у вигляді складнішої підтримки, повільнішого розвитку і ризику відмов. У звичайному програмуванні це добре відомо. У ML — ще гірше.
Класична стаття Google «Hidden Technical Debt in Machine Learning Systems» (Sculley et al., 2015) описує унікальні джерела боргу, яких немає в традиційному ПЗ. Ця стаття через 10 років залишається актуальною.
**Чому ML tech debt особливий:**
- Дані змінюються з часом незалежно від коду
- Межа між кодом і конфігурацією розмита
- Складно відтворити результати без фіксації середовища
- Склад команди часто змінюється, а неявні знання губляться
## Джерело 1: Entanglement (заплутаність)
### Що це
У ML-системі змінення будь-якого компонента може вплинути на поведінку всіх інших. Ви додали нову ознаку — і стара модель поводиться інакше. Ви змінили preprocessing — і метрики пішли вниз без очевидної причини.
Це «CACE-принцип»: Changing Anything Changes Everything.
### Як виникає
Найчастіше — через відсутність версіонування. Датасет оновлюється без мітки версії, preprocessing-скрипт змінюється без коміту, гіперпараметри налаштовуються без запису.
### Як уникнути
**Data versioning:** DVC (Data Version Control) або Delta Lake. Кожна зміна датасету — окрема версія з хешем.
**Experiment tracking:** MLflow або Weights & Biases. Кожен запуск навчання фіксує: версію даних, версію коду, гіперпараметри, метрики.
**Feature store:** централізоване сховище ознак гарантує, що ознака обчислюється однаково при навчанні і inference.
## Джерело 2: Hidden Feedback Loops (приховані петлі зворотного зв'язку)
### Що це
ML-система впливає на дані, які потім використовуються для її перенавчання. Рекомендаційна система показує певний контент → користувачі взаємодіють з ним → система навчається на цих взаємодіях → починає рекомендувати ще більше цього контенту.
Петля замкнулася. Результат: систематичне посилення існуючих упереджень.
### Типові приклади
- Система виявлення шахрайства блокує транзакції → ці транзакції не потрапляють у навчальну вибірку → модель не вчиться на нових паттернах шахрайства
- Система ранжування результатів пошуку → вище ranked отримує більше кліків → модель вважає його «кращим»
### Як боротися
**Counterfactual logging:** логувати не тільки те, що показали, але й що могли показати.
**Exploration policy:** резервувати частку трафіку (5–10%) для випадкових рекомендацій для збору незміщених даних.
**Аудит навчальних даних:** регулярно перевіряти розподіл навчальної вибірки на зміщення.
## Джерело 3: Undeclared Consumers (нерегламентовані споживачі)
### Що це
Ваша ML-система — це не ізольований сервіс. Інші команди починають використовувати її виходи (predictions, embeddings, intermediate features) без явної угоди. Коли ви змінюєте систему, ці команди несподівано ламаються.
### Як виникає
«Швидке» API без версіонування. Відсутність реєстру залежностей. «Неофіційне» використання internal endpoints.
### Рішення
**Версіоноване API:** /v1/predict, /v2/predict — ніколи не ламати існуючі версії.
**Service registry:** документувати всіх споживачів і сповіщати їх про зміни.
**Contract testing:** автоматизовані тести, що перевіряють формат виходів і не дозволяють їх змінити без оновлення версії.
## Джерело 4: Pipeline Jungles (pipeline-джунглі)
### Що це
З часом preprocessing pipeline перетворюється на нечитабельний ліс скриптів: один скрипт читає з S3, передає в інший, який викликає третій, виходи якого об'єднуються з четвертим... Ніхто не знає, що відбувається всередині.
### Ознаки
- Неможливо відтворити pipeline вручну
- «Магічні» проміжні файли без документації
- Скрипти, які «не чіпають, бо ніхто не знає що вони роблять»
- Час запуску pipeline 6+ годин без можливості частково перезапустити
### Рефакторинг
**Оркестратори:** Apache Airflow, Prefect або Metaflow. Кожен крок pipeline — функція з явними входами і виходами.
**Тестування pipeline:** кожен компонент pipeline має unit-тести. Інтеграційні тести на мінімальному датасеті.
**Документація прямо в коді:** docstrings з описом очікуваних вхідних форматів і виходів.
## Джерело 5: Glue Code та Config Debt
### Glue Code
90% ML-проєктів використовують відкриті бібліотеки. Для з'єднання компонентів пишеться glue code — клей між ними. Цей клей накопичується і перетворюється на найбільшу частину кодової бази.
**Симптом:** «у нас тільки 200 рядків ML-коду, але 2 000 рядків клею навколо нього».
### Config Debt
Конфігурація ML-системи (гіперпараметри, шляхи до файлів, порогові значення) зростає і розповзається по різних місцях: частина в .env, частина в config.yaml, частина hardcoded в скриптах.
**Рішення:** централізований конфіг (Hydra або простий YAML), всі параметри — явні і задокументовані.
## Стратегія усунення існуючого боргу
### Аудит: де болить?
Перший крок — картування існуючого боргу. Запитання для команди:
- Що займає більше часу, ніж мало б?
- Де ви боїтеся вносити зміни?
- Яка частина системи «тримається на соплях»?
### Пріоритизація
Не весь борг однаково шкідливий. Матриця пріоритетів:
- **Критичний:** борг, що блокує масштабування або несе ризик безпекового інциденту
- **Важливий:** борг, що уповільнює розробку або ускладнює debugging
- **Прийнятний:** борг, що не впливає на поточну роботу і не буде впливати протягом кварталу
### Tactique Boy Scout Rule
«Залишай табір чистіше, ніж знайшов.» Кожного разу, коли торкаєшся компонента — залишай його трохи кращим. Не рефакторинг заради рефакторингу, а поступове покращення.
**Практично:** при кожному feature request виділяти 20% часу на усунення боргу в торкнутих компонентах.
### Debt Sprints
Раз на квартал — спринт, повністю присвячений технічному боргу. Жодних нових фічей. Тільки усунення задокументованих проблем.
**Умова успіху:** підтримка менеджменту. Без розуміння «навіщо ми нічого нового не робимо два тижні» — debt sprint перетвориться на фрустрацію.
## Превентивні практики для нових проєктів
**Definition of Done для ML:** будь-яка модель вважається «зробленою» тільки якщо: є версіонований датасет, зафіксовані гіперпараметри, задокументовані обмеження, написані базові тести preprocessing.
**ML Code Review checklist:** явний список питань для review: чи є hardcoded шляхи? чи логуються метрики? чи тестується pipeline?
**Architecture Decision Records (ADR):** документувати кожне архітектурне рішення: що обрали, які альтернативи розглядали, чому відхилили. Безцінно при onboarding нових членів команди.
Технічний борг у ML-системах — не ознака поганої команди. Це неминучий результат ітеративної розробки в умовах невизначеності. Ключ — усвідомлено управляти ним, а не ігнорувати до першої серйозної відмови.
Стаття в розробці. Підпишіться щоб отримати сповіщення.
Написати нам →#MLOps#технічний борг#рефакторинг#ML стратегія
МС
Марія Сич
Команда CodeNest
Практикуючий ML-інженер. Спеціалізується на побудові виробничих AI-систем для бізнесу.
🤖
Готові автоматизувати ваш бізнес?
Обговоримо ваш проєкт і запропонуємо оптимальне рішення. Безкоштовна консультація без зобов'язань.