От диплома до продакшена: Как я создавал архитектуру ИИ-проекта для… Часть 7: Инфраструктура, MLOps и уроки масштабирования
Автор: Алексей Бобрешов, руководитель отдела искусственного интеллекта Категория: Искусственный интеллект, MLOps, управление проектами, масштабирование Время чтения: 13–16 минут
Это седьмая, заключительная часть серии. Для контекста по безопасности рекомендую Часть 6.
Введение: почему модель — это ещё не продукт
Когда я защищал диплом по «умному дому» в 2021 году, у меня была работающая нейросеть с точностью 94.06%. Я думал: «Вот оно — готовое решение».
Реальность оказалась сложнее. И сразу честно, как и в Части 6: сам дипломный проект в продакшн не пошёл — это был proof of concept, который я довёл до рабочего прототипа и проверял дома. Всё, что я расскажу дальше про масштабирование, MLOps и эксплуатацию, — это уроки из последующей коммерческой работы над ИИ-проектами, наложенные на тот самый дипломный прототип как на сквозной пример.
Главный вывод за эти годы у меня сложился такой: обучить модель — это меньшая часть работы. Большая часть — это масштабирование, мониторинг, поддержка и эволюция системы в реальных условиях. Это расхожая отраслевая оценка (часто говорят про «20/80»), и мой опыт её скорее подтверждает, чем опровергает.
В этой части я разберу:
какие ошибки совершают при переходе из прототипа в прод и как их избежать;
архитектурные паттерны, которые делают модель пригодной для эксплуатации;
как устроены MLOps-процессы в реальной команде;
практический чеклист готовности проекта к масштабированию.
Глава 1. «Проклятие прототипа»: почему код из Jupyter не живёт в продакшене
1.1. Типичный путь: от ноутбука к кластеру
Этот путь проходят почти все ИИ-проекты — мой не исключение:
Этап |
Инструменты |
Проблемы |
Решение |
|---|---|---|---|
Прототип |
Jupyter, Colab, локальные данные |
Нет версионности и воспроизводимости |
Git + DVC |
Пилот |
Docker, Flask, ручной деплой |
Нет автоматизации, сложно откатывать |
CI/CD |
Продакшн |
Kubernetes, MLflow, Prometheus |
Мониторинг, дрейф моделей |
Полноценный MLOps |
1.2. Три ошибки, которые стоят дороже всего
Ошибка 1. «У меня же работает на ноутбуке».
Прототип живёт в идеальных условиях: чистые данные, один пользователь, никакой нагрузки. Прод — это валидация входа, таймауты, логирование и обработка отказов. Разница в коде наглядна:
# Прототип: работает локально, пока всё идёт по плану model = load_model('my_model.h5') result = model.predict(audio) # Продакшн: учитываем окружение и отказы class ProductionModel: def __init__(self, model_path: str, config: ModelConfig): self.model = self._load_with_validation(model_path) self.preprocessor = AudioPreprocessor(config) self.logger = SecurityAuditLogger() def predict(self, audio: bytes, context: RequestContext) -> Prediction: try: self._validate_input(audio) # валидация входа processed = self.preprocessor.process(audio) self.logger.log_preprocessing(context, processed.shape) result = self._predict_with_timeout(processed, timeout_ms=500) return self._validate_output(result) # валидация выхода except ModelError as e: self.logger.log_error(context, e) raise
Ошибка 2. Игнорирование дрейфа данных.
Модель распознавания команд отлично работала на обучающей выборке. В реальной эксплуатации картина другая: акценты, которых не было в датасете; фоновый шум вместо лабораторной тишины; другие микрофоны. Распределение входных данных «уезжает» — и точность падает, хотя сам код не менялся.
Для контроля используют индекс стабильности популяции (PSI). Вот рабочая реализация — без заглушек:
import numpy as np def calculate_psi(expected: np.ndarray, actual: np.ndarray, bins: int = 10) -> float: """Population Stability Index между эталонным и текущим распределением.""" # Границы бинов — по квантилям эталонного распределения edges = np.quantile(expected, np.linspace(0, 1, bins + 1)) edges[0], edges[-1] = -np.inf, np.inf # покрываем хвосты exp_counts, _ = np.histogram(expected, bins=edges) act_counts, _ = np.histogram(actual, bins=edges) eps = 1e-6 # сглаживание, чтобы не делить на ноль exp_pct = exp_counts / exp_counts.sum() + eps act_pct = act_counts / act_counts.sum() + eps return float(np.sum((act_pct - exp_pct) * np.log(act_pct / exp_pct))) # Интерпретация: < 0.1 — стабильно; 0.1–0.25 — умеренный дрейф; > 0.25 — сильный дрейф
Ошибка 3. print() вместо мониторинга.
Пока пользователей единицы, отладочный вывод в консоль ещё спасает. На масштабе он превращается в бомбу замедленного действия: когда что-то ломается, у вас нет ни метрик, ни структурированных логов, ни алертов — только тишина и недовольные пользователи.
1.3. Архитектурный паттерн: «обёртка продакшена»
Ключевая идея — не пускать запрос напрямую в модель, а оборачивать её слоями защиты и наблюдаемости:
┌─────────────────────────────────────────────────────────────┐ │ PRODUCTION WRAPPER │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Input │ │ Model │ │ Output │ │ │ │ Validation │ │ Executor │ │ Validation │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ │ │ │ Rate │ │ Timeout │ │ Logging & │ │ │ │ Limiting │ │ Control │ │ Auditing │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ │ │ │ Circuit │ │ Fallback │ │ Metrics │ │ │ │ Breaker │ │ Strategy │ │ Collection │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────┐ │ Core Model │ └─────────────────┘
Модель здесь — лишь ядро. Всё вокруг — это то, что отличает демо от системы, которую не страшно вывести к пользователям.
Глава 2. MLOps на практике: как устроены процессы
2.1. Эволюция стека
Если сравнить «инструменты студента» и «инструменты команды», разница примерно такая:
Компонент |
Прототип |
Прод |
Зачем меняли |
|---|---|---|---|
Версионирование |
Ручные бэкапы |
DVC + Git LFS |
Воспроизводимость экспериментов |
Эксперименты |
Таблицы в Excel |
MLflow / Weights & Biases |
Сравнение моделей и метрик |
Деплой |
|
Kubernetes + ArgoCD |
Автоматизация, откаты, A/B |
Мониторинг |
|
Prometheus + Grafana + ELK |
Проактивное обнаружение проблем |
Тестирование |
Ручные проверки |
Pytest + Great Expectations |
Гарантия качества перед деплоем |
2.2. CI/CD для ML-модели
Пайплайн отличается от обычного бэкенда тем, что между тестами и деплоем появляется обучение и оценка модели:
# .github/workflows/ml-pipeline.yml name: ML Model CI/CD on: push: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Unit tests run: pytest tests/unit/ - name: Data validation run: python scripts/validate_data.py train: needs: test runs-on: gpu-cluster if: github.ref == 'refs/heads/main' steps: - name: Train run: python train.py --config config/prod.yaml - name: Evaluate (gate by threshold) run: python evaluate.py --threshold 0.95 - name: Register model run: mlflow models register --name voice_control deploy: needs: train runs-on: kubernetes if: github.ref == 'refs/heads/main' steps: - name: Deploy to staging run: kubectl apply -f k8s/staging/ - name: Smoke tests run: python tests/smoke/test_api.py - name: Deploy to production (manual approval) run: kubectl apply -f k8s/production/
Обратите внимание на шаг Evaluate (gate by threshold): если новая модель не дотягивает до порога качества, она просто не доезжает до прода. Это дешевле любого инцидента.
2.3. Что отслеживать в эксплуатации
Полезно держать метрики на трёх уровнях:
Инфраструктура: CPU/Memory/GPU, latency (p50/p95/p99), error rate (4xx/5xx).
Модель: дрейф распределения предсказаний, распределение confidence-скоров, перекос классов.
Бизнес: доля успешно выполненных команд, неявная обратная связь от пользователей, стоимость одного предсказания.
Первый уровень показывает, что система жива; второй — что модель всё ещё работает; третий — что всё это вообще приносит пользу.
Глава 3. Команда и процессы: масштабируется не только код
3.1. Роли в ИИ-команде
Когда проект перерастает «одного человека с ноутбуком», важно разделить ответственность:
Роль |
За что отвечает |
|---|---|
ML Engineer |
Разработка и обучение моделей |
MLOps Engineer |
Деплой, мониторинг, инфраструктура |
Data Engineer |
Пайплайны данных и их качество |
AI Product Manager |
Требования бизнеса, приоритизация, метрики |
AI Security Specialist |
Безопасность, приватность, аудит (см. Часть 6) |
На раннем этапе один человек закрывает несколько ролей — это нормально. Проблема начинается, когда роли подменяются молчанием: «мониторингом займёмся потом», «безопасность — не моя зона». «Потом» обычно наступает в виде инцидента.
3.2. Жизненный цикл: от идеи до эксплуатации
1. DISCOVERY (1–2 недели) • Бизнес-требования и метрики успеха • Оценка доступности данных, рисков ↓ 2. PROTOTYPING (2–4 недели) • EDA, baseline-модель, демо PoC ↓ 3. DEVELOPMENT (4–8 недель) • Прод-код с тестами, оптимизация • Security & privacy review ↓ 4. STAGING (1–2 недели) • A/B, нагрузочное тестирование, UAT ↓ 5. PRODUCTION + MONITORING (постоянно) • Постепенный rollout, canary • Мониторинг, алерты, обратная связь, ретрейнинг
3.3. Что я сделал бы иначе
Закладывал бы MLOps с первого дня, а не «сначала модель, потом инфраструктура». Параллельно — дешевле.
Автоматизировал бы тестирование данных раньше. Самые неприятные баги — не в коде, а в «тихом» изменении распределения.
Завёл бы playbook для инцидентов. Когда что-то падает в три часа ночи, нужен чеклист, а не паника.
Глава 4. Чеклист: готов ли проект к масштабированию
Это самая практичная часть — её можно унести с собой.
Код и архитектура
[ ] Код вынесен из Jupyter в модули с тестами
[ ] Конфигурация отделена от кода (config-файлы, env)
[ ] Есть обработка ошибок и graceful degradation
[ ] Логирование структурированное, а не
print()[ ] Есть health checks и readiness probes
Данные
[ ] Версионирование данных (DVC, LakeFS)
[ ] Валидация входных данных
[ ] Мониторинг дрейфа
[ ] SLA на свежесть данных
Модель
[ ] Версионирование моделей (MLflow, DVC)
[ ] A/B-тестирование или canary-деплой
[ ] Механизм отката на предыдущую версию
[ ] Метрики успеха модели именно в проде, а не только на тесте
Инфраструктура
[ ] Автоматизированный деплой (CI/CD)
[ ] Горизонтальное/вертикальное масштабирование
[ ] Мониторинг инфраструктуры и приложения
[ ] Заданы SLO/SLI и правила алертинга
Команда и процессы
[ ] Чёткое разделение ролей
[ ] Code review с фокусом на ML-аспекты
[ ] On-call ротация и playbook для инцидентов
[ ] Регулярные ретроспективы
[ ] Соответствие 152-ФЗ / GDPR проверено (см. Часть 6)
Если по большинству пунктов стоит галочка — вы, скорее всего, готовы. Если нет — вы готовы к проблемам.
Глава 5. Мысленный эксперимент: как я масштабировал бы дипломный прототип
А теперь — честная оговорка, и заодно ответ внимательному читателю.
В Части 6 я прямо сказал: дипломный проект не дошёл до промышленной эксплуатации. Поэтому всё, что ниже, — это не «отчёт о реальном внедрении на 10 000 устройств», а проекция: как повёл бы себя этот прототип при масштабировании, исходя из его реальных характеристик и из закономерностей, которые я наблюдал на коммерческих проектах. Цифры здесь — ориентиры порядка величины, а не замеры конкретной прод-системы.
Проблема 1. Латентность растёт с нагрузкой. Один сервер с синхронным инференсом упрётся в потолок задолго до тысяч устройств. Лечится горизонтальным масштабированием inference-сервисов, кэшированием частых запросов (Redis) и асинхронной обработкой некритичных команд.
Проблема 2. Дрейф качества. Точность на тесте и точность через три месяца в проде — разные числа, и второе обычно ниже. Лечится мониторингом дрейфа (PSI, KS-тест), автоматическим триггером ретрейнинга и active learning: сбором «сложных» примеров для дообучения.
Проблема 3. Стоимость инфраструктуры. GPU-инференс «в лоб» дорожает быстрее, чем растёт польза. Лечится оптимизацией моделей (квантование, pruning), spot-инстансами для batch-задач и агрессивным авто-скейлингом в ночные часы.
Ориентировочная проекция «было → стало» (повторюсь: расчётные ориентиры, а не факт эксплуатации):
Метрика |
Старт |
Цель |
|---|---|---|
Устройства |
100 |
10 000+ |
Latency p95 |
2–5 сек |
< 500 мс |
Точность в проде |
падает до ~87% |
восстанавливается до ~93% |
Время деплоя модели |
дни |
< 1 часа |
Здесь и начинаются «разногласия», которые вы могли заметить по серии: между честным «прототип не пошёл в прод» и заманчивым «а вот как бы он полетел». Где проходит граница между проверенным опытом и обоснованной проекцией, какие из этих цифр я могу подтвердить реальными кейсами, а какие остаются гипотезой — этому я посвящу Часть 8. Там же разберу вопросы и возражения из комментариев к предыдущим частям: честный разбор расхождений полезнее, чем красивый, но непроверяемый кейс.
Заключение: масштабирование — это другая игра, а не «больше того же»
Когда я начинал, я думал, что главное — точная модель. Сегодня я думаю иначе: главное — система, которая работает в реальном мире, для реальных людей, в реальных условиях.
Три принципа, которые я вынес:
Масштабируйте процессы, а не только код. Автоматизация, мониторинг и документация — это фундамент, а не «потом».
Закладывайте отказоустойчивость с первого дня. Модель упадёт, данные испортятся, сеть отвалится. Вопрос не «если», а «когда».
Масштабирование — командный спорт. Прототип может сделать один человек; систему — нет.
Что я сказал бы себе в начале пути: «Не спеши. Инвестируй в инфраструктуру. Документируй. Тестируй. Масштабируй постепенно. И помни: продакшн — это не финиш, а старт».
Призыв к действию
Если вы делаете ИИ-проект: не откладывайте MLOps, документируйте допущения и ограничения модели, тестируйте не только accuracy, но и latency, cost и устойчивость.
Если вы руководите направлением: вкладывайтесь в команду и процессы, измеряйте успех бизнес-метриками.
Если вы только начинаете: начните с малого, но думайте о масштабе, и учитесь на чужих ошибках — в том числе на моих.
И главное — оставайтесь честными с читателем. Где я опираюсь на опыт, а где на расчёт, я постарался отметить прямо. Полный разбор спорных мест — в следующей части.
Вся серия:
Часть 1. Что я хотел видеть дома в 2021
Часть 2. Как я проектировал опыт пользователя
Часть 3. Архитектура нейросети для распознавания голосовых команд
Часть 4. Обучение и валидация модели — 250 эпох, 94.55% точности и борьба с переобучением
Часть 5. Интеграция с устройствами умного дома — от модели к реальному устройству
Часть 7. Инфраструктура, MLOps и уроки масштабирования (## эта статья получилась очень долгой, столько разного хотелось дополнить и пояснить, столько всего вспомнилось что было в моменты размышлени над дипломным проектом в 21-м году, такие разные виделись картинки в голове… эх… Желаю и вам, это было здорово!)
Часть 8 (скоро): разбор разногласий, ответы на комментарии и граница между опытом и проекцией.
Автор: Алексей Бобрешов, руководитель отдела искусственного интеллекта Лицензия: CC BY-NC 4.0
Теги: искусственный интеллект, MLOps, масштабирование, продакшн, управление проектами, умный дом, голосовые интерфейсы, DevOps, мониторинг, 152-ФЗ
Хабы: Искусственный интеллект, Машинное обучение, DevOps, Голосовые интерфейсы