# Обзор архитектуры ML приложений: от концепций до production

## Введение

Мир разработки программного обеспечения переживает тектонический сдвиг. Если раньше код был исключительно детерминированным (при одном и том же входе мы всегда получали один и тот же выход), то теперь мы всё чаще внедряем вероятностные системы — модели машинного обучения (ML).

Для архитектора программных решений это означает появление нового класса требований: обработка неопределенности, управление данными как кодом, специфические паттерны отказоустойчивости и необходимость тестирования того, что нельзя протестировать юнит-тестами в классическом понимании.

Цель этой статьи — сформировать у вас, как у специалиста по ИТ-архитектуре, целостную картину современных подходов к построению ML-приложений. Мы пройдем путь от базовых понятий до конкретных архитектурных решений.

---

## 1. Основные понятия, концепции и принципы ML

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

### 1.1. Модель как артефакт

С точки зрения архитектора, **модель машинного обучения** — это программный артефакт, полученный в результате обучения на исторических данных. Этот артефакт (часто файл с расширением `.pkl`, `.pt`, `.h5`, `.onnx`) кодирует в себе статистические закономерности. В отличие от классического кода (бизнес-логики), модель не "вычисляет" ответ строго по формулам, а "предсказывает" его на основе примеров, которые видела во время обучения.

### 1.2. Обучение (Training) vs. Инференс (Inference)

Это два ключевых режима работы системы:

* **Обучение (Training):** Ресурсоемкий процесс, где "сырые" данные превращаются в модель. Требует огромных вычислительных мощностей (GPU/TPU) и работы с большими объемами данных. Выполняется периодически.
* **Инференс (Inference):** Режим эксплуатации. Готовая модель получает входные данные (например, текст запроса пользователя) и выдает результат (например, вероятность намерения). Это быстрая, часто онлайн-операция.

### 1.3. Типы задач

Архитектура сильно зависит от типа задачи:

* **Классификация:** Отнесение объекта к одной из категорий (например, "спам / не спам").
* **Рег рессия:** Предсказание непрерывного значения (например, стоимость недвижимости).
* **Генерация (GenAI):** Создание нового контента (текста, изображения, кода). Самый сложный класс с точки зрения архитектуры, так как требует контроля качества, безопасности и огромных вычислительных ресурсов.

### 1.4. Основные архитектурные принципы

При проектировании ML-систем нужно учитывать специфические принципы:

* **Разделение данных и кода:** Данные для обучения — это изменяемая сущность. Если изменились данные, модель должна быть переобучена. Версионирование данных так же важно, как версионирование кода.
* **Изоляция экспериментов:** Процесс создания модели — это R&D. Архитектура должна позволять Data Scientist'ам экспериментировать (перебирать гиперпараметры, пробовать разные архитектуры нейросетей) в песочнице, не влияя на продакшн-системы.
* **Асинхронность и пакетность:** Обучение почти всегда асинхронно по отношению к основному бизнес-процессу. Инференс может быть как синхронным (онлайн), так и пакетным (batch).

---

## 2. MLOps процессы и практики

MLOps (Machine Learning Operations) — это набор практик, которые объединяют разработку ML (Dev) и эксплуатацию ML-систем (Ops). Для архитектора это аналог DevOps, но с учетом специфики жизненного цикла модели.

Без MLOps рано или поздно наступает "технический долг ML": модели, которые невозможно воспроизвести, данные, которые потеряли актуальность, и ручное переобучение "на коленке".

### 2.1. Конвейер CI/CD/CT

Классический CI/CD расширяется до CI/CD/CT (Continuous Training):

* **CI (Continuous Integration):** Проверяем не только код, но и данные и модели. Включает тестирование валидности данных (data validation), тестирование качества модели (model evaluation) на тестовых выборках.
* **CD (Continuous Delivery):** Автоматическая деплоймент обученной модели в staging/production среду как микросервис.
* **CT (Continuous Training):** Автоматическое переобучение модели при появлении новых данных или изменении бизнес-метрик. Это сердце MLOps.

### 2.2. Ключевые компоненты архитектуры MLOps

Чтобы обеспечить CI/CD/CT, в инфраструктуру добавляются новые компоненты:

* **Feature Store (Хранилище признаков):** Слой абстракции между сырыми данными и моделью. Он позволяет переиспользовать одни и те же признаки (фичи) для обучения и для инференса, гарантируя их консистентность. Например, "средний чек клиента за последние 7 дней" вычисляется одинаково в момент обучения модели и в момент предсказания для реального пользователя.
* **Model Registry (Реестр моделей):** Каталог версий моделей с метаданными (кто обучил, на каких данных, качество на тестах). Здесь происходит переход модели из статуса "экспериментальная" в "production-ready".
* **Metadata Store:** База данных, хранящая логи каждого эксперимента: гиперпараметры, датасеты, метрики. Необходим для воспроизводимости и аудита.
* **Model Serving (Подача модели):** Инфраструктура для запуска инференса.

### 2.3. Паттерны Serving'а

