Пайплайн машинного
обучения на Apache
Spark
Павел Клеменков, Rambler&Co
p.klemenkov@rambler-co.ru
Remember when Rambler used to be a search engine?
Pepperidge Farm remembers
Мотивационный пример
• Обучили модель CTR (PySpark,
vowpal wabbit
• Предикт ~= baseline CTR
• Закинули модель в сервис
(Vert.X, VW JNI)
• Предикт != baseline CTR
• В чем дело?
• Из-за sparse-формата,
потерялись некоторые фичи
Что хотим от математика-программиста?
• Качественные эксперименты быстро
• Доведение эксперимента до продакшена
• Поддержка и багфиксы
WTF is this shit?!
All my code works!
And I didn’t break the build!
Качественный эксперимент быстро
• Знакомое окружение
• Все новое и крутое
• Витрина фич
Эксперимент в продакшене
• Простое тестирование
• Окружение как на продакшене
• Автоматизация
Эксплуатация и багфиксы
• Простой и наглядный мониторинг
• Адресные оповещения
• Доступная отладка
С чего стартовали?
HDFS
+
Hive
SCP
NFS
Custom
scripts
Redis
Cluster
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
Monitoring
(DIY)
ML
(local)
You got a problem
with that?!
+
HDFS
+
Hive
SCP
NFS
Custom
scripts
Redis
Cluster
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
Monitoring
(DIY)
ML
(local)
HDFS
+
Hive
Redis
Cluster
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
Monitoring
(DIY)
ML
(local)
Kafka
Gobblin
HDFS
+
Hive
Redis
Cluster
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
Monitoring
(DIY)
ML
(local)
Kafka
Gobblin
HDFS
+
Hive
Aerospike
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
Monitoring
(DIY)
ML
(local)
Kafka
Gobblin
HDFS
+
Hive
Aerospike
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
Monitoring
(DIY)
ML
(local)
Kafka
Gobblin
HDFS
+
Hive
Aerospike
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
ML
(local)
Kafka
Gobblin
Graphite Grafana
HDFS
+
Hive
Aerospike
Hive
streaming
ML
(local)
Cron +
joblocker
Hive
streaming
ML
(local)
Kafka
Gobblin
Graphite Grafana
HDFS
+
Hive
Aerospike
Hive
streaming
ML
(local)
Airflow
Hive
streaming
ML
(local)
Kafka
Gobblin
Graphite Grafana
HDFS
+
Hive
Aerospike
Hive
streaming
ML
(local)
Airflow
Hive
streaming
ML
(local)
Kafka
Gobblin
Graphite Grafana
Со стриммингом одни проблемы (
Diagnostic Messages for this Task:
Error: java.lang.RuntimeException: Hive Runtime Error
while closing operators
SELECT TRANSFORM(*) USING 'python script.py'
FROM table;
И даже тесты не помогут…
INSERT OVERWRITE TABLE predict
SELECT TRANSFORM(line)
FROM features_table
USING 'umworld_caller.py apply -f model.vw'
AS uid, probabilities;
Traceback (most recent call last)
----> uid, probabilities =
'0000000149C7211B6A53058C0942A001 1.3752,-
0.37520000000149BBA4BF2CC10CD6043D1401 1.3752,-
0.3752'
ValueError: too many values to unpack
Очень долго готовить данные
Типичный алгоритм эксперимента
• Выгрузить сэмпл из Hive
• Сконвертировать в Pandas
• Поиграть с данными
• Понять, что чего-то не хватает
• Выгрузить другой сэмпл из Hive…
HDFS
+
Hive
Aerospike
Hive
streaming
Airflow
Kafka
Gobblin
Graphite Grafana
Spark +
ML
Почему ?
It is in-memory and
there is a Python API!
Pandas vs Spark Dataframe
import pandas as pd
!hive -e "select * from
users" > dt.csv
df = pd.read_csv("dt.csv")
counts = df[df.age > 30]
.groupby("sex")
.count()
from pyspark.sql import
HiveContext
ctx = HiveContext(sc)
df = ctx.sql("select * from
users")
counts = df[df.age > 30]
.groupby("sex")
.count()
А на самом деле…
SPARK-15139
PySPark TreeEnsemble
missing methods
SPARK-18177
Add missing ‘subsamplingRate’
of pyspark GBTClassifier
SPARK-17025
Cannot persist PySpark ML
Pipeline model that includes
custom Transformer
SPARK-15194
Add Python ML API for
MultivariateGaussian
Архитектура Spark
Resilient
Distributed
Dataset
rdd1.join(rdd2)
.groupby(...)
.filter(...)
RDD
Partition
Partition
Partition
Partition
Job
Stage
Task
Task
Task
Task
action
Driver
SparkContext
Cluster
Manager
Worker Node
Executor Cache
Task Task
Worker Node
Executor Cache
Task Task
Урок №1
При запуске задачи необходимо явно
указывать требуемые ресурсы. Это
сильно упрощает жизнь
Урок №2
При запуске задачи необходимо явно
указывать требуемые ресурсы. Это
сильно усложняет жизнь
Narrow (no shuffle):
• map
• flatMap
• filter
• sample
Wide (shuffle):
• sortByKey
• reduceByKey
• groupByKey
• join
Урок №3
Избегайте shuffle
Вся прелесть DataFrame
Почему DataFrame
такой быстрый?
• RDD – низкоуровневый API без оптимизаций
• DataFrame – это Spark SQL
• Catalyst – оптимизатор запросов
• Tungsten Execution Backend
Урок №4
Используя DataFrame можно меньше
париться про оптимизацию
вычислений
Урок №5
При чтении из Hive, Spark создает
партиции по числу бакетов таблицы
Use XGBoost, Luke
© Unknown Kaggler
Почему мы не используем
Spark.ML?
Причина №1
• Vowpal Wabbit и XGBoost в старом пайплайне
• Новый код для напилки фич
Причина №2
SPARK-14374
PySpark ml GBTClassifier, Regressor
support export/import
(Resolved: 15/Apr/16)
SPARK-13034
PySpark ml.classification support
export/import
(Resolved: 16/Mar/16)
Причина №3Качествонаобучении
Объем обучающей выборки
Но мы верили, что
все изменится :)
Поэтому поддержали API Spark.ML
from pyspark.ml.pipeline import Transformer
class BaseTransformer(Transformer):
def __init__(self, day=None)
def fit(self, df)
def _transform(self, df)
def load(self, timestamp)
def save(self, timestamp)
Spark
Context
Py4J
Spark
Context
Local
FS
Spark
Worker
Spark
Worker
Python
Python
Python
Python
Python
Python
Socket
Pipe
Python JVM
Урок №6
При работе с PySpark overhead есть не
только у самого Python, но и на
перегонку объектов в/из JVM
Урок №7
Для сериализации используется
cloudpickle, а он не всемогущ
Talk is cheap.
Show me the code!
class SparkXGBoostClassifier(SparkSklearnClassifier):
def predict_proba(self, df):
rdd = df.map(self._create_dataset)
df = rdd.toDF()[['uid', 'feature']]
v_model = df._sc.broadcast(self.model)
res = df.rdd.mapPartitionsWithIndex(
partial(apply_model, v_model=v_model))
return res
Timing (100 executors – 8gb, 2 vcores)
Подзадача Время
Загрузить и сджойнить фичи 0:08:49
Сконвертировать трейн в Pandas 0:07:43
Настройка модели 0:01:44
Вычисление качества 0:04:44
Применение модели 0:46:07
Сконвертировать вероятность в ответ 0:02:24
Итого 1:13:05
Those, who ask questions.
You da real MVP!

Пайплайн машинного обучения на Apache Spark / Павел Клеменков (Rambler&Co)