Соавтор

Этот блог создан совместно с Эриком Паком.

Приквел

Это история о том, как мы, специалисты по обработке данных и инженеры по машинному обучению в Zendesk, вышли из темной эры инструментов машинного обучения, создали собственный инструментарий pakkr pipeline и поделились им с мир.

The Dark Age: Life Pre-pakkr и как мы пришли сюда

В настоящее время многие компании говорят о важности конвейеров данных. Хороший конвейер машинного обучения помогает специалистам по обработке данных сократить время разработки моделей и эффективно производить продукты машинного обучения. Предварительный конвейер жизни довольно сложен для любой команды, занимающейся обработкой данных: код нелегко поддерживать, развертывать, масштабировать и повторно использовать. Zendesk не исключение.

Еще в 2017 году, когда команда Zendesk Data Science работала над замечательным продуктом под названием Content Cues, нам не хватало инструментов для написания более чистого, быстрого и готового к работе кода. Хотя конвейерная обработка не является новой концепцией в области программного обеспечения, в то время было доступно несколько инструментов конвейерной обработки. Scikit-learn Pipeline и Airflow - некоторые примеры, но они либо слишком тяжелы, либо не имеют необходимого уровня абстракции для нужд нашей команды. .

Scikit-learn Pipeline требует, чтобы каждый шаг был объектом оценщика для реализации определенного интерфейса, а именно transformandfitmethods. Эта парадигма подходит для последовательного преобразования / вывода, но слишком ограничительна для ситуаций, когда шаг дает несколько выходных данных, и не все из них будут использованы в шаге сразу после него. Возьмем, к примеру, следующую диаграмму.

Представьте, что вы работаете над 4-этапным конвейером, состоящим из

  1. Загрузить и преобразовать
  2. Модель поезда
  3. Использовать модель
  4. Сохраните результаты.

Допустим, у вас есть данные и файл конфигурации для настройки конвейера. Сначала вы загружаете и преобразуете данные, указанные в awesome_config.

input_data_path: s3://input-bucket/source-features
result_output_path: my_directory
model_params: {learning_rate: 0.00001, ...}

Затем вы разделяете данные на train_data и test_data.

Затем вы замечаете, что передать train_dataи input_data_path на следующий шаг конвейера обучения Scikit очень просто. Однако при попытке передать test_dataproduced в Load & Transform (шаг 1) в Test Model (шаг 3) становится сложно перемещать данные. То же, что и передачаresult_output_path в конфигурации, определенной в шаге 1 для Сохранить результаты (шаг 4). Теперь вы видите, что находитесь в очень сложной ситуации.

Дизайн взаимосвязанного конвейера просто не соответствует традиционной парадигме рабочего процесса / конвейера машинного обучения, которая требует менее строгой абстракции и настройки / управления косвенными зависимостями.

Airflow реализует Направленный ациклический график (DAG) для удовлетворения этих требований. Вышеупомянутая ситуация может выглядеть следующим образом в форме DAG.

Тем не менее создание группы доступности базы данных трудоемко, потому что

  • каждый шаг должен быть определен в первую очередь
  • все шаги должны быть созданы
  • управление отношениями между каждым узлом графа является необходимостью

Неудовлетворенный существующими на тот момент решениями, в одну волшебную ночь, когда все остальные в команде гуляли на фестивале джазовой музыки в Мельбурне, наш штатный инженер Эрик Пак один в офисе в Мельбурне открыл свой Ноутбук и начал писать то, что позже стало легендарным конвейером pakkr. (Классный блог Эрика по машиностроению машинного обучения в настоящее время находится в разработке. Следите за обновлениями!)

PS. Эрик часто работает на музыкальных фестивалях. Ниже приведена фотография, на которой он размышляет в блокноте во время выступления Sidney Myer Music Bowl.

Происхождение: дизайн-мышление и сценарии использования

pakkr находит золотую середину между Scikit-learn Pipeline и Airflow Pipeline с точки зрения сложности. Он сочетает в себе последовательное дизайнерское мышление (чтобы оно соответствовало рабочему процессу проекта машинного обучения) с гибкой абстракцией и настройкой и управлением косвенными зависимостями. pakkr достигает этого за счет реализации трех основных концепций: вызов, управление зависимостями и конфигурация.

Вот краткое представление о том, как pakkr работает с набором данных Fisher’s Iris, прежде чем мы углубимся в технические объяснения.

Призыв