1. **Микросервис с REST/gRPC API:**
    * *Как это работает:* Модель загружена в память веб-сервера (например, FastAPI, TensorFlow Serving, TorchServe). Получаем запрос -> передаем в модель -> возвращаем ответ.
    * *Плюсы:* Низкая задержка (latency), простота интеграции.
    * *Минусы:* Сложность горизонтального масштабирования (нужно синхронизировать состояние моделей), модель потребляет память постоянно.
2. **Serverless (Lambda Functions, Cloud Run):**
    * *Как это работает:* Функция поднимается по запросу, загружает модель из удаленного хранилища (S3) и делает предсказание.
    * *Плюсы:* Масштабируется до нуля, экономия на простаивающих ресурсах.
    * *Минусы:* Холодный старт (загрузка модели может занимать секунды), ограничение по времени выполнения и памяти.
3. **Пакетный (Batch) инференс:**
    * *Как это работает:* Запуск Spark или MapReduce задачи для обработки терабайтов данных раз в сутки/неделю. Результаты складываются в базу данных (например, рекомендации на завтра для всех пользователей).
    * *Плюсы:* Эффективность для больших объемов, простота мониторинга.
    * *Минусы:* Не подходит для онлайн-сценариев (чат-боты).

---

## 3. Архитектура диалоговых систем

Диалоговые системы (чат-боты, голосовые ассистенты) — классический пример сложного ML-приложения, объединяющего несколько моделей в один конвейер.

Архитектура таких систем эволюционировала от жестких деревьев решений до гибких нейросетевых подходов. Рассмотрим классическую NLU-архитектуру.

### 3.1. Классическая pipeline-архитектура (NLU/NLP)

Большинство промышленных чат-ботов (в поддержке, банкинге) строятся как конвейер из нескольких модулей:

1. **Speech-to-Text (STT) / Input Normalization:** Если вход голосовой, он переводится в текст. Также здесь происходит орфография, приведение к нижнему регистру.
2. **Language Detection:** Определение языка запроса.
3. **Intent Classification (Классификация намерений):** Модель (часто BERT-подобная или логистическая регрессия) относит текст к одному из заранее определенных классов: "Заказать пиццу", "Узнать баланс", "Пожаловаться на оператора". Это ответ на вопрос *"Что хочет пользователь?"*.
4. **Entity Extraction (Извлечение сущностей):** Из текста вытаскиваются параметры (слоты). Например, для намерения "Заказать пиццу" нужно извлечь сущности: "тип пиццы" (Маргарита), "размер" (30 см), "адрес".
5. **Dialog Management (Менеджер диалога):** Конечный автомат или нейросеть, который хранит контекст. Если пользователь не назвал сущность "размер", бот должен переспросить: "Какой размер пиццы вас интересует?".
6. **Response Generation / Action Execution:** Выполнение бизнес-логики (вызов API пиццерии) и генерация ответа пользователю.

**Недостаток:** Ошибка на раннем этапе (например, в классификации интента) убивает весь дальнейший диалог.

### 3.2. Сквозные нейросетевые модели (End-to-End)

Современные LLM (Large Language Models) позволяют строить диалоговые системы без жестко заданного конвейера.

* *Принцип:* Одна большая модель (например, GPT или LLaMA) получает историю диалога и текущий запрос и сразу генерирует ответ.
* *Плюсы:* Лучше понимает контекст, умеет вести свободный диалог.
* *Минусы:* Сложность контроля (может ответить то, чего не должна), высокие требования к железу, сложность интеграции с внешним API (модель сама должна решить, когда вызвать функцию).

### 3.3. Гибридный подход

На практике в enterprise-архитектурах часто используется гибрид:

* LLM используется для понимания контекста и перефразирования.
* Классические NLU-модели используются для жесткой классификации (например, "перевести деньги" — критически важный интент, ошибки быть не должно).
* Оркестратор управляет потоком, решая, какому компоненту доверить обработку.

---

## 4. RAG (Retrieval-Augmented Generation)

RAG — это архитектурный паттерн, ставший стандартом *де-факто* для создания приложений на базе LLM, которым необходимо взаимодействовать с приватными или актуальными данными (документация компании, база знаний, новости).

### 4.1. Проблема, которую решает RAG

LLM обучены на публичных данных и "заморожены" во времени. Они:

1. Не знают ваших внутренних документов.
2. Могут "галлюцинировать" (выдумывать факты), когда не знают ответа.
3. Трудно обновляются (дообучение/дообучение (fine-tuning) дорого и долго).

### 4.2. Компоненты архитектуры RAG

RAG решает эту проблему, добавляя в систему компонент поиска (Retriever). Процесс состоит из двух этапов: **Индексация** и **Генерация**.

**Этап 1: Индексация (Offline/Background)**

