Apache Spark — это популярная платформа с открытым исходным кодом для крупномасштабной обработки данных, которая хорошо подходит для итеративных задач машинного обучения. В этой статье мы представляем MLlib, распределенную библиотеку машинного обучения Spark с открытым исходным кодом. MLlib обеспечивает эффективную функциональность для широкого диапазона настроек обучения и включает в себя несколько основных примитивов статистики, оптимизации и линейной алгебры. Поставляемая со Spark, MLlib поддерживает несколько языков и предоставляет высокоуровневый API, который использует богатую экосистему Spark для упрощения разработки сквозных конвейеров машинного обучения. MLlib пережил быстрый рост благодаря активному сообществу открытого исходного кода, насчитывающему более 140 участников, и включает в себя обширную документацию для поддержки дальнейшего роста и предоставления пользователям возможности быстро освоиться.

1. Введение

Современные наборы данных быстро увеличиваются в размерах и сложности, и существует острая необходимость в разработке решений для использования этого богатства данных с использованием статистических методов. Для крупномасштабной обработки данных было разработано несколько механизмов потоков данных «следующего поколения», которые обобщают MapReduce (Dean and Ghemawat, 2004), и создание функций машинного обучения на этих механизмах представляет большой интерес. В частности, Apache Spark (Zaharia et al., 2012) стал широко используемым движком с открытым исходным кодом. Spark — это отказоустойчивая система кластерных вычислений общего назначения, предоставляющая API-интерфейсы на Java, Scala, Python и R, а также оптимизированный движок, поддерживающий общие графы выполнения. Кроме того, Spark эффективен при итерационных вычислениях и поэтому хорошо подходит для разработки крупномасштабных приложений машинного обучения.

В этой работе мы представляем MLlib, распределенную библиотеку машинного обучения Spark и самую большую такую ​​библиотеку. Библиотека нацелена на крупномасштабные настройки обучения, которые выигрывают от параллелизма данных или параллелизма моделей для хранения и работы с данными или моделями. MLlib состоит из быстрых и масштабируемых реализаций стандартных алгоритмов обучения для общих настроек обучения, включая классификацию, регрессию, совместную фильтрацию, кластеризацию и уменьшение размерности. Он также предоставляет различные базовые статистические данные, линейную алгебру и примитивы оптимизации. Написанная на Scala и использующая собственные (на основе C++) библиотеки линейной алгебры на каждом узле, MLlib включает API-интерфейсы Java, Scala и Python и выпускается как часть проекта Spark под лицензией Apache 2.0.

Тесная интеграция MLlib со Spark дает несколько преимуществ. Во-первых, поскольку Spark разработан с учетом итерационных вычислений, он позволяет разрабатывать эффективные реализации крупномасштабных алгоритмов машинного обучения, поскольку они обычно носят итеративный характер. Улучшения в низкоуровневых компонентах Spark часто приводят к повышению производительности MLlib без каких-либо прямых изменений в самой библиотеке. Во-вторых, активное сообщество Spark с открытым исходным кодом привело к быстрому росту и принятию MLlib, включая вклад более 140 человек. В-третьих, MLlib — это одна из нескольких высокоуровневых библиотек, созданных поверх Spark, как показано на рис. 1(а). Являясь частью богатой экосистемы Spark и отчасти благодаря API-интерфейсу MLlib spark.ml для разработки конвейеров, MLlib предоставляет разработчикам широкий спектр инструментов, упрощающих разработку конвейеров машинного обучения на практике.

2. История и рост

Spark был запущен в AMPLab Калифорнийского университета в Беркли и стал открытым исходным кодом в 2010 году. Spark предназначен для эффективных итерационных вычислений, и, начиная с ранних выпусков, он содержит примеры алгоритмов машинного обучения. Однако до создания MLlib ему не хватало набора надежных и масштабируемых алгоритмов обучения. Разработка MLlib началась в 2012 году в рамках проекта MLbase (Kraska et al., 2013), а в сентябре 2013 года исходный код MLlib был открыт. выпуск Spark 0.8. Как проект Apache, Spark (и, следовательно, MLlib) имеет открытый исходный код под лицензией Apache 2.0. Более того, начиная с Spark версии 1.0, Spark и MLlib находятся на 3-месячном цикле выпуска. Первоначальная версия MLlib была разработана в Калифорнийском университете в Беркли 11 участниками и предоставляла ограниченный набор стандартных методов машинного обучения. С момента выхода этого оригинального релиза число участников MLlib резко возросло. Менее чем через два года после выпуска Spark 1.4 у MLlib более 140 участников из более чем 50 организаций. Рисунок 1(b) демонстрирует рост сообщества открытого исходного кода MLlib в зависимости от версии выпуска. Сила этого сообщества с открытым исходным кодом стимулировала разработку широкого спектра дополнительных функций.

