Как выпустить ML-сервис в прод малыми силами: кейс работы в облаке
Создание ML-модели — сложный и ресурсоёмкий во всех смыслах процесс. Но часто выкатка сервиса на основе модели в прод оказывается ещё сложнее: требует подготовки платформы, выделения ресурсов, настройки программных интерфейсов для передачи данных из модели конечному пользователю. В таких условиях рациональнее разворачивать решения в облаках, особенно если можно использовать сервисы для полного цикла ML-разработки.
Привет, Хабр. Нас зовут Александр Кузьмичёв и Александр Казначеев. Мы пилотируем проект «ML-сервис по оттоку». В этой статье мы поделимся нашим опытом разработки модели и выкатки её в прод с помощью Cloud ML Platform.
Предыстория
Наша команда занимается разработкой и обучением моделей машинного обучения под разные задачи и сценарии использования. В том числе мы создаём ML-модели по запросу бизнеса. Одной из таких стала модель для определения оттока клиентов, которую мы готовили по заказу компании Premium Bonus, предлагающей решения для автоматизации работы с данными клиентов.
Запрос и исходные данные
Нам требовалось разработать математический алгоритм на основе машинного обучения для автоматического предсказания склонности клиента к оттоку в течение прогнозируемого периода. Для ритейла это важная метрика, поэтому предсказание таких событий важно для разработки долгосрочной стратегии развития бизнеса. В качестве периода прогнозирования выбрали 60 дней: если в течение этого времени человек не возвращается в магазин за новой покупкой, мы считаем, что он ушёл в «отток».
После первичного анализа проекта мы поняли, что:
- задача несложная, поэтому для её решения достаточно одной ML-модели. Это позволило сделать её монолитной, что упрощает обучение;
- в качестве исходника для ML-модели можно выбрать бустинг на основе решающих деревьев — алгоритм контролируемого машинного обучения, который способен выдавать неплохой результат при решении задач классификации и регрессии.
Исходя из этого, мы решили делать ML-модель на CatBoost. Это универсальная Open-Source-библиотека с поддержкой категориальных переменных, которая в том числе решает задачи смещения градиента (Gradient Bias) и смещения предсказания (Prediction Shift). Библиотека CatBoost подходила нам и потому, что даёт высокое качество обучения, а работать с ней можно из Python, R и командной строки.
Подготовка модели
Мы разработали модель на собственном сервере. Написали её на Python. Для работы с моделью мы подготовили пайплайн, который позволяет реализовать простой алгоритм взаимодействия с сервисом:
- загрузили данные и переменные;
- ML-модель выполнила расчёт;
- пользователь получил интерпретируемый результат.
Для обучения мы собрали датасет из 2 млн записей, в который вошли исторические данные за 1,5 года — с ноября 2021 года по апрель 2023 года. В исходной выборке среднее значение оттока было на уровне 11% в месяц при более 100 000 клиентов в месяц.
Изначально мы выделили из датасета 137 переменных, в том числе социально-демографические и поведенческие. Нам было важно извлечь из исторических данных все признаки, в том числе интервал между покупками, размер чека, стоимость товаров в чеке.
На этапе предварительной подготовки датасета для сокращения размерности мы отсеяли часть признаков по низкой одномерной предсказательной силе и корреляции. В итоге в модель вошло 50 переменных. При этом, уменьшив размерность, мы обеспечили сохранение переменных при многомерном отборе, который проводился для подбора гиперпараметров.
После обучения модели и её тестирования мы получили на выборке OOT показатель индекса Gini на уровне 75%. Этот индекс часто используется при оценке предсказательных моделей в задачах бинарной классификации при сильной несбалансированности классов целевой переменной. Так мы убедились, что правильно выбрали признаки и модель не требует дообучения.
Выкатка ML-модели в прод
После подготовки модели нам надо было выбрать платформу для её размещения. Хостить на своём железе мы изначально не хотели и не планировали. В качестве основного варианта развертывания рассматривали облако:
- в нём можно получить нужные ресурсы и инструменты для развёртывания;
- к облаку легче подключить конечных пользователей;
- при развёртывании в облаке мы выносим за пределы нашей ответственности администрирование сервисов вроде MLFlow и управления инфраструктурой;
- доверие к продукту увеличивается благодаря стабильности инфраструктуры.
Мы выбрали сервис Cloud ML Platform от VK Cloud — платформу для полного цикла ML‑разработки. В нашем случае ключевым было наличие MLFlow и JupyterHub, а также поддержка нужных нам библиотек.
В качестве среды для упаковки ML-моделей и их автоматического развёртывания в облаке мы выбрали MLflow Deploy. Для этого последовательно создали инстанс JupyterHub и инстанс MLflow — с инструкциями от VK Cloud проблем не возникло.
При запуске важно вручную поменять ресурсы на 2 Гб и 2 CPU, иначе есть вероятность выйти за пределы ограничений VK по умолчанию.
Этап подготовки модели для нас свёлся к паре кликов: поскольку мы подготовили и обучили её заранее, нам понадобилось только загрузить её в MLFlow, который расписан в папке tutorial, и развернуть.
Правда, после хоста модели в Cloud ML Platform нам понадобилось несколько доработать её для обеспечения полной совместимости с платформой. Дело в том, что MLFlow не воспринимает никакие другие функции, кроме predict
. Но наша модель была сделана на основе библиотеки CatBoost, в которой за вызов предсказаний отвечает функция predict probe
. После консультаций с командой VK Cloud мы сделали небольшую «прокладку», отвечающую за конвертацию класса: теперь у ML Flow вызывается predict
, а у CatBoost он вызывает и присылает predict probe
.
%load_ext autoreload
%autoreload 2
import pandas as pd
import mlflow
import catboost
import pickle
# Импортируем нашу модель
loaded_model = pickle.load(open('1_model_all.pickle', 'rb'))
# Переопределяем класс
class AddN(mlflow.pyfunc.PythonModel):
def __init__(self, model):
self.model = model
def predict(self, context, model_input):
# Здесь мы говорим, что вызвать у нашей модели в нашем случае
# predict_proba.
# Здесь вы также можете прописать любые проверки уведомления или преобразования данных
# перед вызовом предикта
return self.model.predict_proba(model_input)
# Применяем класс
add5_model = AddN(loaded_model)
# Сохраняем модель в MLFLOW
mlflow.set_experiment(experiment_name='demand_forecasting')
with mlflow.start_run():
model_info = mlflow.pyfunc.log_model(artifact_path="model", python_model=add5_model)
# Пример деплоя модели из MLFLOW
import mlflow
from mlflow.deployments import get_deploy_client
client = get_deploy_client('vk-cloud-mlplatform')
deploy_server_name='deploy_server_q2'
auth_value = "user:PasswordDA@dvv//!123$"
auth_deployment_name = "test"
model_source_uri = 'mlflow-artifacts:/3/69715f65259c43d68360584710909fc0/artifacts/model'
client.create_deployment(deploy_server_name, auth_deployment_name, model_source_uri, auth=auth_value)
Под саму модель подняли конфигурацию на 2 CPU и 2 Гб. По результатам наших тестов выделенных мощностей достаточно для обработки 10 000 запросов в минуту при 50 переменных. Для текущей модели этого более чем достаточно. На эту конфигурацию, не поднимая новую, мы положим следующие модели.
Сейчас наша ML-модель для предсказания склонности клиента к оттоку доступна по API. Для обращения к ней достаточно простого запроса в одну строку. Для работы с моделью пользователю надо иметь только уникальную ссылку, логин и пароль.
# Пример
import requests
data={"inputs":[0.045341, 0.050680, 0.060618, 0.031065, 0.028702,0.045341]}
response = requests.post('https://ml-platform-77777777.ml.msk.vkcs.cloud/deploy/7777777-5299-4109-a6a6-7777777/test/invocations', json=data, auth=("user", "PasswordDA@dvv//!123$"))
print(response.text)
{"predictions": [0.9838204200479245, 0.01617957995207549]}
Весь алгоритм работы с моделью выглядит так:
- Пользователь загружает сырые данные. Подготовку датасета, сбор и выбор фичей мы оставили на стороне пользователя. При таком подходе он может оперировать данными, которые у него есть, без каких-либо ограничений.
- На стороне Cloud ML Platform происходят все преобразования. Отдельных обработок, исключений и чего-то подобного поверх не предпринимается: все обработки стандартные, которые выполняются по умолчанию в модели CatBoost.
- Модель выдаёт пользователю прогноз в виде числа от 0 до 1, на основании которого можно делать выводы о вероятности оттока клиента в ближайшие два месяца.
Такой алгоритм позволил вынести все потенциальные сложности пользователя за скобки: для него вся механика вычислений, преобразований, логарифмы, деление, сенсибилизация, PPCA и другие процессы остаются в Black Box. Это уменьшает требования к компетенциям пользователей и снижает порог входа: не надо нанимать DevOps-разработчика, который всё поднимет и доведет модель до выдачи прогнозов.
Перспективы улучшения
ML-модель уже используется. Но это не единственная и не финальная реализация.
- При необходимости мы можем повысить показатель Gini. В текущем кейсе это не нужно: модель показывает хорошие результаты как в тесте, так и при решении целевых задач. Но потенциал для такого улучшения есть — например, с помощью введения дополнительных переменных и улучшения пайплайна.
- Мы предусмотрели возможность быстрого дообучения с учётом новых вводных или переобучения модели под другие задачи и сценарии. Это можно сделать, добавляя в исходную модель новые переменные. Пока что в ручном режиме по индивидуальному запросу — каждая модель будет проходить полный цикл разработки от начала до конца, —, но со временем мы начнём формировать скоры по похожим сегментам. Это поможет повысить качество и предоставить новому бизнесу уже готовый скор для их моделей.
И первую, и вторую доработки мы можем выполнить, используя ресурсы Cloud ML Platform. Это важно для нас, потому что не требует выведения модели из прода и поиска дополнительных инструментов для реализации.
Послесловие
Мы изначально были ориентированы на оптимизацию всех процессов разработки ML-модели и работы с ней в проде. В первую очередь это было возможно из-за невысокой сложности требуемых вычислений. Следуя этому курсу, мы смогли сделать простую, но эффективную модель, дающую высокую точность предсказаний, и быстро развернуть её в проде, используя предварительно настроенную среду и инструменты Cloud ML Platform. Наша ML-модель ещё имеет потенциал для улучшения. А благодаря тому, что мы работаем в облаке, мы можем добавлять новые инстансы и реализовать любые доработки, не останавливая сервис для конечных пользователей, и легко подстраиваться под рост запросов и сложности задач.