Абстракция pakkr очень общая, поскольку pakkr требует, чтобы каждый шаг был Callable. Другими словами, шагом может быть просто функция или объект, реализующий __call__ Dunder (он же двойное подчеркивание или магический метод). Таким образом, pakkr объединяет простые функции преобразования, а также преобразования, требующие более сложного создания экземпляров.

И если мы сделаем шаг (каламбур) назад, поскольку конвейер также является Callable, pakkr может использовать экземпляры конвейера как шаги в других конвейерах. Это не только обеспечивает возможность повторного использования, но и способствует модульности.

Управление зависимостями

Подумайте о примере, который мы представили ранее: без использования какой-либо библиотеки, как бы вы реализовать конвейер, состоящий из 4 последовательных шагов? Если вы используете python, вы можете написать это так:

def pipeline():
train_data, test_data, awesome_config = load_and_transform()
model = train_model(train_data, awesome_config)
results = test_model(model, test_data)
save_results(results, awesome_config)

Разве не было бы замечательно, если бы мы могли просто определить это, как показано ниже?

pipeline=Pipeline(
    load_and_transform,
    train_model,
    test_model,
    save_results
)

Это будет означать, что конвейер должен отслеживать awesome_config и test_data и предоставлять их только соответствующим этапам ниже по потоку, когда это необходимо. pakkr делает это, вводя концепцию мета-рабочего пространства.

Мета

Мета - это механизм рабочего пространства метаданных в пакете pakkr, который похож на хранилище ключей / значений. После того, как объекты проходят проверку типа, meta будет удерживать эти объекты для нас, пока они не будут вызваны снова на последующих этапах конвейера (как показано на диаграммах ниже). Вы можете подумать о функции рабочего пространства meta как мемоизация или кеширование. Таким образом, мы можем избежать использования DAG и сделать конвейер более гибким.

Обратите внимание, что мета-значения должны содержаться в пределах времени существования конвейера и не должны включаться в возвращаемые значения конвейера, за исключением одного сценария: понижающее преобразование. Мы познакомим вас с концепцией понижения в части II серии блогов pakkr. Не беспокойся об этом пока.

Конфигурация

Мы говорили о «что», но как насчет «как»? Как конвейер узнает, что нужно передать на следующий шаг, а что нужно сохранить в мета-рабочем пространстве для следующих шагов? Ответ состоит в том, чтобы указать, как вывод шага следует интерпретировать с помощью функции returns.

Возврат

returns позволяет нам вводить объекты в мета и выполнять проверку типа возвращаемого значения функции. Его можно использовать как декоратор или как обычную функцию. В примере notebook мы демонстрируем, что pakkr использует returns и meta вместе для интерпретации возвращаемых значений.

returns принимает типы как позиционные и ключевые аргументы для проверки возвращаемых значений функции; это позволяет нам проверять как количество возвращаемых значений, так и их типы. Позиционные аргументы будут переданы на следующий шаг, а аргументы ключевых слов будут вставлены в мета.

Аргумент командной строки

На GPU или сервере? Без проблем! pakkr также анализирует аргументы командной строки для конвейеров, чтобы вы могли выполнять конвейеры с помощью CLI. Если вам нужна помощь в настройке этой дополнительной утилиты, посетите наш репозиторий, чтобы увидеть несколько примеров.

Конец

Последние два года pakkr помогает нам в преобразовании данных, разработке и проверке моделей (включая модели, лежащие в основе Content Cues). Это было большим подспорьем в нашей повседневной работе, и мы надеемся, что pakkr поможет и вам. Следовательно, у нас есть пакет с открытым исходным кодом на PyPi.

У нас все еще есть некоторые другие функции и улучшения, такие как интеграция mypy, визуализация зависимостей и автоматическая сборка мусора в мета, и это лишь некоторые из них. Надеюсь, мы скоро сможем над ними поработать. А пока не стесняйтесь поднимать вопросы в GitHub, если вы обнаружите какие-либо ошибки или у вас есть какие-либо предложения. С вашей помощью pakkr станет лучше и будет полезнее для всех.

Особое спасибо

Мы также хотели бы воспользоваться этой возможностью, чтобы поблагодарить нашего руководителя отдела Data Science Soon-Ee Cheah за потрясающий заголовок и стихи. Мы также хотели бы выразить нашу благодарность всем членам команды и коллегам, которые так щедро тратят свое время и идеи, чтобы сделать этот блог отличным произведением. Перейти на науку о данных! Перейти к Zendesk!

Следующий

В настоящее время мы пишем pakkr (Часть II), Многоликый Бог, в котором мы углубимся в технические детали и проанализируем различные варианты использования pakkr.