1. **Загрузка документов:** Документы (PDF, Word, Confluence) загружаются в систему.
2. **Chunking (Разбиение):** Документы нарезаются на небольшие фрагменты (чанки). Это необходимо, так как LLM имеют ограниченный контекст, и нам нужно искать релевантные куски, а не весь документ целиком.
3. **Embedding (Векторизация):** Каждый чанк прогоняется через специальную модель-энкодер (Embedding Model), которая превращает текст в вектор чисел (эмбеддинг) — координаты в многомерном пространстве. Смысл в том, что близкие по смыслу тексты в этом пространстве находятся рядом.
4. **Хранение в Vector Database:** Векторы и исходный текст сохраняются в векторной базе данных (Pinecone, Qdrant, Milvus, pgvector для PostgreSQL).

**Этап 2: Генерация (Online/Inference)**

1. **Запрос пользователя:** Приходит вопрос: "Какая политика компании по удаленной работе?".
2. **Embedding запроса:** Тот же самый энкодер превращает вопрос пользователя в вектор.
3. **Поиск (Similarity Search):** Вектор запроса используется для поиска в Vector Database K наиболее близких векторов (чанков) — алгоритм KNN (k ближайших соседей) или ANN (приближенный).
4. **Добавление в контекст (Augmentation):** Найденные текстовые чанки вставляются в промпт к LLM как контекст.
5. **Генерация ответа:** LLM получает промпт вида: "Ответь на вопрос, используя только следующий контекст: ... Вопрос: ...". LLM генерирует ответ, опираясь исключительно на предоставленные данные.

### 4.3. Архитектурные соображения

* **Выбор чанка (Chunking strategy):** Размер чанка и стратегия (по предложениям, по абзацам, рекурсивное) критически влияют на качество. Слишком мелко — потеря контекста, слишком крупно — шум.
* **Метаданные (Metadata filtering):** Векторные БД позволяют хранить метаданные (дата документа, автор, тема). Перед векторным поиском можно отфильтровать документы по дате, чтобы искать только в актуальных.
* **Ранжирование (Re-ranking):** После первичного поиска можно использовать более тяжелую модель Re-ranker, чтобы заново оценить релевантность найденных чанков и отсортировать их заново.

---

## 5. Распознавание намерений (Intent Recognition)

Это, пожалуй, самый распространенный и важный компонент для бизнес-приложений. Любая система автоматизации клиентского сервиса начинается с вопроса: "Что хочет клиент?".

### 5.1. Архитектурные подходы к Intent Recognition

**1. Классический ML (TF-IDF + LogReg / SVM):**

* *Как работает:* Текст превращается в мешок слов с весами TF-IDF. Эти разреженные вектора подаются в классификатор (логистическая регрессия).
* *Плюсы:* Очень быстро, дешево, интерпретируемо. Работает отлично для небольшого числа интентов (до 50-100).
* *Минусы:* Не понимает контекст и синонимию ("хочу купить машину" vs "желаю приобрести авто").

**2. Трансформеры (BERT и семейство):**

* *Как работает:* Используются предобученные модели типа RuBERT, LaBSE. Текст токенизируется (разбивается на подслова), прогоняется через сеть трансформера, и специальный токен [CLS] на выходе подается в классификатор (head).
* *Плюсы:* Глубокое понимание контекста, учет порядка слов, отличная работа с синонимией. Лучший выбор для сложных диалогов.
* *Минусы:* Требует GPU для обучения и инференса (хотя есть оптимизированные версии типа DistilBERT). Медленнее классики.

**3. LLM и Few-Shot Learning:**

* *Как работает:* В промпт к LLM загружается описание интентов и несколько примеров. LLM должна вернуть JSON с названием интента.
* *Плюсы:* Не требует обучения на тонной разметке. Можно быстро добавить новый интент, просто описав его в промпте.
* *Минусы:* Неконтролируемая задержка, дороговизна (если использовать внешние API), риск, что модель перепутает интенты или придумает свой.

### 5.2. Out-of-Scope (OOS) Detection

Критическая проблема для продакшна. Модель классификации всегда выберет один из классов, даже если пользователь спросит "А как приготовить борщ?" в банковском боте.

* **Решение:** Использование порогов уверенности (confidence threshold) или обучение отдельного бинарного классификатора на специальных OOS-примерах.

### 5.3. Интеграция с системой

Для архитектора важно, что Intent Recognition — это "тонкий" микросервис (обычно без состояния), который может кэшировать результаты для часто задаваемых вопросов. Он должен отдавать не только имя интента, но и **скор (уверенность)** и **альтернативные варианты** на случай, если оркестратор захочет переспросить пользователя.

---

## Заключение

Проектирование ML-приложений требует нового мышления. Мы переходим от мира жесткой логики к миру вероятностей и данных. Для успешной архитектуры сегодня критически важно:

1. **Принять недетерминизм:** Планировать отказоустойчивость с учетом того, что модель может ошибиться.
2. **Инвестировать в MLOps:** Без автоматизации конвейеров данных и моделей поддержание ML-систем в рабочем состоянии становится невозможным по мере их роста.
3. **Разделять ответственность:** Feature Store — за фичи, Model Registry — за модели, Vector DB — за знания.
4. **Выбирать правильный паттерн:** Не пытаться засунуть LLM туда, где хватит TF-IDF, и наоборот. RAG — это не "игрушка", а стандарт промышленной работы с документами.

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