Сегодня в постоянно меняющейся сфере машинного обучения особую важность приобретает возможность управлять полным жизненным циклом моделей без особых усилий. Этот витиеватый процесс поможет упростить Open-Source-платформа MLflow.
Команда VK Cloud перевела пошаговое руководство по интеграции SQL-моделей в экосистему этой платформы. В нём автор проследит, по какому пути навстречу друг другу движутся SQL-модели и функции MLflow. Цель статьи двоякая: во-первых, разобраться в фундаментальных принципах использования на платформе простой SQL-модели и, во-вторых, решить сложную задачу — как сохранить SQL запросы (SQL-модели), используя репозиторий моделей MLflow.
Значение SQL-моделей
Трудно найти нечто более важное для реальных бизнес-сценариев, рейтинговых, рекомендательных систем и фильтров данных, чем SQL-модели. Где ещё SQL-модели играют ключевую роль?
-
Складской учёт. В базах данных SQL ведут учёт товаров, сроков пополнения запасов и данных о цепочках поставок. SQL-запросы помогают отслеживать количество продукции на складе, генерировать предупреждения о необходимости докупить товары и оптимизировать оборачиваемость запасов.
-
Сегментация заказчиков и таргетированный маркетинг. Маркетологи используют SQL-модели, чтобы сегментировать клиентскую базу и разрабатывать кампании таргетированной рекламы. С помощью этих моделей анализируют демографические характеристики потребителей, историю покупок и действия онлайн-пользователей, чтобы разбить заказчиков на конкретные сегменты с определёнными предпочтениями, тем самым закладывая фундамент для стратегий персонализированного маркетинга.
-
Оптимизация цепочки поставок. Компании, работающие со сложными цепочками поставок, используют SQL-модели, чтобы оптимизировать уровни запасов, упростить логистику и сократить расходы. SQL-запросы помогают анализировать деятельность поставщиков, прогнозы спроса и графики работы, чтобы организовать своевременные поставки и эффективное производство.
Что такое MLflow
MLflow — это Open-Source-платформа, разработанная Databricks и предназначенная для комплексного управления жизненным циклом машинного обучения. Она предоставляет инструменты для мониторинга экспериментов, упаковки кода в воспроизводимые итерации (runs), совместного доступа к моделям и их развёртывания в рамках единого фреймворка. MLflow предлагает структурированный подход к организации проектов машинного обучения и совместной работе дата-сайентистов, инженеров машинного обучения и бизнес-аналитиков.
Ключевые компоненты MLflow:
-
MLflow Tracking. Этот компонент позволяет вести логи и мониторинг экспериментов, фиксируя важные метрики, параметры и артефакты, связанные с разными runs.
-
MLflow Projects. «Проекты» позволяют упаковать спецификации кода, зависимостей и среды в формат, поддерживающий многократное использование. Это позволяет воспроизводить эксперименты, снижая вероятность нестыковок при переходе от разработки в продакшен.
-
MLflow Models. Это стандартный формат для упаковки моделей машинного обучения, который можно использовать в различных последующих инструментах, например для обслуживания в реальном времени через REST API или пакетного вывода в Apache Spark. Формат определяет соглашение, которое позволяет вам сохранять модель в разных «вариантах», которые могут быть поняты различными последующими инструментами.
-
MLflow Registry. Это хорошо организованная библиотека, в которой вы храните и управляете разными версиями обученных моделей машинного обучения. Нечто вроде полки с разными изданиями любимых книг. Model Registry в MLflow помогает отслеживать, как модели изменяются со временем; при этом в тот или иной момент можно легко найти и использовать нужную версию.
MLflow можно назвать единой платформой, обеспечивающей согласованную работу разных библиотек моделей, в том числе scikit-learn и TensorFlow. Она упрощает развёртывание и облегчает изменение алгоритмов модели. С MLflow компания может позволить себе разнообразные эксперименты с разными алгоритмами, соблюдая при этом единообразный процесс развёртывания. Платформа сглаживает различия между библиотеками, обеспечивая беспроблемный переход от разработки к развёртыванию без преобразований вручную. Благодаря этой гибкости устраняются сложности с изменением алгоритмов, поддерживается адаптация к инновациям и сокращается трудоёмкость технического обслуживания благодаря централизации пайплайнов для развёртывания.
Для чего нужна интеграция SQL-модели в MLflow
MLflow отлично справляется с моделями Python и артефактами TensorFlow, но готовое решение не поддерживает SQL-запросы в контексте модели. Из-за такого разделения компаниям часто приходится внедрять разные системы для развёртывания моделей SQL и Python. В результате растёт объём задач для техподдержки и появляется всё больше несоответствий в работе.
Эту проблему можно решить с помощью неординарной стратегии: ввести логику запросов SQL в функцию Python. Таким образом мы прокладываем дорожку к беспроблемной интеграции SQL-моделей в экосистему MLflow. Так достигается эффективность хранения, версионирования и развёртывания.
Благодаря интеграции расширяются функциональные возможности платформы: они выходят за рамки традиционных алгоритмов машинного обучения, превращая решение в ценный актив для компаний, которые стремятся задействовать всю мощь SQL-запросов в рабочих процессах анализа данных. В такой интеграции реализуется унифицированный подход к управлению жизненным циклом модели. Здесь в одном фреймворке эффективно объединяются модели SQL и Python. Очень удобно для компаний, полагающихся на возможности SQL для анализа данных и разработки моделей. Это расширяет функциональность MLflow для решения разнообразных задач моделирования, повышает эффективность и обеспечивает совместную работу на протяжении всего жизненного цикла разработки модели.
Этапы внедрения
0. Постановка задачи
Рассмотрим сценарий Airbnb. Чтобы сделать сайт удобнее для пользователей, компания стремится оптимизировать модель ранжирования объявлений. Прежде чем погрузиться в современные алгоритмы машинного обучения, они решили написать SQL-модель в качестве исходной точки для сравнения. Их основная цель — исходя из среднего рейтинга ранжировать объявления по конкретному региону в ответ на запрос пользователя на сайте.
Вот что для этого нужно сделать.
1. Генерируем синтетические данные
Во-первых, давайте сгенерируем синтетический датасет, имитирующий данные из объявлений на Airbnb. Он содержит ID объявлений, регионы, рейтинг, даты создания и количество комнат. Такие сгенерированные данные позволят нам работать с репрезентативным датасетом для нашей модели.
import
random
from builtins import round
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, rand
from pyspark.sql.types import IntegerType, StringType, DateType
Create a Spark session
#spark = SparkSession.builder.appName("AirbnbSimulator").getOrCreate()
# Define the number of rows for the simulated dataset
num_rows = 1000
# Generate the simulated data
data = []
for i in range(num_rows):
listing_id = i + 1
region = f"Region_{i % 10}"
review_score = round(random.gauss(80, 5), 2) # Generating review scores from 10 to 100
create_date = f"2023-01-{(i % 30) + 1}" # Creating dates within January 2023
number_of_rooms = (i % 5) + 1
data.append((listing_id, region, review_score, create_date, number_of_rooms))
# Create a DataFrame from the simulated data
listing_df = spark.createDataFrame(data, ["listing_id", "region", "review_score", "create_date", "number_of_rooms"])
# Show the first few rows of the DataFrame
listing_df.show()
# Stop the Spark session
#spark.stop()
Исходный файл listing_df.py на GitHub
Давайте рассмотрим датасет, который мы только что создали:
2. Определяем функцию ранжирования
Давайте определим функцию ранжирования объявлений по региону. В ней исходные данные — это территория (регион); для фильтрации и сортировки объявлений по рейтингу в порядке убывания используются SQL-запросы.
# Define the function to rank listings by region
def rank_listings_by_region(area,spark):
# Load the listings DataFrame from the specified table
spark.sql("CREATE OR REPLACE TEMPORARY VIEW listings_df AS SELECT * FROM listing_df")
# Apply filters and sorting using SQL query
ranked_listings = spark.sql(f"""
SELECT listing_id
FROM listings_df
WHERE region = '{area}'
ORDER BY review_score DESC
""")
return ranked_listings
Исходный файл rank_listings_by_region.py на GitHub
Давайте по-быстрому протестируем функцию:
# Create a temp table from DataFrame generated for example
listing_df.createOrReplaceTempView("listing_df")
# Call the function to rank listings by region
ranked_listings = rank_listings_by_region("Region_3", spark)
# Show the ranked listings
ranked_listings.show()
Исходный файл test_call.py на GitHub
3. Упаковываем функцию для MLflow
Чтобы интегрировать эту функцию ранжирования в MLflow, её нужно упаковать с помощью конвенций платформы. Создадим класс Python под названием
RankingModel
, который является наследником mlflow.pyfunc.PythonModel
. Этот класс содержит метод predict
, который инициализирует сеанс Spark, извлекает регион из исходных данных и вызывает функцию ранжирования.import mlflow
from mlflow.tracking import MLflowClient
# Define your RankingModel class that inherits from mlflow.pyfunc.PythonModel
class RankingModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
# Initialize Spark session
spark = SparkSession.builder.appName('RankingModel').getOrCreate()
# Extract region from the model input dictionary (not used in this case)
region = model_input["region"][0]
# Call the rank_listings_by_region function
return rank_listings_by_region(region, spark).toPandas()
Исходный файл SimplifiedRankingModel.py на GitHub
4. Тестируем модель
Давайте по-быстрому проверим, работает ли
RankingModel
в соответствии с ожиданиями. Для этого создадим экземпляр модели, определим для неё исходные данные (регион) и вызовем метод predict
для получения ранжированных объявлений.# Testing
if __name__ == "__main__":
# Create an instance of the RankingModel class
model = RankingModel()
# Define model_input as a dictionary (region is not used in this case)
model_input = {"region": ["Region_3"], 'user_id': [100]}
# Call the predict method of the model
result = model.predict(None, model_input)
# Print the resulting ranked listings
print(result)
Исходный файл test_rankingmodel.py на GitHub.
Регистрируем модель
После пройденного теста зарегистрируем модель для дальнейшего использования в MLflow. На этом этапе нужно определить run на платформе, вызвать метод
predict()
с тестовыми данными, получить сигнатуру функции predict
, ввести артефакт модели в MLflow и зарегистрировать модель в Model Registry.import mlflow
from mlflow.tracking import MLflowClient
from mlflow.models.signature import infer_signature
# Create a sample test DataFrame
test_data = pd.DataFrame({
'area': ['Any Region'],
'user_id': [100]
})
# Initialize MLflow client
client = MLflowClient()
# Create an instance of the RankingModel
model = RankingModel()
# Start an MLflow run
with mlflow.start_run() as run:
# Call the `predict()` method on the instantiated model with the required arguments
prediction = model.predict(context=None, model_input=test_data)
# Infer the signature of the predict function
signature = infer_signature(test_data, prediction)
# Log the model artifact to MLflow
mlflow.pyfunc.log_model(
artifact_path="sql_model",
python_model=model,
input_example=test_data,
signature=signature
)
# Register the model to the model registry
mv = mlflow.register_model(f'runs:/{run.info.run_id}/sql_model', "sql_model")
client.transition_model_version_stage(f'sql_model', mv.version, "Production", archive_existing_versions=True)
Исходный файл register_model.py на GitHub
Рассмотрим зарегистрированную модель.
Если после регистрации загрузить модель в другой Notebook или контекст и вызвать её метод
predict
, используя регионы в качестве исходных данных, мы получим результат в виде ID объявлений по этому региону, ранжированных по рейтингу.5. Загружаем и используем зарегистрированную модель
Наконец, продемонстрируем, как загрузить зарегистрированную модель в другой контекст или ноутбук и использовать её для прогнозирования. Так мы получаем беспроблемную интеграцию модели в разные приложения.
# Load the registered model
model_uri = "models:/sql_model/2" # Update with the correct URI for your model
loaded_model = mlflow.pyfunc.load_model(model_uri)
# Create a new test DataFrame
new_test_data = pd.DataFrame({
'region': ['Region_1'],
'user_id': [300]
})
# Make predictions using the loaded model
predictions = loaded_model.predict(new_test_data)
# Display the predictions
print(predictions)
Исходный файл simple_model.py на GitHub
После этих действий мы успешно создадим SQL-модель, интегрируем её с MLflow и сделаем доступной для разных data-driven-приложений далее в системе.
Заключение
Итак, нам удалось создать SQL-модель и интегрировать её в MLflow. Модель зарегистрирована и может использоваться как endpoint для других сервисов, предоставляя масштабируемое и эффективное решение для ранжирования объявлений по рейтингу. Этот подход демонстрирует универсальность MLflow при управлении моделями разного рода в рамках единообразного фреймворка, выводит её функциональные возможности за пределы моделей Python и позволяет внедрить SQL-модели. Полный ноутбук лежит здесь.
Попробуйте ML Platform от VK Cloud — она помогает построить процесс работы с ML-моделями от дизайна до деплоя, контролировать качество экспериментов и моделей. Для тестирования мы начисляем новым пользователям 3 000 бонусных рублей и будем рады вашей обратной связи.
Stay tuned
Присоединяйтесь к Telegram-каналу «Данные на стероидах». В нем вы найдете все об инструментах и подходах к извлечению максимальной пользы из работы с данными: регулярные дайджесты, полезные статьи, а также анонсы конференций и вебинаров.