Разработка, развёртывание и поддержка моделей машинного обучения в продакшене может быть сложной и трудоёмкой задачей. Именно здесь на помощь приходит Machine Learning Operations (MLOps). MLOps — это набор практик, который автоматизирует управление ML-процессами и упрощает развёртывание моделей.
В этой статье я расскажу о некоторых основных практиках и инструментах MLOps на примере реализации проекта от начала до конца. Это поможет вам эффективнее управлять ML-проектами, начиная с разработки и заканчивая мониторингом в продакшене.
Прочитав эту статью, вы узнаете:
- Как использовать DVC для версионирования данных.
- Как отслеживать логи, артефакты и регистрировать версии моделей с помощью MLflow.
- Как развернуть модель с помощью FastAPI, Docker и AWS ECS.
- Как отслеживать модель в продакшене с помощью Evidently AI.
Оглавление:
- Что такое MLOps?
- Настройка проекта
- Обучение модели
- Data Version Control (DVC)
- MLflow
- Makefile
- Config.yml
- FastAPI
- Docker
- AWS ECS
- Evidently AI
- Заключение и ссылки
Что такое MLOps?
MLOps — это набор методов и практик, направленных на упрощение и автоматизацию жизненного цикла систем машинного обучения. Цель MLOps — повысить эффективность и надёжность развёртывания ML-моделей в продакшене. MLOps устраняет разрыв между разработкой ML-моделей и их эксплуатацией, обеспечивая возможность их устойчивого и эффективного внедрения, управления и мониторинга в реальных условиях. Этот подход снижает риски ошибок при проектировании системы, способствуя более устойчивым и точным предсказаниям в реальной среде.Изображение создано автором
Зачем нам нужен MLOps?
Обычно любой ML-проект начинается с определения бизнес-задачи. После того, как задача определена, выполняются этапы извлечения данных, подготовки данных, создания признаков и обучения модели. Завершённая модель сохраняется в хранилище или системе управления версиями, чтобы инженерные и операционные команды могли её развернуть в продакшен-среде.
Что не так с этим подходом?
Такой подход создаёт разрыв между этапами разработки и развёртывания, что приводит к неэффективности и потенциальным ошибкам. Отсутствие тесного сотрудничества между дата-сайентистами и инженерами может привести к разработке моделей, которые недостаточно оптимизированы для продакшена, что в свою очередь может вызвать проблемы — такие как снижение производительности, трудности с масштабируемостью и поддержкой.
MLOps решает эти проблемы, создавая единый рабочий процесс, который объединяет разработку и эксплуатацию. Это гарантирует, что модели будут надёжными, масштабируемыми и проще в поддержке. Такой подход снижает риск ошибок, ускоряет развёртывание и поддерживает эффективность моделей за счёт непрерывного мониторинга их работы в продакшене.
Теперь, когда у нас есть базовое понимание MLOps, перейдём к части реализации.
Настройка проекта
Проект по машинному обучению требует стандартной структуры, чтобы его можно было легко поддерживать и модифицировать. Хорошо организованная структура проекта позволяет участникам команды сотрудничать эффективно и просто.В данном проекте мы используем базовую структуру, которая поможет управлять всем жизненным циклом ML-проекта, включая сбор данных, предобработку, обучение модели, её оценку, развёртывание и мониторинг.
Для начала клонируйте репозиторий mlops-project с GitHub и следуйте инструкциям.
# клонируем репозиторий с GitHub
git clone https://github.com/prsdm/mlops-project.git
После клонирования структура проекта будет выглядеть примерно так:
.
├── .github # Метаданные и конфигурация DVC
│ └── workflows # GitHub Actions Workflows для CI/CD
│ └── docs.yml
├── data # Директория для хранения файлов данных
│ ├── train.csv
│ └── test.csv
├── docs # Документация проекта
│ └── index.md
├── models # Хранение обученных моделей
├── mlruns # Директория для логов запусков и артефактов MLflow
├── steps # Исходный код для обработки данных и обучения модели
│ ├── __init__.py
│ ├── ingest.py
│ ├── clean.py
│ ├── train.py
│ └── predict.py
├── tests # Директория для хранения тестов
│ ├── __init__.py
│ ├── test_ingest.py
│ └── test_clean.py
├── .gitignore # Игнорировать файлы, которые не нужно коммитить в Git
├── app.py # Файл приложения FastAPI
├── config.yml # Конфигурационный файл
├── data.dvc # Для отслеживания файлов данных и их версий
├── dataset.py # Скрипт для загрузки или генерации данных
├── dockerfile # Dockerfile для контейнеризации FastAPI
├── LICENSE # Лицензия на проект
├── main.py # Автоматизация обучения модели
├── Makefile # Хранение полезных команд, например make train или make test
├── mkdocs.yml # Конфигурационный файл для MkDocs
├── README.md # Описание проекта
├── requirements.txt # Файл зависимостей для воспроизведения окружения
├── samples.json # Пример данных для тестирования
'''Дополнительные файлы для мониторинга'''
├── data
│ └──production.csv # Данные для мониторинга
├── monitor.ipynb # Ноутбук для мониторинга модели
├── test_data.html # Результаты мониторинга для тестовых данных
└── production_data.html # Результаты мониторинга для данных в продакшене
Разбор структуры:
- data: Хранит файлы данных, используемые для обучения и оценки модели.
- docs: Содержит документацию проекта.
- models: Хранит обученные ML-модели.
- mlruns: Содержит логи и артефакты, созданные MLflow.
- steps: Включает исходный код для загрузки данных, их очистки и обучения модели.
- tests: Включает юнит-тесты для проверки работоспособности кода.
- app.py: Содержит код FastAPI приложения для развёртывания модели.
- config.yml: Конфигурационный файл для хранения параметров проекта и путей к ресурсам.
- data.dvc: Отслеживает версии файлов данных с помощью DVC (Data Version Control, система управления версиями данных).
- dataset.py: Скрипт для скачивания или генерации данных.
- dockerfile: Используется для сборки Docker-образа для контейнеризации FastAPI приложения.
- main.py: Автоматизирует процесс обучения модели.
- Makefile: Содержит команды для автоматизации задач, таких как обучение или тестирование.
- mkdocs.yml: Конфигурационный файл для MkDocs, который используется для генерации документации проекта.
- requirements.txt: Содержит все необходимые пакеты для проекта.
- samples.json: Содержит пример данных для тестирования.
- monitor.ipynb: Jupyter Notebook для мониторинга производительности модели.
- production_data.html и test_data.html: Хранят результаты мониторинга для тестовых и продуктивных данных.
Теперь давайте создадим виртуальное окружение и активируем его, используя следующие команды:
Для bash:
# создать виртуальное окружение
python3 -m venv venv
# активировать
source venv/bin/activate
Для cmd:
# создать виртуальное окружение
python -m venv venv
# активировать
.\venv\Scripts\activate
Затем установим все необходимые пакеты с помощью файла requirements.txt.
# установить все зависимости
pip install -r requirements.txt
Пример:
Пример настройки проекта. Полную версию GIF можно посмотреть по ссылке
После настройки окружения и установки зависимостей можно переходить к этапу обучения модели.
Обучение модели
На первом этапе обучения модели необходимо получить данные из источника, который может находиться как в локальном хранилище, так и в удалённом. Для этого запустите файл dataset.py.# для получения данных из источника# для получения данных из источника
python3 dataset.py
Этот скрипт извлекает данные из источника, разделяет их на обучающий и тестовый датасеты, а затем сохраняет их в директорию data/.
Пример:
Пример извлечения данных
После того как данные будут сохранены в директорию data, следующие шаги включают их очистку, обработку и обучение модели. Папка steps/ содержит модули для каждого из этих этапов.
# часть обучения модели из структуры проекта
├── steps/
│ ├── ingest.py
│ ├── clean.py
│ ├── train.py
│ └── predict.py
├── main.py
├── models/model.pkl
Рассмотрим, что делает каждый файл:
- ingestion.py — обрабатывает начальное извлечение данных, гарантируя, что данные правильно загружены и доступны для последующих этапов обработки.
- clean.py — выполняет базовые задачи очистки и предобработки данных, такие как обработка пропущенных значений, удаление дублей и улучшение качества данных.
- train.py — обучает модель на очищенных данных и сохраняет её как model.pkl в директории models/ для дальнейшего использования.
- predict.py — используется для оценки производительности модели на тестовых данных с использованием обученной модели.
Чтобы выполнить все эти шаги последовательно, запустите файл main.py:
# для обучения модели
python3 main.py
Вот как выглядит файл main.py в этом проекте:
import logging
from steps.ingest import Ingestion
from steps.clean import Cleaner
from steps.train import Trainer
from steps.predict import Predictor
# Настройка логирования
logging.basicConfig(level=logging.INFO,format='%(asctime)s:%(levelname)s:%(message)s')
def main():
# Загрузка данных
ingestion = Ingestion()
train, test = ingestion.load_data()
logging.info("Загрузка данных завершена успешно")
# Очистка данных
cleaner = Cleaner()
train_data = cleaner.clean_data(train)
test_data = cleaner.clean_data(test)
logging.info("Очистка данных завершена успешно")
# Подготовка и обучение модели
trainer = Trainer()
X_train, y_train = trainer.feature_target_separator(train_data)
trainer.train_model(X_train, y_train)
trainer.save_model()
logging.info("Обучение модели завершено успешно")
# Оценка модели
predictor = Predictor()
X_test, y_test = predictor.feature_target_separator(test_data)
accuracy, class_report, roc_auc_score = predictor.evaluate_model(X_test, y_test)
logging.info("Оценка модели завершена успешно")
# Вывод результатов оценки
print("\n============= Результаты оценки модели ==============")
print(f"Модель: {trainer.model_name}")
print(f"Точность: {accuracy:.4f}, ROC AUC: {roc_auc_score:.4f}")
print(f"\n{class_report}")
print("=====================================================\n")
if __name__ == "__main__":
main()
Пример:
Пример обучения модели
Теперь давайте рассмотрим, как можно улучшить этот проект с помощью таких инструментов, как DVC и MLflow.
Data Version Control (DVC)
Начнём с Data Version Control (DVC) — бесплатного инструмента с открытым исходным кодом, предназначенного для управления большими датасетами, автоматизации ML-пайплайнов и обработки экспериментов. Этот инструмент помогает DS и ML командам более эффективно управлять данными, обеспечивать воспроизводимость и улучшать совместную работу.Почему стоит выбрать DVC, а не GitHub?
Git отлично подходит для версионирования исходного кода и текстовых файлов, но имеет ограничения при работе с большими бинарными файлами, такими как наборы данных. Git сохраняет новые версии бинарных файлов как отдельные копии, не показывая подробные различия между ними, что затрудняет отслеживание изменений с течением времени. Кроме того, хранение больших датасетов или конфиденциальной информации в GitHub не всегда оптимально, так как это может привести к разрастанию репозитория и потенциальным рискам безопасности.DVC решает эти проблемы, управляя большими файлами через метаданные и внешние хранилища (например, S3, Google Cloud Storage или Azure Blob Storage), при этом отслеживая изменения данных и историю версий. DVC использует человекочитаемые метафайлы, которые хранятся в Git и содержат информацию о состоянии данных, что позволяет версионировать и передавать данные без добавления самих файлов в репозиторий. Кроме того, DVC обеспечивает безопасную совместную работу, обеспечивая контроль доступа к компонентам проекта и предоставляя возможность делиться ими с конкретными командами и пользователями.
Чтобы начать работу с DVC, сначала установите его (если он еще не установлен):
# установка DVC через pip
pip install dvc
Затем инициализируйте DVC:
# инициализировать DVCdvc init
Это создаст необходимые конфигурационные файлы DVC.
Теперь добавьте файлы данных в DVC:
# добавляем данные
dvc add data
Это позволит отслеживать файлы данных с помощью DVC, при этом сами данные будут храниться во внешнем хранилище.
Настройка удалённого хранилища:
# добавить конфигурацию удалённого хранилищаdvc remote add -d <remote_name> <remote_storage_path>
Замените <remote_name> на название удалённого хранилища, а <remote_storage_path> на путь к удалённому хранилищу (например, s3://mybucket/mydata).
Загрузка данных в удалённое хранилище:
# зафиксировать изменения конфигурации DVC в Gitgit commit .dvc/config -m 'config dvc store'
# загрузить данные в настроенное удалённое хранилище
dvc push
Эта команда загружает данные в настроенное удалённое хранилище.
Отправка всех зафиксированных изменений в git:
# отправить все зафиксированные изменения в Git-репозиторий
git push origin main
Пример:
Пример DVC push. Полную версию GIF можно посмотреть по ссылке.
Чтобы загрузить последнюю версию данных из удалённого хранилища в локальную директорию, используйте следующую команду:
# получить последнюю версию данных
dvc pull
Пример:
Пример DVC pull. Полную версию GIF можно посмотреть по ссылке
С помощью интеграции DVC можно эффективно управлять большими наборами данных, разгружая Git-репозиторий и сосредоточив его на исходном коде проекта.
Примечание: DVC можно использовать для версионирования моделей так же, как и для данных.
MLflow
После версионирования данных с помощью DVC крайне важно организовать чёткий учёт всех этапов обучения моделей, изменений версий и параметров, даже если вы не проводите активные эксперименты с разными моделями.Без системного отслеживания могут возникнуть следующие проблемы:
- Потеря деталей версий: Без учёта параметров и изменений кода для каждой версии модели становится сложно воспроизвести прошлые результаты или продолжить работу с предыдущих версий. Это может замедлить прогресс и привести к повторению ошибок.
- Трудности с сравнением версий: Регулярная фиксация результатов каждой модели помогает сравнивать разные версии. Без этого трудно понять, улучшается ли модель или нет.
- Проблемы с командной работой: В команде отсутствие ясного управления версиями моделей может привести к путанице и случайным перезаписям, что усложняет совместную работу.
Чтобы интегрировать MLflow, сначала установите MLflow (если он ещё не установлен):
# установить mlflow
pip install mlflow
Затем обновите файл main.py, чтобы добавить логирование параметров, метрик и моделей. Код будет выглядеть примерно так:
import logging
import yaml
import mlflow
import mlflow.sklearn
from steps.ingest import Ingestion
from steps.clean import Cleaner
from steps.train import Trainer
from steps.predict import Predictor
from sklearn.metrics import classification_report
# Настройка логирования
logging.basicConfig(level=logging.INFO,format='%(asctime)s:%(levelname)s:%(message)s')
def main():
with open('config.yml', 'r') as file:
config = yaml.safe_load(file)
mlflow.set_experiment("Model Training Experiment")
with mlflow.start_run() as run:
# Загрузка данных
ingestion = Ingestion()
train, test = ingestion.load_data()
logging.info("Загрузка данных завершена успешно")
# Очистка данных
cleaner = Cleaner()
train_data = cleaner.clean_data(train)
test_data = cleaner.clean_data(test)
logging.info("Очистка данных завершена успешно")
# Подготовка и обучение модели
trainer = Trainer()
X_train, y_train = trainer.feature_target_separator(train_data)
trainer.train_model(X_train, y_train)
trainer.save_model()
logging.info("Обучение модели завершено успешно")
# Оценка модели
predictor = Predictor()
X_test, y_test = predictor.feature_target_separator(test_data)
accuracy, class_report, roc_auc_score = predictor.evaluate_model(X_test, y_test)
report = classification_report(y_test, trainer.pipeline.predict(X_test), output_dict=True)
logging.info("Оценка модели завершена успешно")
# Теги
mlflow.set_tag('Model developer', 'prsdm')
mlflow.set_tag('preprocessing', 'OneHotEncoder, Standard Scaler, and MinMax Scaler')
# Логирование метрик
model_params = config['model']['params']
mlflow.log_params(model_params)
mlflow.log_metric("accuracy", accuracy)
mlflow.log_metric("roc", roc_auc_score)
mlflow.log_metric('precision', report['weighted avg']['precision'])
mlflow.log_metric('recall', report['weighted avg']['recall'])
mlflow.sklearn.log_model(trainer.pipeline, "model")
# Регистрация модели
model_name = "insurance_model"
model_uri = f"runs:/{run.info.run_id}/model"
mlflow.register_model(model_uri, model_name)
logging.info("Отслеживание в MLflow завершено успешно")
# Вывод результатов оценки
print("\n============= Результаты оценки модели ==============")
print(f"Модель: {trainer.model_name}")
print(f"Точность: {accuracy:.4f}, ROC AUC: {roc_auc_score:.4f}")
print(f"\n{class_report}")
print("=====================================================\n")
if __name__ == "__main__":
main()
После этого запустите скрипт main.py и просмотрите детали эксперимента, используя следующую команду:
# запуск MLflow UI
mlflow ui
Откройте URL http://127.0.0.1:5000 в браузере, чтобы изучить и сравнить залогированные параметры, метрики и модели.
Пример:
Пример отслеживания MLflow
Пример сравнения моделей в MLflow
С помощью MLflow можно легко отслеживать версии моделей и управлять изменениями, обеспечивая воспроизводимость и возможность выбора наиболее эффективной модели для развёртывания.
Прежде чем перейти к этапу развёртывания, давайте взглянем на файлы Makefile и config.yml, которые есть в проекте. Эти файлы помогают упростить рабочий процесс и гарантируют согласованность в настройке и конфигурации проекта.
Makefile
Использование Makefile в Python-проектах может значительно упростить управление задачами. Многие дата-сайентисты и ML-инженеры не осознают, что make позволяет автоматизировать рутинные операции, такие как настройка окружения, установка зависимостей, обучение модели, запуск тестов и очистка файлов. Это экономит время и снижает вероятность ошибок. Makefile широко используется в разработке ПО, потому что помогает управлять длинными и сложными командами, которые сложно запомнить.Makefile в этом проекте выглядит примерно так:
bash:
python = venv/bin/python
pip = venv/bin/pip
setup:
python3 -m venv venv
$(python) -m pip install --upgrade pip
$(pip) install -r requirements.txt
run:
$(python) main.py
mlflow:
venv/bin/mlflow ui
test:
$(python) -m pytest
clean:
rm -rf steps/__pycache__
rm -rf __pycache__
rm -rf .pytest_cache
rm -rf tests/__pycache__
remove:
rm -rf venv
Для Windows (cmd) файл необходимо немного изменить.
python = venv/Scripts/python
pip = venv/Scripts/pip
setup:
python -m venv venv
$(python) -m pip install --upgrade pip
$(pip) install -r requirements.txt
run:
$(python) main.py
mlflow:
venv/Scripts/mlflow ui
test:
$(python) -m pytest
clean:
@if exist steps\__pycache__ (rmdir /s /q steps\__pycache__)
@if exist __pycache__ (rmdir /s /q __pycache__)
@if exist .pytest_cache (rmdir /s /q .pytest_cache)
@if exist tests\__pycache__ (rmdir /s /q tests\__pycache__)
remove:
@if exist venv (rmdir /s /q venv)
Разбор каждой части:
- make setup: Создаёт виртуальное окружение (venv), обновляет pip и устанавливает необходимые пакеты из файла requirements.txt, обеспечивая совместимость всех зависимостей в разных средах.
- make run: Запускает скрипт main.py с помощью интерпретатора Python из виртуального окружения.
- make mlflow: Запускает mlflow ui для отслеживания экспериментов и метрик моделей.
- make test: Выполняет все тесты, определённые в проекте, с использованием pytest.
- make clean: Удаляет временные файлы, такие как __pycache__, .pytest_cache и другие, чтобы поддерживать чистоту директории.
- make remove: Полностью удаляет виртуальное окружение (venv) из проекта.
# Например, для настройки окружения
make setup
# ИЛИ для запуска основного скрипта
make run
# ИЛИ для запуска тестов
make test
# и так далее...
Пример:
Пример использования команд Make
С помощью Makefile можно автоматизировать и оптимизировать выполнение различных задач, что способствует согласованности и снижает количество ошибок при работе в разных средах.
Config.yml
Файлы YAML — удобный способ хранения и управления конфигурационными настройками для ML-моделей. Они позволяют централизованно управлять путями к данным и моделям, параметрами моделей и другими конфигурациями, что упрощает эксперименты с различными настройками и обеспечивает переиспользуемость кода.Файл Config.yml выглядит примерно так:
data:
train_path: data/train.csv
test_path: data/test.csv
train:
test_size: 0.2
random_state: 42
shuffle: true
model:
name: DecisionTreeClassifier
params:
criterion: entropy
max_depth: null
store_path: models/
# name: GradientBoostingClassifier
# params:
# max_depth: null
# n_estimators: 10
# store_path: models/
# name: RandomForestClassifier
# params:
# n_estimators: 50
# max_depth: 10
# random_state: 42
# store_path: models/
Вот что делает каждая часть:
- data: Указывает пути к обучающим, тестовым и продуктивным (последним) датасетам. Это позволяет централизованно управлять расположением данных и легко обновлять их.
- train: Содержит параметры для разделения данных на обучающие и тестовые наборы, такие как test_size (размер тестового набора), random_state (начальное значение для генерации случайных чисел) и параметр shuffle (перемешивание данных). Эти настройки помогают поддерживать согласованность при разделении данных и обеспечивают воспроизводимость.
- model: Определяет имя модели, её параметры и путь для сохранения обученной модели. Такая конфигурация позволяет легко переключаться между разными моделями, обеспечивая гибкость в выборе моделей.
Пример:
В следующем примере модель изменена на ‘GradientBoostingClassifier’ на основе настроек, указанных в файле config.yml.
Пример файла config.yml
Теперь перейдём к этапу развёртывания, где будут использованы FastAPI, Docker и AWS ECS. Эта настройка поможет создать масштабируемое и легко управляемое приложение для обслуживания ML-модели.
FastAPI
FastAPI — это современный фреймворк для создания API с использованием Python, который отлично подходит для обслуживания ML-моделей благодаря своей скорости и простоте.Для начала установите FastAPI и Uvicorn (если они ещё не установлены):
# установка fastapi и uvicorn
pip install fastapi uvicorn
Определите приложение FastAPI и конечные точки для обслуживания модели в файле app.py.
from fastapi import FastAPI
from pydantic import BaseModel
import pandas as pd
import joblib
app = FastAPI()
class InputData(BaseModel):
Gender: str
Age: int
HasDrivingLicense: int
RegionID: float
Switch: int
PastAccident: str
AnnualPremium: float
model = joblib.load('models/model.pkl')
@app.get("/")
async def read_root():
return {"health_check": "OK", "model_version": 1}
@app.post("/predict")
async def predict(input_data: InputData):
df = pd.DataFrame([input_data.model_dump().values()],
columns=input_data.model_dump().keys())
pred = model.predict(df)
return {"predicted_class": int(pred[0])}
Затем протестируйте сервер FastAPI локально, открыв http://127.0.0.1:8000/docsusing и выполнив следующую команду:
# запустить приложение FastAPI
uvicorn app:app --reload
Пример:
Пример FastAPI
Теперь давайте контейнеризуем этот API с использованием Docker.
Docker
Docker — это платформа с открытым исходным кодом, которая упрощает развёртывание программных приложений, помещая их в контейнеры. Эти контейнеры — лёгкие и портативные единицы, содержащие всё необходимое для запуска приложения в различных средах.Зачем использовать контейнеры?
Контейнеры обеспечивают удобную изоляцию приложений и позволяют развёртывать их так, чтобы они работали одинаково в разных средах, будь то ноутбук разработчика или облако. Такая изоляция повышает переносимость и эффективность использования ресурсов, делая Docker важным инструментом в современном процессе разработки ПО.Для установки Docker следуйте инструкциям на официальном сайте Docker.
Теперь создайте файл Dockerfile в директории проекта для сборки Docker-образа:
# официальный образ Python 3.10
FROM python:3.10
# задать рабочую директорию
WORKDIR /app
# добавить app.py и директорию models
COPY app.py .
COPY models/ ./models/
# добавить файл зависимостей
COPY requirements.txt .
# установить библиотеки Python
RUN pip install --no-cache-dir -r requirements.txt
# указать команды по умолчанию
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]
Теперь создайте образ Docker с помощью следующей команды:
# Для сборки Docker-образа
docker build -t <image_name> <path_to_dockerfile>
Пример:
Пример сборки докера
Наконец, запустите контейнер Docker для тестирования API по адресу http://localhost:80/predict:
# Для запуска Docker-контейнера
docker run -d -p 80:80 <image_name>
Пример:
Пример запуска docker
Чтобы остановить запущенный контейнер Docker, найдите идентификатор или имя запущенного контейнера с помощью следующей команды:
# Показать запущенные контейнеры
docker ps
После определения идентификатора или имени контейнера его можно остановить с помощью следующей команды:
# Остановить контейнер
docker stop <container_id_or_name>
Пример:
Пример остановки запущенного контейнера
Теперь, чтобы загрузить образ Docker в Docker Hub, выполните следующие шаги:
- Выведите список всех Docker-образов в системе с их тегами, чтобы найти нужный образ для загрузки:
docker image ls
2. Присвойте образу тег, указав нужный репозиторий и имя:
# Задать тег изображению
docker tag <image_name> <dockerhub_username>/<docker-repo-name>
3. Загрузите образ с тегом в Docker Hub с помощью следующей команды:
# Загрузить Docker-образ
docker push <dockerhub_username>/<docker-repo-name>:latest
Эта команда загрузит образ в указанный репозиторий на Docker Hub.
Пример:
Пример команд Docker Push. Полную версию GIF можно посмотреть по ссылке
Пример репозитория Docker Hub
Теперь, когда образ Docker загружен в Docker Hub, он доступен для развёртывания в AWS Elastic Container Service (ECS).
AWS ECS
AWS ECS — это полностью управляемый сервис для оркестрации контейнеров, который позволяет легко запускать и масштабировать Docker-контейнеры на AWS. Он поддерживает запуск как на EC2, так и на Fargate. Вот пошаговое руководство:- Для начала создайте кластер ECS:
- Шаг 1: Войдите в свою учётную запись AWS, перейдите в сервис ECS и выберите «Создать кластер» (Create Cluster).
- Шаг 2: Дайте кластеру имя, выберите тип запуска AWS Fargate (без серверов) и нажмите «Создать» (Create). Это займёт несколько минут.
Пример кластера AWS
Затем определите Task Definition (определение задачи):
- Шаг 1: В консоли ECS перейдите в раздел «Task Definitions» и создайте новое определение задачи.
- Шаг 2: Присвойте задаче имя и настройте такие параметры, как требования к памяти и процессору.
- Шаг 3: В разделе «Container Definitions» укажите URL-адрес образа Docker из Docker Hub и оставьте настройки маппинга портов контейнера по умолчанию. Нажмите «Create» (создать).
Пример Task Definition
После этого добавьте Security Group (группу безопасности):
- Шаг 1: Перейдите в EC2, в разделе «Networks and Security» (Сети и безопасность) выберите «Security Groups» (Группы безопасности) и нажмите «Create Security Group» (Создать группу безопасности). Присвойте ей имя и описание.
- Шаг 2: В разделе «Inbound Rules» (Входящие правила) выберите тип HTTP и источник Anywhere-IPv4 Затем добавьте аналогичное правило для Anywhere-IPv6. Нажмите «Create Security Group» (Создать группу безопасности).
Пример AWS security Group
Затем создайте Service (службу):
- Шаг 1: Перейдите к созданному кластеру ECS и добавьте новую службу.
- Шаг 2: Выберите параметры вычислений типа запуска и тип запуска Fargate. Затем выберите ранее созданное определение задачи (Task definition) и укажите имя службы в настройках развёртывания.
- Шаг 3: Наконец, выберите созданную ранее группу безопасности в разделе «Networking» (сетевые настройки) и нажмите «Create» (создать). Процесс создания службы займет примерно 5–8 минут.
Пример сервисов
И наконец, доступ к запущенной службе:
После развёртывания службы откройте вкладку Services в вашем кластере ECS. Найдите нужную службу, перейдите во вкладку Tasks (Задачи) и выберите активную задачу. Используйте публичный IP-адрес задачи для подключения к приложению FastAPI. Это будет выглядеть примерно так:
Пример публичного IP
Пример развёрнутой службы
Следуя этим шагам, вы развернёте приложение FastAPI в Docker-контейнере на AWS ECS. Это обеспечивает масштабируемую и управляемую среду для обслуживания ML-модели.
Примечание: По необходимости можно добавить Elastic Load Balancing (ELB) для распределения нагрузки.
После успешного развертывания модели следующим шагом будет постоянный мониторинг её работы в продуктивной среде, чтобы убедиться, что она справляется с данными на продакшене. Мониторинг модели включает оценку различных факторов, таких как метрики сервера (например, использование CPU, потребление памяти, задержка), качество данных, data drift (смещение данных), target drift (смещение целевой переменной), concept drift (изменение концепции), производственные метрики и т.д.
Для простоты сосредоточимся на нескольких методах мониторинга, таких как data drift, target drift и качество данных, с использованием инструмента Evidently AI.
Evidently AI
Evidently AI — это отличный инструмент для мониторинга производительности моделей, обнаружения смещений данных (data drift) и оценки качества данных с течением времени. Он помогает гарантировать, что модель остаётся точной и надёжной при поступлении новых данных. Evidently AI предоставляет подробные отчёты о том, как меняется производительность модели, и выявляет значительные сдвиги в распределении данных, что критически важно для поддержания точности модели в продакшене.Для установки Evidently AI используйте следующую команду:
# для установки
pip install evidently
# или
pip install evidently @ git+https://github.com/evidentlyai/evidently.git
Затем запустите файл monitor.ipynb, чтобы обнаружить возможные проблемы с качеством данных, а также смещения данных (data drift) и целевых переменных (target drift). Файл выглядит примерно так:
# Если этот .py файл не работает, используйте ноутбук для его запуска.
import joblib
import pandas as pd
from steps.clean import Cleaner
from evidently.report import Report
from evidently.metric_preset import DataDriftPreset, DataQualityPreset, TargetDriftPreset
from evidently import ColumnMapping
import warnings
warnings.filterwarnings("ignore")
# # импортировать версию модели 1 из mlflow
# import mlflow
# logged_model = 'runs:/47b6b506fd2849429ee13576aef4a852/model'
# model = mlflow.pyfunc.load_model(logged_model)
# # ИЛИ импортировать из models/
model = joblib.load('models/model.pkl')
# Загрузка данных
reference = pd.read_csv("data/train.csv")
current = pd.read_csv("data/test.csv")
production = pd.read_csv("data/production.csv")
# Очистка данных
cleaner = Cleaner()
reference = cleaner.clean_data(reference)
reference['prediction'] = model.predict(reference.iloc[:, :-1])
current = cleaner.clean_data(current)
current['prediction'] = model.predict(current.iloc[:, :-1])
production = cleaner.clean_data(production)
production['prediction'] = model.predict(production.iloc[:, :-1])
# Применить отображение столбцов
target = 'Result'
prediction = 'prediction'
numerical_features = ['Age', 'AnnualPremium', 'HasDrivingLicense', 'RegionID', 'Switch']
categorical_features = ['Gender','PastAccident']
column_mapping = ColumnMapping()
column_mapping.target = target
column_mapping.prediction = prediction
column_mapping.numerical_features = numerical_features
column_mapping.categorical_features = categorical_features
# Часть обнаружения дрейфа данных
data_drift_report = Report(metrics=[
DataDriftPreset(),
DataQualityPreset(),
TargetDriftPreset()
])
data_drift_report.run(reference_data=reference, current_data=current, column_mapping=column_mapping)
data_drift_report
# data_drift_report.json()
data_drift_report.save_html("test_drift.html")
Пример тестовых данных:
Пример обнаружения качества и смещения тестовых данных
Пример продуктивных данных:
Пример обнаружения качества и смещения продуктивных данных
Запускайте скрипт мониторинга регулярно на поступающих данных, чтобы генерировать отчёты о смещениях данных и производительности модели. Эти отчёты помогут вовремя повторно обучить модель и гарантировать её точность и надёжность в долгосрочной перспективе.
С этим шагом мы успешно завершили реализацию проекта MLOps.
Заключение
В этой статье мы рассмотрели основные практики и инструменты MLOps через практический проект. Мы версионировали данные с помощью DVC, отслеживали и регистрировали модели с использованием MLflow, а также развернули модель с помощью FastAPI, Docker и AWS ECS. Кроме того, мы настроили мониторинг модели (качество данных, смещение данных и целевых переменных) с помощью Evidently AI. Эти шаги создают прочную основу для управления ML-проектами с использованием инструментов и практик MLOps — от разработки до продакшена. По мере накопления опыта с этими инструментами и методами можно исследовать более продвинутые методы автоматизации и оркестрации для улучшения рабочих процессов MLOps.Полезные ссылки:
- Операции машинного обучения (MLOps): Обзор, определение и архитектура
- Система управления версиями данных (DVC)
- MLflow
- FastAPI
- Docker
- Evidently AI
Операции машинного обучения (MLOps) для начинающих: полное внедрение проекта
Разработка, развёртывание и поддержка моделей машинного обучения в продакшене может быть сложной и трудоёмкой задачей. Именно здесь на помощь приходит Machine Learning Operations (MLOps). MLOps — это...
habr.com