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

Обоснование разработки платформы

После развертывания наших первых двух моделей с использованием существующей обслуживающей архитектуры Zillow с поддержкой AWS EC2 мы быстро осознали трудности, с которыми столкнется наш уровень обслуживания. Данная модель может вызываться только один раз на запрос предложения, а другая модель может вызываться тысячи раз в минуту. Уравновешивание стоимости, доступности и пакетной масштабируемости быстро привело нас к исследованию альтернативного подхода.

В нашей первоначальной программной архитектуре использовалась монолитная конструкция, что позволяло нам быстро выполнять итерацию без необходимости выделения нового оборудования. Однако по мере того, как к нему добавлялись новые модели, управление зависимостями становилось сложной проблемой. Развертывание каждой модели по отдельности, инкапсуляция зависимостей и требование обеспечить воспроизводимость наших прогнозов вызвали у нас необходимость принять контейнеры.

Сделаем шаг назад

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

  • Проект - бизнес-проблема. Каждый проект находится в собственном репозитории Git, который в основном разбит на три области: экспериментальные исследования в виде записных книжек Jupyter, код производственного моделирования и любые вспомогательные конвейеры данных или необходимые определения рабочего процесса.
  • Вариант - конкретная реализация решения бизнес-проблемы проекта, описанного в проекте. Также там, где существует код обучения и обслуживания модели.
  • Конечная точка - схема, демонстрирующая вариант решения. Определяется как контракт API для группы клиентов-потребителей или метод отладки для самоанализа.

Проект может быть реализован несколькими вариантами (даже одновременно с помощью A / B, бандитов и т. Д.) И открыт для последующих потребителей через множество конечных точек.

Превращение концепции в компоненты

С помощью описанных выше концепций нам нужно было превратить их в повторяющийся узор. Мы обратились к cookiecutter, утилите для создания шаблонных проектов, чтобы предоставить нам шаблон проектирования для единообразного создания новых репозиториев. Преимуществами этого подхода были простота создания новых проектов и возможность их настройки. Однако развертывание обновлений самого шаблона может быть непростым делом и требует большого внимания. Мы упростили наш процесс, разработав набор внутренних библиотек и инструментов, совместно используемых в разных проектах, централизовав код, который выполняет повторяющуюся тяжелую работу, и абстрагируя большую часть взаимосвязей между компонентами. Это позволило разработчикам моделей сосредоточиться на задачах, которые у них лучше всего получаются!

Два из этих инструментов: Столп и Волшебник. Pillar инкапсулирует утилиты для построения рабочих процессов обучения, обрабатывает нашу структуру вариантов кода и принимает конфигурации гиперпараметров и обучающих данных для заданий, выполняемых в AWS SageMaker. Scorcerer централизует инструменты для раскрытия конечных точек для наших клиентов-потребителей. Scorcerer печально известен своим неправильным произношением, но он дарит волшебные ощущения, и с новыми услугами онбординг никуда не денется!

При сборке каждый проект упаковывает все свои зависимости в один образ Docker и предоставляет несколько точек входа, которые вызываются на этапах конвейера обучения. Последовательно повторно используя один и тот же образ между обучением и обслуживанием, мы сглаживаем требуемый набор зависимостей (как на уровне системы, так и на уровне приложения), что позволяет нам взять модель, которую мы обучили в SageMaker, сериализовать ее в наше озеро данных, и развернуть на Kubernetes для обслуживания в реальном времени. Без Docker модели отладки, обученные в прошлом, были чреваты ошибками, поскольку часто наборы зависимостей были несовместимы. Теперь, когда мы обучаемся, мы одновременно обновляем сериализованную модель и образ Docker, чтобы упростить этот процесс.

По умолчанию мы предоставляем следующие точки входа:

  • train - настраиваемая точка входа в SageMaker, которая вызывает Pillar для приема гиперпараметров и конфигураций данных из интерфейса SageMaker в обучающий код варианта.
  • serve - вызывает Scorcerer, который использует gunicorn и flask для обслуживания модели через HTTP.
  • pred_batch - предоставляет механизм для запуска автономного пакетного вывода для набора данных.
  • отладка - позволяет инженерам и прикладным специалистам легко прыгать в контейнер для отладки или тестирования.

Соединяем компоненты вместе

Новый проект создается после открытия новой области исследования. Шаблон исходного кода создается и настраивается с использованием нашего шаблона архетипа, поддерживаемого cookiecutter. Первоначальное исследование выполняется в записных книжках, хранящихся в рамках проекта, а любой повторно используемый код переносится в отдельные модули. Мы используем встроенный в Gitlab инструментарий CI / CD для создания конвейеров, которые собирают, тестируют и публикуют наши образы Docker в репозиториях на AWS ECR. Такой подход значительно упростил наш путь от начального исследования до производства за счет максимального повторного использования кода между этими средами.

Airflow действует как оркестратор конвейера обучения, инициируя одно или несколько заданий Spark, которые берут необработанные наборы данных из нашего озера данных и преобразуют их в наборы данных, адаптированные для обучения. Затем мы загружаем эти наборы данных в SageMaker как отдельные каналы. На этом этапе мы обычно завершаем проектирование функций, необходимое для конкретного варианта модели.

Pillar затем организует потоки обучения в точке входа train SageMaker и оценивает модели по мере их завершения. Оценка дает нам решение о публикации для интерпретации задач, стоящих ниже по течению. Затем мы сериализуем модель и сохраняем ее в S3, используя структуру пути, которая кодирует проект, имя варианта и другие важные метаданные.

Если принято решение о публикации, Airflow извлекает вариант пути S3, созданный на предыдущем шаге, и передает его в Gitlab, где другой конвейер развертывания использует Helm для выполнения развертывания в Kubernetes с помощью нашего решения для оценки в реальном времени чародей. Если мы не публикуем, мы запускаем оповещение для проверки вручную.

Мы регистрируем показатели для оценки запросов к Scorcerer в Datadog для отладки и в Платформе потоковой передачи данных Zillow для долгосрочного моделирования прогнозирования в автономном режиме. Это позволяет нам согласовывать запросы на оценку с наборами достоверных данных, чтобы гарантировать, что наша производительность коррелирует с фактическими значениями постфактум.

Будущее

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

Большое спасибо Стивену Хелшеру, Алексу Приемке, Эзре Шиффу, Срути Нагалла и Тейлору Маккею за руководство и помощь в редактировании этой статьи, а также всей команде ZO Machine Learning за их усилия, которые продвинули нас так далеко!