КАК МЫ
УСКОРИЛИ
ПРОГНОЗ
СПРОСА ПУТЕМ
МИГРАЦИИ С
PANDAS
НА POLARS
Moscow Python Meetup #96
Python-разработчик
в ecom.tech (ex Samokat.tech)
Кирилл
Гладких
КАК МЫ
УСКОРИЛИ
ПРОГНОЗ
СПРОСА ПУТЕМ
МИГРАЦИИ С
PANDAS
НА POLARS
Slide 2
Slide 2 text
Гладких
Кирилл
• 5 лет разработки на Python
• Работаю в ecom.tech в команде
продуктовизации ML-моделей
для серисов Самоката
• Люблю котиков и путешествия
Slide 3
Slide 3 text
ритейл реального
времени в цифрах
заказов в день Самокат
доставляет своим клиентам
с доступом к быстрой
доставке продуктов
уникальных посетителей
Мегамаркета каждый
месяц
пунктов выдачи заказов
и постаматов по всей России
673 тыс. 127 городов
74 тыс.
40 млн
Slide 4
Slide 4 text
План
(01)
Проблематика:
Система прогноза
спроса в Самокате
(02)
Как устроена обработка, и с
какими проблемами
столкнулись.
(03)
Решение и альтернативы
Почему выбрали Polars?
(04)
Сравнение
быстродействия
библиотек
Slide 5
Slide 5 text
СИСТЕМА
ПРОГНОЗА
СПРОСА
Slide 6
Slide 6 text
Цели:
Уменьшить количество
списаний или время
недоступности товаров.
Требования
от бизнеса
[01]
Slide 7
Slide 7 text
Цели:
Уменьшить количество
списаний или время
недоступности товаров.
Повышение выручки
компании.
Требования
от бизнеса
Конечная цель
[01]
[02]
Slide 8
Slide 8 text
Цели:
Уменьшить количество
списаний или время
недоступности товаров.
Прогноз продаж:
Спрогнозировать количество
проданного товара на каждый
день для каждого даркстора
на 7 недель вперёд
по 46 категориям товаров
Например:
Бакалея, Мясо, Гигиена
и т.п.
Повышение выручки
компании.
Требования
от бизнеса
Конечная цель
[01]
[02]
Решение:
[01]
Slide 9
Slide 9 text
Цели:
Уменьшить количество
списаний или время
недоступности товаров.
Прогноз продаж:
Спрогнозировать количество
проданного товара на каждый
день для каждого даркстора
на 7 недель вперёд
по 46 категориям товаров
Например:
Бакалея, Мясо, Гигиена
и т.п.
Повышение выручки
компании.
Отправка прогноза:
Отправить прогнозы
потребителям в S3
и в Kafka
[02]
Требования
от бизнеса
Конечная цель
[01]
[02]
Решение:
[01]
Slide 10
Slide 10 text
Характеристики системы прогноза спроса
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 11
Slide 11 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 12
Slide 12 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
Написан на Python + Pandas +
Polars + scikit
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 13
Slide 13 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
~100 Гб данных для обработки
ежедневно
Написан на Python + Pandas +
Polars + scikit
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 14
Slide 14 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
~100 Гб данных для обработки
ежедневно
Написан на Python + Pandas +
Polars + scikit
Запускается в k8s на ноде
(500 Гб оперативной памяти
и 64 CPU ядра)
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 15
Slide 15 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
~100 Гб данных для обработки
ежедневно
Написан на Python + Pandas +
Polars + scikit
Запускается в k8s на ноде
(500 Гб оперативной памяти
и 64 CPU ядра)
20 375 строк python кода
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 16
Slide 16 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
~100 Гб данных для обработки
ежедневно
Написан на Python + Pandas +
Polars + scikit
Запускается в k8s на ноде
(500 Гб оперативной памяти
и 64 CPU ядра)
20 375 строк python кода
Много бизнес-логики
на разных этапах
формирования данных
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 17
Slide 17 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
~100 Гб данных для обработки
ежедневно
Написан на Python + Pandas +
Polars + scikit
Запускается в k8s на ноде
(500 Гб оперативной памяти
и 64 CPU ядра)
20 375 строк python кода
Много бизнес-логики
на разных этапах
формирования данных
268М регулярных
предсказаний еженедельно
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 18
Slide 18 text
Характеристики системы прогноза спроса
Технические
характеристики:
Бизнес-
характеристики:
~100 Гб данных для обработки
ежедневно
Написан на Python + Pandas +
Polars + scikit
Запускается в k8s на ноде
(500 Гб оперативной памяти
и 64 CPU ядра)
20 375 строк python кода
Много бизнес-логики
на разных этапах
формирования данных
268М регулярных
предсказаний еженедельно
100М предсказаний
с учетом промо акции
Airflow Kubernetes
DWH
MSSQL
S3
S3
Demand-
prediction
Slide 19
Slide 19 text
и с какими проблемами мы столкнулись:
Как устроена
обработка
ML model
Train Data
SpawnProcess
warehouse=1
ML-App with
multiprocessing
SpawnProcess
warehouse=2
SpawnProcess
warehouse=n
…
Slide 20
Slide 20 text
и с какими проблемами мы столкнулись:
Как устроена
обработка
ML model
Train Data
SpawnProcess
warehouse=1
ML-App with
multiprocessing
SpawnProcess
warehouse=2
SpawnProcess
warehouse=n
Резкое увеличение количества
дарксторов. (01)
…
Slide 21
Slide 21 text
и с какими проблемами мы столкнулись:
Невозможность дальнейшего
масштабирования
на тот момент мы уже потребляли
около 450 Гб оперативной памяти. (02)
Как устроена
обработка
ML model
Train Data
SpawnProcess
warehouse=1
ML-App with
multiprocessing
SpawnProcess
warehouse=2
SpawnProcess
warehouse=n
Резкое увеличение количества
дарксторов. (01)
…
Slide 22
Slide 22 text
и с какими проблемами мы столкнулись:
Перестали укладываться
в SLA (24 часа).
Невозможность дальнейшего
масштабирования
на тот момент мы уже потребляли
около 450 Гб оперативной памяти. (02)
(03)
Как устроена
обработка
ML model
Train Data
SpawnProcess
warehouse=1
ML-App with
multiprocessing
SpawnProcess
warehouse=2
SpawnProcess
warehouse=n
Резкое увеличение количества
дарксторов. (01)
…
Slide 23
Slide 23 text
РЕШЕНИЕ
ПРОБЛЕМЫ
Slide 24
Slide 24 text
Альтернативные способы решения
Slide 25
Slide 25 text
Альтернативные способы решения
Использовать Spark вместо
Pandas
Spark позволил бы
масштабироваться
горизантально, но пришлось
бы переписать весь проект,
на что ресурсов не было.
Slide 26
Slide 26 text
Альтернативные способы решения
Использовать Spark вместо
Pandas
Spark позволил бы
масштабироваться
горизантально, но пришлось
бы переписать весь проект,
на что ресурсов не было.
Увеличить количество
процессов
Мы уже уперлись
в максимальный размер
ноды (500 Гб оперативной
памяти).
Slide 27
Slide 27 text
Альтернативные способы решения
Использовать Spark вместо
Pandas
Spark позволил бы
масштабироваться
горизантально, но пришлось
бы переписать весь проект,
на что ресурсов не было.
Увеличить количество
процессов
Мы уже уперлись
в максимальный размер
ноды (500 Гб оперативной
памяти).
Переписать отдельные
участки кода без
использования apply()
Как вариант, но не даст
того же прироста по
скорости,
как рефакторинг вместе
с миграцией на Polars.
Slide 28
Slide 28 text
Альтернативные способы решения
Использовать Spark вместо
Pandas
Spark позволил бы
масштабироваться
горизантально, но пришлось
бы переписать весь проект,
на что ресурсов не было.
Увеличить количество
процессов
Мы уже уперлись
в максимальный размер
ноды (500 Гб оперативной
памяти).
Переписать отдельные
участки кода без
использования apply()
Как вариант, но не даст
того же прироста по
скорости,
как рефакторинг вместе
с миграцией на Polars.
Аналитическая БД?
(1) Много расчетов и
бизнес- логики, которую
трудно поддерживать на
уровне запросов к БД.
(2) Исходные данные —
из нескольких источников.
Slide 29
Slide 29 text
Установить
профилировщик
Профилировщик
позволяет в удобном виде
проанализировать и найти
наиболее долгие функции.
Например: line_profiler.
Сбор аналитики
После настройки
профилировщик
необходимо запустить
обработку.
Поиск медленных
функций
После сбора аналитики
находим самые медленные
функций. Оцениваем
количество кода и
целесообразность
рефакторинга.
Создание задач на
рефакторинг
Оцениваем сроки
миграции, создаём задачи
на рефакторинг.
Приоритет задачи
определяется количеством
кода для рефакторинга.
Как организовать
процесс миграции
Сперва необходимо найти «bottleneck»
функции
Slide 30
Slide 30 text
Пишем
юнит-тесты
Если в проекте нет
юнит-тестов, то нужно их
написать.
Берутся реальные
входные и выходные
датасеты для функции.
Рефакторинг
Переписываем целую
функцию с pandas на
Polars. Из Polars в Pandas
конвертируем методом
to_pandas()
Оценка
результата
С помощью
профилировщика
оцениваем результат
рефакторинга.
Далее начинаем процесс рефакторинга
Как организовать
процесс миграции
Slide 31
Slide 31 text
Результаты миграции
Достижения
• Переписав несколько функций, мы получили
ускорение нашего пайплайна с 24 до 16
часов, что позволило нам уложиться в SLA.
[01]
Slide 32
Slide 32 text
Результаты миграции
Достижения
• Переписав несколько функций, мы получили
ускорение нашего пайплайна с 24 до 16
часов, что позволило нам уложиться в SLA.
• На полный процесс миграции одной
функции уходило от нескольких дней
до 3 недель.
[01]
Slide 33
Slide 33 text
Результаты миграции
Достижения
• Переписав несколько функций, мы получили
ускорение нашего пайплайна с 24 до 16
часов, что позволило нам уложиться в SLA.
• На полный процесс миграции одной
функции уходило от нескольких дней
до 3 недель.
• Уменьшили расходы на инфраструктуру.
[01]
Slide 34
Slide 34 text
Результаты миграции
Достижения
• Переписав несколько функций, мы получили
ускорение нашего пайплайна с 24 до 16
часов, что позволило нам уложиться в SLA.
• На полный процесс миграции одной
функции уходило от нескольких дней
до 3 недель.
• Уменьшили расходы на инфраструктуру.
Минусы [02]
[01]
Slide 35
Slide 35 text
Результаты миграции
Достижения
• Переписав несколько функций, мы получили
ускорение нашего пайплайна с 24 до 16
часов, что позволило нам уложиться в SLA.
• На полный процесс миграции одной
функции уходило от нескольких дней
до 3 недель.
• Уменьшили расходы на инфраструктуру.
Минусы
• Увеличилась длительность юнит-тестов.
[02]
[01]
Slide 36
Slide 36 text
Результаты миграции
Достижения
• Переписав несколько функций, мы получили
ускорение нашего пайплайна с 24 до 16
часов, что позволило нам уложиться в SLA.
• На полный процесс миграции одной
функции уходило от нескольких дней
до 3 недель.
• Уменьшили расходы на инфраструктуру.
Минусы
• Увеличилась длительность юнит-тестов.
• В случае нового увеличения количества
складов необходима дальнейшая
оптимизация или миграция на кластерные
вычисления.
[02]
[01]
Slide 37
Slide 37 text
POLARS И ЕГО
ПРЕИМУЩЕСТ
ВА
Slide 38
Slide 38 text
Что за Polars?
и почему
мы его выбрали?
Slide 39
Slide 39 text
Что за Polars и почему мы его выбрали?
Polars — это библиотека для работы с наборами данных
(Dataframes) поверх механизма запросов OLAP, реализованный
на Rust с использованием формата столбцов Apache Arrow
в качестве модели памяти.
Slide 40
Slide 40 text
МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ
(01)
В отличии от Pandas большинство операций в
Polars выполняются на всех доступных ядрах
процессора. Также есть возможность
конфигурировать количество активных потоков.
Что за Polars и почему мы его выбрали?
Polars — это библиотека для работы с наборами данных
(Dataframes) поверх механизма запросов OLAP, реализованный
на Rust с использованием формата столбцов Apache Arrow
в качестве модели памяти.
Slide 41
Slide 41 text
МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ
(01)
В отличии от Pandas большинство операций в
Polars выполняются на всех доступных ядрах
процессора. Также есть возможность
конфигурировать количество активных потоков.
НЕ НУЖНО СОЗДАВАТЬ КЛАСТЕР
ДЛЯ ВЫЧИСЛЕНИЙ
(02)
В инструментах, как Spark, необходимо
поднимать кластер вычислений.
Что за Polars и почему мы его выбрали?
Polars — это библиотека для работы с наборами данных
(Dataframes) поверх механизма запросов OLAP, реализованный
на Rust с использованием формата столбцов Apache Arrow
в качестве модели памяти.
Slide 42
Slide 42 text
МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ
(01)
В отличии от Pandas большинство операций в
Polars выполняются на всех доступных ядрах
процессора. Также есть возможность
конфигурировать количество активных потоков.
ВОЗМОЖНОСТЬ ЧАСТИЧНОЙ
МИГРАЦИИ
(03)
Можно проводить рефакторинг кода
по функциям, так как датафрейм можно
быстро сконвертировать в Pandas формат.
НЕ НУЖНО СОЗДАВАТЬ КЛАСТЕР
ДЛЯ ВЫЧИСЛЕНИЙ
(02)
В инструментах, как Spark, необходимо
поднимать кластер вычислений.
Что за Polars и почему мы его выбрали?
Polars — это библиотека для работы с наборами данных
(Dataframes) поверх механизма запросов OLAP, реализованный
на Rust с использованием формата столбцов Apache Arrow
в качестве модели памяти.
Slide 43
Slide 43 text
МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ
(01)
В отличии от Pandas большинство операций в
Polars выполняются на всех доступных ядрах
процессора. Также есть возможность
конфигурировать количество активных потоков.
ВОЗМОЖНОСТЬ ЧАСТИЧНОЙ
МИГРАЦИИ
(03)
Можно проводить рефакторинг кода
по функциям, так как датафрейм можно
быстро сконвертировать в Pandas формат.
НЕ НУЖНО СОЗДАВАТЬ КЛАСТЕР
ДЛЯ ВЫЧИСЛЕНИЙ
(02)
В инструментах, как Spark, необходимо
поднимать кластер вычислений.
СПЕЦИФИКАЦИЯ ARROW
(04)
Данные в памяти хранятся в формате Arrow,
что позволяет эффективнее использовать
процессор.
Что за Polars и почему мы его выбрали?
Polars — это библиотека для работы с наборами данных
(Dataframes) поверх механизма запросов OLAP, реализованный
на Rust с использованием формата столбцов Apache Arrow
в качестве модели памяти.
Slide 44
Slide 44 text
Отсутствие индекса
Apache Arrow vs Numpy
В Pandas каждой строке назначается
индекс, который обозначает позицию
строки в датафрейме. В Polars отказались
от этого механизма.
Pandas для хранения данных использует
Numpy, но Polars использует Arrow, модель
которого более оптимизированно
использует оперативную память для
хранения данных.
Ключевые отличия Pandas и Polars
Slide 45
Slide 45 text
Параллельные
вычисления
Для параллелизации вычислений
в Pandas необходимо использовать
инструменты Dask или Modin.
Ленивые вычисления
В Polars есть механизм оптимизации
плана запроса, что позволяет ускорить
вычисления.
Ключевые отличия Pandas и Polars
Slide 46
Slide 46 text
Параллелизация вычислений
Разбиение данных
Данные разбиваются на несколько групп
и вычисления производятся
параллельно над каждой из групп.
Хеш таблицы
В операциях groupby и join создаются
хеш таблицы, в Polars они вычисляются
параллельно.
Slide 47
Slide 47 text
Ленивая оптимизация запросов
Для любого ленивого запроса
Polars имеет:
▪ неоптимизированный план с
набором шагов кода, как мы
его предоставили
▪ оптимизированный план с
изменениями, внесёнными
оптимизатором запросов.
Имеется возможность
рассмотреть как
неоптимизированные, так и
оптимизированные планы
запросов с помощью
визуализации и путём их
печати в виде текста.
Slide 48
Slide 48 text
Ленивая
оптимизация
запросов
WITH COLUMNS [col(“Fare”).round()] WITH COLUMNS [col(“Fare”).round()]
Parquet SCAN titanic.parquet
π 3/12;
σ[(col(“Survived”))=(1)]
Parquet SCAN titanic.parquet
π */12;
σ None
FILTER BY [(col(“Survived”))==(1)]
π 3/3
Без оптимизаций запросов С оптимизацией запросов
Slide 49
Slide 49 text
Операция Pandas Polars
Импорт import pandas as pd import polars as pl
Выбор Данных
df['a']
df.loc[:,'a']
df.select('a')
Фильтрация
df.loc[df["a"] < 10,]
df[df["a"] < 10]
df.query("a < 10")
df.filter(pl.col('a') < 10)
Присваивание по
столбцам
df.assign(b=lambda df_: df_.a * 10)
df["b"] = df["a"] * 10
df.with_columns(a=pl.col("a") * 10)
Ленивые
вычисления - scan_csv("data.csv").some_computations().collect()
Пропущенные
значения float('nan'), np.nan, None
null
float('nan'), np.nan == NotaNumber
Сравнение синтаксиса Polars и Pandas
Slide 50
Slide 50 text
СРАВНЕНИЕ
БЫСТРОДЕЙСТВ
ИЯ БИБЛИОТЕК
Slide 51
Slide 51 text
Тесты быстродействия
▪ 80 Гб оперативной
памяти, DDR4-3200
Набор данных:
Parquet файлы разных
размеров:
200, 400, 800,
1600, 3200, 6400 Мб
▪ 20 CPU ядер, Intel® Xeon®
Gold 6354, 3.00 GHz
Машина для проведения тестов:
Slide 52
Slide 52 text
Сравнение Polars с альтернативами
Чтение parquet файлов (меньше = лучше)