3. Основные характеристики

В этом разделе мы выделяем основные функции MLlib; мы отсылаем читателя к руководству пользователя MLlib для получения дополнительной информации (MLlib, 2015).

Поддерживаемые методы и утилиты. MLlib обеспечивает быстрые распределенные реализации распространенных алгоритмов обучения, включая (но не ограничиваясь ими): различные линейные модели, наивные байесовские модели и ансамбли деревьев решений для задач классификации и регрессии; чередование метода наименьших квадратов с явной и неявной обратной связью для совместной фильтрации; и кластеризация k-средних и анализ основных компонентов для кластеризации и уменьшения размерности. Библиотека также предоставляет ряд низкоуровневых примитивов и основных утилит для выпуклой оптимизации, распределенной линейной алгебры, статистического анализа и извлечения признаков, а также поддерживает различные форматы ввода-вывода, включая встроенную поддержку формата LIBSVM, интеграцию данных через Spark SQL ( Armbrust et al., 2015), а также PMML (Guazzelli et al., 2009) и внутренний формат MLlib для экспорта моделей.

Алгоритмическая оптимизация. MLlib включает множество оптимизаций для поддержки эффективного распределенного обучения и прогнозирования. Здесь мы выделяем несколько случаев. Алгоритм ALS для рекомендации осторожно использует блокировку, чтобы уменьшить накладные расходы на сборку мусора JVM и использовать операции линейной алгебры более высокого уровня. В деревьях решений используются многие идеи из проекта PLANET (Panda et al., 2009), такие как дискретизация признаков в зависимости от данных для снижения затрат на связь, а ансамбли деревьев распараллеливают обучение как внутри деревьев, так и между деревьями. Обобщенные линейные модели изучаются с помощью алгоритмов оптимизации, которые распараллеливают вычисления градиента с использованием быстрых библиотек линейной алгебры на основе C++ для рабочих вычислений. Многие алгоритмы выигрывают от эффективных коммуникационных примитивов; в частности, агрегация с древовидной структурой не позволяет драйверу стать узким местом, а широковещательная рассылка Spark быстро распространяет большие модели среди рабочих.

Pipeline API. Практические конвейеры машинного обучения часто включают последовательность этапов предварительной обработки данных, извлечения признаков, подгонки модели и проверки. Большинство библиотек машинного обучения не обеспечивают встроенную поддержку разнообразного набора функций, необходимых для построения конвейера. Особенно при работе с крупномасштабными наборами данных процесс сборки сквозного конвейера является одновременно трудоемким и дорогостоящим с точки зрения сетевых накладных расходов. Используя богатую экосистему Spark и вдохновившись предыдущими работами (Pedregosa et al., 2011; Buitinck et al., 2013; Sparks et al., 2013, 2015), MLlib включает пакет, предназначенный для решения этих проблем. Этот пакет под названием spark.ml упрощает разработку и настройку многоступенчатых конвейеров обучения, предоставляя единый набор высокоуровневых API (Meng et al., 2015), включая API, которые позволяют пользователям заменять стандартный подход к обучению. вместо собственных специализированных алгоритмов.

