В этом руководстве мы с вами создадим MLOps‑конвейер с использованием TensorFlow, Azure Machine Learning (AML), GitHub Actions, и Bicep (IaC).
Этот конвейер будет охватывать весь жизненный цикл разработки моделей машинного обучения, включая предварительную обработку данных, обучение моделей, оптимизацию гиперпараметров, оценку моделей, развертывание и внедрение конвейеров CI/CD.
По завершении этого руководства вы получите надежную, масштабируемую и удобную в обслуживании MLOps‑систему.
Что вам потребуется
Перед началом работы убедитесь, что у вас есть следующее:
Аккаунт GitHub: Для контроля версий и CI/CD.
Подписка на Azure: Для создания и управления ресурсами Azure.
Azure CLI и Bicep: Установленные локально для развертывания инфраструктуры.
Минимальная осведомленность в теме: Знакомство с TensorFlow, Python и Azure Machine Learning.
Обзор проекта
Наш проект можно разбить на следующие составляющие:
Подготовка инфраструктуры: Использование Bicep для развертывания ресурсов Azure.
Предварительная обработка данных: Подготовка данных с помощью TensorFlow.
Обучение модели: Обучение CNN‑модели на наборе данных CIFAR-10.
Оптимизация гиперпараметров: Оптимизация модели с помощью AML HyperDrive.
Оценка модели: Оценка эффективности модели.
Развертывание модели: Развертывание модели в виде REST API.
Конвейер CI/CD: Автоматизация рабочих процессов с помощью GitHub Actions, включая механизмы версионирования и отката моделей.
GitHub‑репозиторий: charotAmine/mlops_test (github.com)
Должен вас предупредить, что в этом руководстве будет проводиться аналогия с кухней, чтобы стимулировать ваше воображение, так что не пугайтесь. Давайте же начнем!
Шаг 1: Создание структуры проекта
Представьте себе ваш проект как хорошо организованную кухню. Вам потребуются отдельные секции для ингредиентов (данных), рецепта (кода) и кухонной утвари (скриптов). Вот как мы все организуем:
/mlops-project
│
├── data/
│ └── download_data.py
│
├── src/
│ ├── preprocess.py
│ ├── train.py
│ ├── evaluate.py
│ ├── hyperdrive_config.py
│ ├── deploy.py
│ ├── score.py
│ ├── model.py
│ ├── drift_detection.py
│ └── monitor_drift.py
│
├── .github/
│ └── workflows/
│ └── mlops-pipeline.yml
│
├── aml_config/
│ ├── environment.yml
│ ├── inferenceconfig.yml
│ └── data_drift.yml
│
├── bicep/
│ └── modules/
│ └── main.bicep
│
└── README.md
Шаг 2: Подготовка инфраструктуры с помощью Bicep
Представьте, что вы переезжаете в новую квартиру. Первое, что вам нужно, — это надежная инфраструктура: стены, крыша, водопровод, электричество… ну, вы поняли о чем я. В облаке подготовка инфраструктуры происходит точно так же, только вместо стен мы говорим о группах ресурсов, учетных записях хранилищ и рабочих пространствах для машинного обучения.
Вот ссылка на GitHub‑репозиторий с готовой инфраструктурой: charotAmine/mlops_test (github.com)
Шаг 3: Предварительная обработка данных — подготовка ингредиентов
Прежде чем приготовить блюдо, необходимо вымыть, нарезать и отмерить ингредиенты. Точно так же, прежде чем обучать нашу модель, нам нужно подготовить данные для нее.
3.1. Загрузка данных
С помощью data/download_data.py загрузите набор данных CIFAR-10, который мы будем использовать в качестве наших ингредиентов:
import tensorflow as tf
def download_data():
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.cifar10.load_data()
return (train_images, train_labels), (test_images, test_labels)
if __name__ == "__main__":
download_data()
Назначение функции: Функция
download_data
предназначена для загрузки и возврата набора данных CIFAR-10.Загрузка данных:
tf.keras.datasets.cifar10.load_data()
— это функция TensorFlow, которая загружает набор данных CIFAR-10, состоящий из 60 000 цветных изображений 32×32 в 10 классах, по 6 000 изображений на класс. Набор данных разделен на 50 000 обучающих и 10 000 тестовых изображений.Возврат данных: Функция возвращает обучающие и тестовые изображения вместе с соответствующими метками.
Как это вписывается в MLOps
В контексте MLOps этот скрипт служит простым примером шага ввода данных. Вот как он вписывается в более широкий конвейер MLOps:
Загрузка данных: Этот скрипт выполняет загрузку набора данных, что является первым шагом в любом конвейере машинного обучения.
Воспроизводимость: Использование стандартного набора данных и четко определенной функции обеспечивает воспроизводимость процесса получения данных.
Автоматизация: Этот скрипт можно интегрировать в автоматизированные рабочие процессы, такие как конвейеры CI/CD, чтобы обеспечить постоянную доступность и актуальность данных.
3.2. Предобработка данных
В src/preprocess.py нормализуем данные (по аналогии с кухней — очистка и измельчение ингредиентов):
import tensorflow as tf
def preprocess_data(train_images, test_images):
train_images = train_images / 255.0
test_images = test_images / 255.0
return train_images, test_images
Назначение функции: Функция
preprocess_data
предназначена для предварительной обработки обучающих и тестовых изображений.Нормализация: Изображения нормализуются путем деления значения каждого пикселя на 255.0. Это масштабирует значения пикселей из диапазона [0, 255] в диапазон [0, 1], что является обычным шагом предварительной обработки, помогающим нейронной сети обучаться более эффективно.
Возврат данных: Функция возвращает нормализованные обучающие и тестовые изображения.
Теперь наши данные готовы к использованию в модели.
Шаг 4: Готовим модель — Обучение нейронной сети
Настало время готовить! Мы определим сверточную нейронную сеть (CNN), которая будет обучаться на наших предварительно обработанных данных.
4.1. Определение модели
Определим нашу CNN. Считайте, что это наш секретный ингредиент. В файле src/model.py:
import tensorflow as tf
def create_model():
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(32, 32, 3)),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(256, (3, 3), activation='relu'),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
return model
Последовательная модель: Мы создаем последовательную модель, что означает, что слои будут располагаться последовательно.
Conv2D — Сверточные слои: Эти слои выполняют операции свертки. Первый слой Conv2D содержит 64 фильтра, второй — 128 фильтров, третий — 256 фильтров, все с размером ядра (3, 3) и функцией активации ReLU.
MaxPooling2D — Слои пулинга: Эти слои выполняют операции субдискретизации с функцией максимума с размером пула (2, 2), что позволяет уменьшить пространственную размерность выхода.
Flatten — Плоский слой: Этот слой сворачивает размерность входных данных, преобразуя двумерные матричные данные в одномерные векторы.
Dense — Плотный слой: Первый плотный слой состоит из 512 блоков с функцией активацией ReLU, а второй состоит из 10 блоков с функцией активации softmax, которые используются для многоклассовой классификации.
Оптимизатор: В модели используется оптимизатор Adam, который представляет собой адаптивный алгоритм оптимизации скорости обучения.
Функция потерь: В качестве функции потерь используется разреженная категориальная кросс энтропия (sparse categorical crossentropy), которая подходит для задач многоклассовой классификации, где метки являются целыми числами.
Метрики: Модель оценивается с помощью метрик точности.
4.2. Обучение модели
Приготовим (обучим) модель на подготовленных данных. В файле src/train.py:
import tensorflow as tf
from model import create_model
from download_data import download_data
from preprocess_data import preprocess_data
import mlflow
import mlflow.tensorflow
class CustomCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
mlflow.log_metrics({
"loss": logs["loss"],
"accuracy":
logs["accuracy"]
})
# Запускаем логирование
mlflow.start_run()
# Включаем автологирование
mlflow.tensorflow.autolog()
(train_images, train_labels), (test_images, test_labels) = download_data()
train_images, test_images = preprocess_data(train_images, test_images)
model = create_model()
history = model.fit(train_images, train_labels, epochs=1, validation_data=(test_images, test_labels),callbacks=[CustomCallback()])
model.save("outputs/model")
Скрипт train.py предназначен для управления всем процессом обучения ML‑модели, начиная с получения и предобработки данных и заканчивая созданием модели, непосредственным обучением и протоколированием. Этот скрипт является важнейшей частью MLOps‑конвейера, обеспечивая автоматизацию, воспроизводимость и документированность каждого этапа.
Интеграция с MLflow
MLflow — это платформа для управления жизненным циклом машинного обучения. Она предоставляет инструменты для отслеживания экспериментов, управления моделями и их развертывания. В этом скрипте MLflow используется для регистрации метрик и параметров в процессе обучения, что необходимо для отслеживания производительности различных моделей и экспериментов.
Запуск MLflow: Скрипт начинается с запуска MLflow посредством
mlflow.start_run()
. Это создает новый run в MLflow, который будет отслеживать все последующие операции, включая метрики, параметры и артефакты.Автологирование: Строка
mlflow.tensorflow.autolog()
включает автоматическое логирование параметров обучения TensorFlow, метрик и моделей в MLflow. Это означает, что вам не нужно вручную логировать каждую метрику или параметр. MLflow делает это за вас, гарантируя, что вся необходимая информация будет получена.Пользовательский коллбэк для логирования: Определяется пользовательский коллбэк‑класс
CustomCallback
для логирования дополнительных метрик в конце каждой эпохи. Этот коллбэк логирует метрики потерь и точности в MLflow, предоставляя подробный отчет о работе модели с течением времени.
Ввод и предварительная обработка данных
Скрипт использует функции из других модулей для ввода и предварительной обработки данных. Функция download_data
загружает набор данных CIFAR-10, который является стандартным набором данных, используемым для задач классификации изображений. Функция preprocess_data
нормализует изображения, масштабируя значения пикселей в диапазон [0, 1], что помогает нейронной сети обучаться более эффективно.
Создание модели и обучение
Функция create_model
определяет модель сверточной нейронной сети (CNN) с помощью API Keras в TensorFlow. Эта модель состоит из нескольких сверточных, пулинговых и плотных слоев, предназначенных для классификации изображений в одну из десяти категорий.
Затем модель обучается с помощью метода model.fit, который принимает данные для обучения, метки и другие параметры, такие как количество эпох и данные для проверки. В этот метод передается пользовательский колбэк, чтобы обеспечить логирование метрик в MLflow в конце каждой эпохи.
Наконец, обученная модель сохраняется в указанную папку с помощью команды model.save(«outputs/model»). Это позволяет повторно использовать модель для получения выводов или дальнейшего обучения без необходимости заново создавать и обучать ее с нуля.
Основная задача этого скрипта — автоматизировать процесс обучения модели, обеспечив при этом воспроизводимость и документируемость всех этапов. Интегрируя MLflow, скрипт обеспечивает надежную основу для отслеживания экспериментов, что важно для сравнения различных моделей и гиперпараметров. Такой уровень автоматизации и отслеживания крайне важен для MLOps‑конвейера, основной задачей которого является оптимизация разработки, развертывания и мониторинга моделей машинного обучения.
Научиться на практике, как деплоить модели в production, можно на онлайн-курсе "MLOps".
Шаг 5: Оптимизация гиперпараметров — Доводим до совершенства
Подобно тому, как вы пробуете блюдо и корректируете вкус приправами, мы можем точно настроить нашу модель с помощью оптимизации гиперпараметров. Это гарантирует, что наша модель будет настолько хороша, насколько это возможно.
5.1. Настройка HyperDrive
В файле src/hyperdrive_config.py настройте HyperDrive в Azure ML для поиска наилучших параметров модели:
from azure.ai.ml import MLClient
from azure.ai.ml import command
from azure.ai.ml.entities import Environment
from azure.ai.ml.sweep import Choice,MedianStoppingPolicy
from azure.identity import DefaultAzureCredential
import os
from azure.ai.ml.entities import Model
credential = DefaultAzureCredential()
subscription_id = os.getenv("AZURE_SUBSCRIPTION_ID")
resource_group = os.getenv("AZURE_RESOURCE_GROUP")
workspace_name = os.getenv("AZURE_WORKSPACE_NAME")
ml_client = MLClient(
credential=credential,
subscription_id=subscription_id,
resource_group_name=resource_group,
workspace_name=workspace_name
)
# Определяем окружение с помощью conda‑файла
tf_env = Environment(
name="tensorflow-env",
conda_file="aml_config/environment.yml",
image="mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.8-cudnn8-ubuntu22.04"
)
command_job = command(
code="./src", # source directory
command="python train.py --learning_rate ${{inputs.learning_rate}} --batch_size ${{inputs.batch_size}}",
environment=tf_env,
inputs={
"learning_rate": Choice([0.01, 0.001, 0.0001]),
"batch_size": Choice([16, 32, 64])
},
compute="gpu-cluster"
)
command_job_for_sweep = command_job(
learning_rate=Choice([0.01, 0.001, 0.0001]),
batch_size=Choice([16, 32, 64]),
)
# Вызываем sweep() в команд джобе, чтобы просмотреть выражения параметров
sweep_job = command_job_for_sweep.sweep(
compute="gpu-cluster",
sampling_algorithm="random",
primary_metric="accuracy",
goal="Maximize"
)
# Определяем границы для sweep
sweep_job.set_limits(max_total_trials=20, max_concurrent_trials=10, timeout=7200)
# Устанавливаем раннюю остановку
sweep_job.early_termination = MedianStoppingPolicy(delay_evaluation=5, evaluation_interval=2)
# Указываем детали эксперимента.
sweep_job.display_name = "lightgbm-iris-sweep"
sweep_job.experiment_name = "lightgbm-iris-sweep"
sweep_job.description = "Run a hyperparameter sweep job for LightGBM on Iris dataset."
# Сабмитим sweep
returned_sweep_job = ml_client.create_or_update(sweep_job)
# Потоковая передача вывода и ожидание завершения работы
ml_client.jobs.stream(returned_sweep_job.name)
# Обновляем последний статус джобы после потоковой передачи
returned_sweep_job = ml_client.jobs.get(name=returned_sweep_job.name)
if returned_sweep_job.status == "Completed":
# Сначала давайте возьмем run, который дал нам наилучший результат
print(returned_sweep_job)
print(returned_sweep_job.properties.keys())
print(returned_sweep_job.properties.values())
best_run = returned_sweep_job.properties["best_child_run_id"]
# Получаем модель из этого run
model = Model(
path="azureml://jobs/{}/outputs/model/".format(
best_run
),
name="cifar10-model",
description="Model created from run.",
type="custom_model"
)
print("Best run: {}".format(best_run))
print("Model: {}".format(model))
else:
print(
"Sweep job status: {}. Please wait until it completes".format(
returned_sweep_job.status
)
)
registered_model = ml_client.models.create_or_update(model=model)
Цель скрипта hyperdrive_config.py — автоматизировать процесс оптимизации гиперпараметров с помощью Azure Machine Learning (Azure ML). Оптимизация гиперпараметров — важный шаг в создании моделей машинного обучения, поскольку он включает в себя поиск наилучшей комбинации гиперпараметров, обеспечивающей максимальную производительность модели. Этот скрипт использует функционал Azure ML для эффективного и результативного поиска, обеспечивая масштабируемость и документированность процесса.
HyperDrive в Azure ML
HyperDrive — это сервис оптимизации гиперпараметров в Azure ML. Он позволяет дата‑сайентистам и инженерам машинного обучения автоматизировать процесс оптимизации гиперпараметров, который необходим для повышения производительности модели. HyperDrive поддерживает различные алгоритмы сэмплинга для исследования пространства гиперпараметров, такие как случайный поиск (random sampling), решетчатый поиск (grid search) и байесовская оптимизация. Кроме того, в нем предусмотрены политики ранней остановки, позволяющие завершить плохо работающие испытания на ранней стадии, что экономит вычислительные ресурсы и время.
Важность для MLOps
В контексте MLOps HyperDrive играет решающую роль в жизненном цикле разработки модели. Вот почему:
Производительность: HyperDrive автоматизирует процесс оптимизации гиперпараметров, позволяя исследовать большое пространство гиперпараметров без ручного вмешательства. Это крайне важно для быстрого определения наилучших конфигураций модели.
Масштабируемость: Используя облачную инфраструктуру Azure, HyperDrive может масштабировать процесс оптимизации гиперпараметров на нескольких вычислительных узлах. Такая масштабируемость позволяет оптимизировать в разумные сроки даже сложные модели с обширным пространством гиперпараметров.
Воспроизводимость: HyperDrive обеспечивает воспроизводимость процесса оптимизации гиперпараметров. Логируя все эксперименты, конфигурации и результаты, он позволяет дата‑сайентистам отслеживать и воспроизводить наиболее эффективные модели.
Интеграция с MLOps‑конвейерами: HyperDrive легко интегрируется с конвейерами Azure ML, обеспечивая автоматизированные рабочие процессы, включающие оптимизацию гиперпараметров в качестве одного из этапов процесса обучения модели. Такая интеграция гарантирует, что оптимизация гиперпараметров является стандартной частью жизненного цикла разработки модели, что приводит к созданию более надежных и лучше настроенных моделей.
Управление ресурсами: Благодаря таким функциям, как политика ранней остановки, HyperDrive помогает эффективно управлять вычислительными ресурсами. Он останавливает испытания, которые вряд ли дадут хорошие результаты, на ранней стадии, что позволяет сэкономить время и снизить затраты.
Визуализация и анализ результатов перебора гиперпараметров в Azure ML очень важны для понимания эффективности различных комбинаций гиперпараметров и выбора наилучшей модели. Вот как это будет выглядеть:
Работа с Azure ML Studio
Запуск Azure ML Studio: Перейдите в Azure Machine Learning Studio (https://ml.azure.com/).
Перейдите к эксперименту: В левом меню нажмите на «Experiments» и найдите эксперимент, связанный с вашим набором гиперпараметров.
Обзор Sweep Job: Нажмите на sweep job, чтобы открыть ее детали. Здесь вы можете просмотреть обзор джобы, включая статус каждого испытания, используемые гиперпараметры и результирующие метрики.
Визуализация метрик: Azure ML Studio предоставляет встроенные визуализации для анализа результатов. Вы можете просматривать графики, на которых отображается основная метрика (например, точность) в зависимости от различных гиперпараметров. Это поможет вам выявить тенденции и понять, как различные гиперпараметры влияют на производительность модели.
Сравнение испытаний: Вы можете сравнить различные испытания, выбрав их и просмотрев подробные метрики и логи. Это сравнение поможет вам понять, какие комбинации гиперпараметров показали наилучшие результаты.
В нашем случае мы увидим что‑то вроде:

Испытания

Шаг 6: Оценка модели — Дегустация
Прежде чем подать блюдо на стол, его нужно попробовать, чтобы убедиться в его готовности. Мы делаем то же самое с нашей моделью, оценивая ее производительность.
6.1. Оценка модели
Проверим, насколько хорошо работает наша модель. В src/evaluate.py:
import tensorflow as tf
from download_data import download_data
from preprocess_data import preprocess_data
_, (test_images, test_labels) = download_data()
_, test_images = preprocess_data(test_images, test_images)
model = tf.keras.models.load_model("outputs/model")
loss, accuracy = model.evaluate(test_images, test_labels)
print(f"Test accuracy: {accuracy}")
Задача скрипта
Основная цель скрипта evaluate.py — загрузить предварительно обученную модель, обработать тестовые данные, а затем оценить работу модели на этих данных. Этот этап оценки необходим для понимания точности модели и выявления любых потенциальных проблем перед развертыванием модели в продакшене.
Оценка в Azure MLOps
В контексте Azure MLOps этап оценки очень важен по нескольким причинам:
Проверка модели: Прежде чем внедрять модель, необходимо проверить ее работу на отдельном тестовом наборе данных. Это гарантирует, что модель не переобучилась на обучающих данных и может также хорошо работать для новых данных.
Метрики производительности: Скрипт вычисляет ключевые показатели производительности, такие как точность, которые затем логируются и отслеживаются в Azure ML. Эти метрики дают количественную оценку производительности модели и используются для сравнения различных моделей и конфигураций гиперпараметров.
Воспроизводимость: Использование стандартизированного скрипта позволяет воспроизводить процесс оценки. Это означает, что одну и ту же оценку можно последовательно проводить для разных моделей и наборов данных, обеспечивая надежные и сопоставимые результаты.
Интеграция с MLOps‑конвейерами: Скрипт оценки может быть интегрирован в конвейер Azure ML, что позволяет автоматически оценивать модели в рамках процесса непрерывной интеграции и непрерывного развертывания (CI/CD). Такая интеграция обеспечивает тщательное тестирование моделей перед развертыванием, снижая риск развертывания некачественных моделей.
Цикл обратной связи: Результаты оценки могут быть использованы для дальнейших итераций обучения модели и оптимизации гиперпараметров. Анализируя метрики оценки, дата‑сайентисты могут выявить области, требующие улучшения, и соответствующим образом доработать свои модели.
HyperDrive и оценка
При использовании в сочетании с HyperDrive скрипт оценки играет важную роль в процессе оптимизации гиперпараметров. После того как HyperDrive определит наилучшие конфигурации гиперпараметров, скрипт оценки используется для проверки производительности полученных моделей. Этот этап проверки гарантирует, что модели, отобранные HyperDrive, действительно являются наиболее эффективными и готовы к развертыванию.
Включив скрипт оценки в MLOps‑конвейер, мы можем быть уверены, что наши модели не только оптимизированы с точки зрения производительности, но и проверены и готовы к использованию в продакшене. Такой комплексный подход к оценке и проверке моделей необходим для поддержания высоких стандартов качества и надежности моделей в Azure MLOps.
Шаг 7: Развертывание модели — Подача блюда
Пришло время подавать наше идеально приготовленное блюдо! Мы развернем нашу модель, чтобы к ней могли получить доступ другие.
from azure.ai.ml import MLClient
from azure.ai.ml.entities import (
Model,
Environment,
ManagedOnlineEndpoint,
ManagedOnlineDeployment,
CodeConfiguration
)
from azure.identity import DefaultAzureCredential
import os
import time
# Загружаем рабочую среду
credential = DefaultAzureCredential()
subscription_id = os.getenv("AZURE_SUBSCRIPTION_ID")
resource_group = os.getenv("AZURE_RESOURCE_GROUP")
workspace_name = os.getenv("AZURE_WORKSPACE_NAME")
client = MLClient(
credential=credential,
subscription_id=subscription_id,
resource_group_name=resource_group,
workspace_name=workspace_name
)
# Определяем среду
env = Environment(
name="cifar10-env",
conda_file="aml_config/environment.yml",
image="mcr.microsoft.com/azureml/openmpi4.1.0-cuda11.8-cudnn8-ubuntu22.04",
)
client.environments.create_or_update(env)
# Создаем эндпоинт
endpoint = ManagedOnlineEndpoint(
name="cifar10-endpoint",
description="Endpoint for CIFAR-10 model",
auth_mode="key"
)
latest_model_version = max(
[int(m.version) for m in client.models.list(name="cifar10-model")]
)
client.online_endpoints.begin_create_or_update(endpoint)
model = client.models.get("cifar10-model",latest_model_version)
# Создаем конфигурацию развертывания
deployment_config = ManagedOnlineDeployment(
name="cifar10-deployment",
endpoint_name="cifar10-endpoint",
model=model,
code_configuration=CodeConfiguration(code="./src", scoring_script="score.py"),
environment='cifar10-env@latest',
instance_count=1,
instance_type="Standard_DS3_v2" # Example instance type, adjust as needed
)
client.online_deployments.begin_create_or_update(deployment_config)
# Опционально, дожидаемся завершения развертывания
deployment = client.online_deployments.get(name="cifar10-deployment", endpoint_name="cifar10-endpoint")
# Функция ожидания завершения развертывания
def wait_for_deployment_completion(ml_client,deployment, timeout=3600, interval=30):
elapsed_time = 0
while deployment.provisioning_state not in ["Succeeded", "Failed", "Canceled"] and elapsed_time < timeout:
time.sleep(interval)
elapsed_time += interval
deployment = ml_client.online_deployments.get(name=deployment.name, endpoint_name="cifar10-endpoint")
print(f"Deployment state: {deployment.provisioning_state}, elapsed time: {elapsed_time} seconds")
if deployment.provisioning_state == "Succeeded":
print("Deployment completed successfully.")
else:
print(f"Deployment failed with state: {deployment.provisioning_state}")
# Ждем завершения развертывания
wait_for_deployment_completion(client,deployment)
Скрипт deploy.py предназначен для развертывания обученной ML‑модели на Azure Managed Online Endpoint. Этот процесс развертывания является важным шагом в обеспечении доступности модели для прогнозирования в реальном времени и ее интеграции в производственные системы.
Основная задача скрипта deploy.py — автоматизировать развертывание ML‑модели на Azure Managed Online Endpoint. Это включает в себя настройку среды, создание эндпоинта, настройку развертывания и обеспечение готовности модели к генерации прогнозов.
При использовании в сочетании с HyperDrive скрипт развертывания играет важную роль в MLOps‑конвейере. После того как HyperDrive определит наилучшие конфигурации гиперпараметров, а скрипт оценки проверит производительность модели, скрипт развертывания позаботится о развертывании в продакшене модели с наилучшими характеристиками. Такая сквозная автоматизация, от настройки гиперпараметров до развертывания, необходима для обеспечения надежного и эффективного рабочего процесса MLOps.
Включив скрипт развертывания в MLOps‑конвейер, мы можем гарантировать, что наши модели не только оптимизированы и протестированы, но и развернуты масштабируемым, воспроизводимым и безопасным образом. Такой комплексный подход к развертыванию моделей имеет решающее значение для обеспечения надежных и высокопроизводительных решений машинного обучения в производственных средах.
Шаг 8: CI/CD-конвейер GitHub Actions — Автоматизируем нашу кухню
Представьте, что у вас есть робот‑повар, который автоматически готовит, пробует и подает ваши блюда. Именно это и делает наш конвейер CI/CD! Он автоматизирует все процессы — от обучения до развертывания.
8.1. Рабочий процесс GitHub Actions
Определим шаги для нашего робота‑повара в файле.github/workflows/mlops‑pipeline.yml:
name: MLOps Pipeline
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
jobs:
setup-infra:
runs-on: ubuntu-latest
outputs:
config-path: ${{ steps.upload-artifact.outputs.config-path }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: "Az CLI Login"
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy Azure Resources
run: |
ls /home/runner/work/mlops_test/mlops_test/
- name: Deploy Azure Resources
run: |
az deployment sub create \
--location westeurope \
--template-file bicep/main.bicep \
--parameters spnObjectId=${{ secrets.AZURE_OBJECT_ID }} resourceGroupName=${{ secrets.AZURE_RESOURCE_GROUP }} workspaceName=${{ secrets.AZURE_WORKSPACE_NAME }} clusterName=gpu-cluster storageAccountName=mlopsstorageacct0026
env:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
- name: Generate config.json
run: |
mkdir -p .azureml
echo '{
"subscription_id": "'"${{ secrets.AZURE_SUBSCRIPTION_ID }}"'",
"resource_group": "'"${{ secrets.AZURE_RESOURCE_GROUP }}"'",
"workspace_name": "'"${{ secrets.AZURE_WORKSPACE_NAME }}"'"
}' > config.json
- name: Upload config.json as artifact
uses: actions/upload-artifact@v3
with:
name: config
path: config.json
build-and-train:
runs-on: ubuntu-latest
needs: setup-infra
outputs:
model-path: ${{ steps.upload-artifact.outputs.model-path }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: Install dependencies
run: |
pip install azureml-sdk tensorflow mlflow
- name: Train the model
run: |
python src/train.py
env:
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
AZURE_WORKSPACE_NAME: ${{ secrets.AZURE_WORKSPACE_NAME }}
- name: Upload model as artifact
uses: actions/upload-artifact@v3
with:
name: model
path: outputs/model
hyperparameter-tuning:
runs-on: ubuntu-latest
needs: build-and-train
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Download model
uses: actions/download-artifact@v3
with:
name: model
path: outputs/model
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: "Az CLI Login"
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Download config.json
uses: actions/download-artifact@v3
with:
name: config
- name: Install dependencies
run: |
pip install azure-ai-ml azure-identity tensorflow mlflow
- name: Hyperparameter tuning
run: |
python src/hyperdrive_config.py
env:
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
AZURE_WORKSPACE_NAME: ${{ secrets.AZURE_WORKSPACE_NAME }}
evaluate:
runs-on: ubuntu-latest
needs: hyperparameter-tuning
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Download model
uses: actions/download-artifact@v3
with:
name: model
path: outputs/model
- name: Download config.json
uses: actions/download-artifact@v3
with:
name: config
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: "Az CLI Login"
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Install dependencies
run: |
pip install azure-ai-ml azure-identity tensorflow mlflow
- name: Evaluate the model
run: |
python src/evaluate.py
deploy:
runs-on: ubuntu-latest
needs: evaluate
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Download config.json
uses: actions/download-artifact@v3
with:
name: config
- name: Download model
uses: actions/download-artifact@v3
with:
name: model
path: outputs/model
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.8"
- name: "Az CLI Login"
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Install dependencies
run: |
pip install azure-ai-ml azure-identity tensorflow mlflow
- name: Deploy the model
run: |
python src/deploy.py
env:
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
AZURE_WORKSPACE_NAME: ${{ secrets.AZURE_WORKSPACE_NAME }}

MLOps, или Machine Learning Operations, — это критически важная практика, которая позволяет преодолеть разрыв между разработкой и внедрением моделей машинного обучения. Она включает в себя набор лучших практик, инструментов и процессов, которые обеспечивают эффективное, масштабируемое и надежное производство решений машинного обучения. Интегрируя принципы DevOps, инженерии данных и машинного обучения, MLOps стремится оптимизировать весь жизненный цикл машинного обучения — от сбора и предварительной обработки данных до обучения, оценки и развертывания моделей.
Одно из ключевых преимуществ MLOps — возможность автоматизировать и стандартизировать рабочие процессы, что повышает воспроизводимость и согласованность. Такая автоматизация сокращает ручной труд, необходимый для разработки и развертывания моделей, позволяя дата‑сайентистам и инженерам сосредоточиться на инновациях и улучшениях. Кроме того, MLOps облегчает непрерывную интеграцию и непрерывное развертывание (CI/CD) моделей машинного обучения, обеспечивая беспрепятственную интеграцию обновлений и новых моделей в производственные среды.
В MLOps также важны мониторинг и управление развернутыми моделями. Сюда входит отслеживание показателей производительности, выявление аномалий и обеспечение точности и надежности моделей с течением времени. Предоставляя инструменты для контроля версий, отслеживания экспериментов и оптимизации гиперпараметров, MLOps позволяет поддерживать высокие стандарты качества и производительности моделей.
В контексте Azure Machine Learning MLOps использует мощные облачные инструменты и сервисы для поддержки всего жизненного цикла машинного обучения. От HyperDrive для оптимизации гиперпараметров до Managed Online Endpoints для масштабируемого развертывания — Azure ML предоставляет комплексную платформу для внедрения MLOps. Благодаря этой интеграции модели машинного обучения не только оптимизируются и проверяются, но и развертываются безопасным, масштабируемым и воспроизводимым образом.
Таким образом, MLOps необходим для преобразования проектов машинного обучения из экспериментальных в надежные, готовые к производству решения. Применяя практику MLOps, организации могут добиться большей эффективности, масштабируемости и надежности рабочих процессов машинного обучения, что в конечном итоге приведет к улучшению результативности и инновациям.
Следующие шаги
Экспериментируйте: Попробуйте добавить больше рецептов (моделей) или интегрировать хранилище признаков.
Масштабирование: Развертывание на AKS для обеспечения высокой доступности.
Автоматизация: Дальнейшее усовершенствование CI/CD с автоматическим откатом и многомодельным версионированием.
А также приходите на открытый урок по теме «Основы Terraform в Yandex Cloud – автоматизируем облачную инфраструктуру». Урок пройдет 20 марта в рамках онлайн-урока "MLOps", записаться можно здесь.