Интеграция со Spark. MLlib использует различные компоненты экосистемы Spark. На самом низком уровне ядро ​​Spark предоставляет общий исполнительный механизм с более чем 80 операторами для преобразования данных, например, для очистки данных и придания им свойств. MLlib также использует другие высокоуровневые библиотеки, входящие в состав Spark. Spark SQL обеспечивает функциональность интеграции данных, SQL и обработку структурированных данных, которые могут упростить очистку и предварительную обработку данных, а также поддерживает абстракцию DataFrame, которая является фундаментальной для пакета spark.ml. GraphX ​​(Gonzalez et al., 2014) поддерживает крупномасштабную обработку графов и предоставляет мощный API для реализации алгоритмов обучения, которые естественным образом можно рассматривать как задачи с большими разреженными графами, например LDA (Blei et al., 2003; Bradley, 2015). ). Кроме того, Spark Streaming (Zaharia et al., 2013) позволяет пользователям обрабатывать потоки данных в реальном времени и, таким образом, позволяет разрабатывать алгоритмы онлайн-обучения, как в Freeman (2015). Более того, повышение производительности ядра Spark и этих высокоуровневых библиотек приводит к соответствующим улучшениям в MLlib.

Документация, сообщество и зависимости. Руководство пользователя MLlib содержит обширную документацию; он описывает все поддерживаемые методы и утилиты и включает несколько примеров кода вместе с документацией по API для всех поддерживаемых языков (MLlib, 2015). В руководстве пользователя также перечислены зависимости кода MLlib, которыми, начиная с версии 1.4, являются следующие библиотеки с открытым исходным кодом: Breeze, netlib-java и (в Python) NumPy (Breeze, 2015; Halliday, 2015; Braun, 2015; NumPy, 2015). Кроме того, как часть экосистемы Spark, MLlib имеет активные списки рассылки сообщества, частые встречи и отслеживание проблем JIRA для облегчения участия в открытом исходном коде (Community, 2015). Для дальнейшего поощрения вклада сообщества Spark Packages (Packages, 2015) предоставляет индекс пакетов сообщества для отслеживания растущего числа пакетов и библиотек с открытым исходным кодом, которые работают со Spark. На сегодняшний день несколько предоставленных пакетов содержат функции машинного обучения, основанные на MLlib.

Наконец, был создан массовый открытый онлайн-курс для описания основных алгоритмических концепций, используемых для разработки распределенных реализаций в MLlib (Talwalkar, 2015).

4. Производительность и масштабируемость

В этом разделе мы кратко продемонстрируем скорость, масштабируемость и постоянные улучшения MLlib с течением времени. Сначала мы рассмотрим масштабируемость, рассмотрев ALS, широко используемый подход к совместной фильтрации. Для этого эталонного теста мы работали с масштабированными копиями набора данных Amazon Reviews (McAuley and Leskovec, 2013), где мы дублировали информацию о пользователях по мере необходимости для увеличения размера данных. Мы выполнили 5 итераций ALS MLlib для различных масштабированных копий набора данных, запущенных в кластере EC2 из 16 узлов с экземплярами m3.2xlarge с использованием MLlib версий 1.1 и 1.4. Для сравнения мы провели тот же эксперимент с Apache Mahout версии 0.9 (Mahout, 2014 г.), который работает на Hadoop MapReduce. Результаты сравнительного анализа, представленные на рис. 2(а), демонстрируют, что накладные расходы MapReduce на планирование и отсутствие поддержки итеративных вычислений существенно снижают его производительность на наборах данных среднего размера. Напротив, MLlib демонстрирует превосходную производительность и масштабируемость и фактически может масштабироваться для решения гораздо более серьезных задач.

Затем мы сравниваем MLlib версий 1.0 и 1.1, чтобы оценить улучшения с течением времени. Мы измеряем производительность распространенных методов машинного обучения в MLlib, при этом все эксперименты проводились на EC2 с использованием инстансов m3.2xlarge с 16 рабочими узлами и синтетических наборов данных из пакета spark-perf (https://github.com/databricks/spark-perf). ). Результаты представлены на рис. 2(b) и показывают ускорение в среднем в 3 раза по всем алгоритмам. Эти результаты обусловлены конкретными алгоритмическими улучшениями (как в случае ALS и деревьев решений), а также общими улучшениями протоколов связи в Spark и MLlib в версии 1.1 (Явуз и Менг, 2014).

5. Заключение

MLlib находится в активной разработке, и по следующей ссылке можно узнать, как внести свой вклад: https://cwiki.apache.org/confluence/display/SPARK/Contributing+to+Spark. Кроме того, мы хотели бы поблагодарить всех участников MLlib. Список участников Spark можно найти по адресу https://github.com/apache/spark, а для идентификации участников MLlib можно использовать команду git log.