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

Масштабная поддержка машинного обучения связана с множеством проблем, не последняя из которых - это надежная, максимально быстрая доставка моделей в производство с учетом большого разнообразия типов моделей, настроек вызова, библиотек, источников данных, подходов к мониторингу и т. Д. Основываясь на основных ценностях Booking.com (разнообразие дает нам силу), мы создали систему, которая поддерживает широкий спектр подходов к машинному обучению. В этой статье мы представляем RS, нашу производственную систему машинного обучения.

Разнообразие дает нам силы

Это одна из главных ценностей Booking.com. Национальности, языки, возраст, происхождение, пол, хобби, религии, диеты… все очень разнообразно. Машинное обучение никуда не годится. Люди, создающие модели машинного обучения, делают это по-разному. Некоторые используют небольшой набор данных и R, другие - огромный набор данных и инструмент командной строки, такой как Vowpal Wabbit. Некоторым нравится писать собственный алгоритм оптимизации на Java, другие используют sklearn или H2O. Некоторые строят модели глубокого обучения в Pytorch, другие - в Tensorflow и так далее. Мы верим в такое разнообразие и поэтому поощряем его и поддерживаем его инструментами, курсами, инфраструктурой и многим другим, но ...

Разнообразие дает нам ... вызов

Большинство создаваемых нами моделей ценны только тогда, когда они интегрированы в более крупную систему, такую ​​как основной веб-сайт Booking.com, наши мобильные приложения, наши партнерские службы, системы обслуживания клиентов и т. Д. Процесс принятия работающей модели с машинным обучением и ее интеграции с соответствующей системой, чтобы сделать ее доступной для наших клиентов, - это то, что мы называем производством. Это критический шаг, и он влечет за собой ряд требований. Давайте посмотрим на самые важные из них:

Последовательность

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

Высокая доступность

Большинство наших систем доступны 24/7, а это значит, что наши модели с машинным обучением также должны обслуживать запросы семь дней в неделю, 24 часа в сутки, по всему миру. Обновление модели, ее масштабирование для более широкой аудитории, поддержка хостов, на которых она выполняется, тестирование новых инструментов и т. Д. Не должны мешать доступности модели в производственной среде. Ставки высоки: весь эксперимент может оказаться недействительным, если одна из конкурирующих моделей слишком часто терпит неудачу.

Низкая задержка

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

Масштабируемость

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

Наблюдаемость

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

Возможность повторного использования

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

Удовлетворение всех этих требований для моделей, построенных с использованием такого разнообразного набора подходов, является довольно сложной задачей. Но это именно та проблема, с которой мы постоянно сталкиваемся.

Фантастическая четверка

Давайте рассмотрим четыре основных механизма создания моделей с машинным обучением. Эти механизмы составляют основу нашей системы, и они воплощают типы компромиссов, на которые мы идем при развертывании наших моделей. Они работают немного как герои Marvel, у всех есть сильные и слабые стороны, но работая вместе, они достигают великих результатов.

Таблицы поиска

Большинство наших моделей сопоставляют входной вектор с прогнозом (или набором прогнозов в случае рекомендательных систем). Очень простой способ развернуть модель в производственной среде - предварительно вычислить все прогнозы для всех возможных входных данных и сохранить их в хранилище «ключ-значение». Во время прогнозирования все, что нам нужно сделать, это найти прогноз, используя входные данные в качестве ключа. Это очень наивный подход, но он имеет множество преимуществ:

  • Поскольку во время прогнозирования вычисления не выполняются, а большинство хранилищ значений ключей оптимизировано для быстрого чтения, задержка обычно очень мала.
  • Горизонтальная масштабируемость довольно проста, об этом позаботится большинство хранилищ ключей.
  • Огромная гибкость моделирования. На самом деле не имеет значения, как модель была обучена, будь то линейная модель, обученная в R, или сеть с двойным вниманием, обученная с помощью Keras, если прогнозы могут быть вычислены и записаны в хранилище значений ключа во время модели. могут быть изготовлены надежно.

Также у него есть несколько недостатков:

  • Когда входное пространство велико, может быть трудно сохранить такое количество комбинаций или невозможно предварительно вычислить все прогнозы в разумные сроки. Кроме того, велика вероятность того, что многие комбинации входных данных никогда не появятся в процессе производства, что приведет к потере вычислительных ресурсов и ресурсов хранения.
  • Процесс записи прогнозов в хранилище ключей и значений может быть обременительным, если мы рассматриваем версии модели, модификации пространства функций и т. Д.
  • Непрерывный ввод не поддерживается.

Для проблем с небольшим и дискретным пространством функций этот метод предлагает огромную гибкость моделирования вместе со всеми приятными атрибутами хорошего хранилища ключей и значений: быстрым чтением, высокой доступностью и горизонтальной масштабируемостью. В Booking.com этот метод довольно популярен во Front End, где у нас обычно есть отдельные пространства функций или естественный ключ, такой как идентификаторы пользователя / жилья / места назначения.

Обобщенные линейные модели (GLM)

В этом методе модель представлена ​​скалярным весом для каждого входа плюс глобальное смещение; во время прогнозирования мы просто вычисляем внутреннее произведение входных данных с весами, добавляем смещение, применяем скалярную функцию («инвертированная ссылка») и возвращаемся. Если нас интересует ранжирование элементов, мы делаем то же самое для каждого элемента и сортируем их по их баллам, более формально:

Прогноз (X) = 𝓕 (‹W, 𝓣 (X)›)

Где ‹,› означает внутренний продукт, X - входной вектор, W - вектор веса (модель), 𝓕 - инвертированная ссылка. функция (скаляр в скаляр), а 𝓣 - преобразование вектора в вектор, применяемое до вычисления внутреннего продукта, наконец, на выходе получается один скаляр.

Предметы ранжирования очень похожи:

Рейтинг (X) = arg sortᵢ 𝓕 (‹Wᵢ, 𝓣 (X, i ) ›), i ∈ 𝓘

Здесь 𝓘 - это набор элементов, Wᵢ - вектор веса для элемента i (модель W теперь представляет собой матрицу) и 𝓣 преобразует входной вектор X в другой вектор, который может зависеть от конкретного элемента i. Результатом является отсортированный список элементов, конечно, можно приложить саму оценку для последующих целей или даже взять верхние k элементов, в отличие от сортировки, которая может выполняться за линейное время.

Теперь, в зависимости от того, как мы создаем экземпляры всех этих переменных, мы получаем очень разные модели, все линейные по параметрам W. Например:

  • И 𝓣 идентичность дает простую линейную регрессию.
  • 𝓕 сигмовидная и 𝓣 идентичность дают простую логистическую регрессию.
  • Если X - это одномерный вектор только с идентификатором пользователя, 𝓕 - это идентификатор, 𝓣 преобразует X в d -мерный вектор пользователя. (независимо от i), а Wᵢ - это d -мерный вектор-элемент для элемента i, мы получаем билинейные модели, такие как матричная факторизация и k-ближайших соседей на основе косинусного сходства.

В общем, это простое правило прогнозирования позволяет выполнять прогнозы для многих видов регрессоров, бинарных или многоклассовых классификаторов, рекомендательных систем или ранжеров и даже простых моделей последовательностей, таких как цепи Маркова.

Конечно, реальная модель зависит от того, как W извлекается из данных. Линейная регрессия на самом деле может быть классификатором SVM, но нам не нужно об этом заботиться. Не имеет значения, какой алгоритм обучения используется, если он может быть представлен вектором весов, входным преобразованием и функцией связи, мы можем запустить его в производственной среде.

Этот метод напрямую решает проблемы таблиц поиска. GLM могут легко моделировать непрерывные входные данные, большое количество входных данных, и они более эффективны, поскольку вычисляются только фактически запрошенные прогнозы. За такую ​​гибкость приходится платить: мы можем производить только линейные модели. Обратите внимание, что это означает линейность в W, ничто не мешает нам вносить нелинейности через преобразования функций (𝓣), такие как взаимодействия, сегментирование, отсечение или даже использование вложений. Еще один недостаток заключается в том, что нам необходимо преобразовать нашу модель из библиотеки, используемой для ее обучения, в формат линейного предиктора, который может быть подвержен ошибкам и добавляет еще один шаг в процесс развертывания.

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

Родные библиотеки

Этот метод состоит из простого использования библиотеки, используемой для обучения модели, для прогнозирования в производственной среде. Например, если модель обучается с использованием sklearn, мы можем сохранить ее в формате pickle, загрузить на производственный сервер, где она будет загружена с помощью API-интерфейсов sklearn и pickle, что сделает ее готовой для обслуживания прогнозов. Если мы обучили модель с помощью H2O, мы можем сериализовать ее с помощью Java Serialization API и, как и в случае со sklearn, загрузить ее на сервер, десериализовать и использовать для прогнозирования. Большинство библиотек предлагают некоторую форму сериализации уже обученной модели, поэтому этот подход в принципе является довольно общим.

Этот метод привносит новое измерение в картину: простоту использования. Мы можем просто обучить нашу модель и загрузить ее без преобразования в промежуточные форматы. Он также обеспечивает высокую согласованность, тот же код, который используется для обучения, используется для прогнозирования, никаких сюрпризов в производстве. С другой стороны, собственные библиотеки может быть сложно развернуть, поскольку для них требуется определенная среда выполнения. Например, если наши серверы работают на Java, развертывание моделей Python непросто, или если наши серверы работают на Python, развертывание H2O MOJO может быть очень сложным. В общем, это приводит к развитию поддержки библиотек, совместимых со средой выполнения сервера, которая предлагает гораздо меньшую гибкость по сравнению с таблицами поиска и GLM. Другой недостаток заключается в том, что собственные библиотеки могут быть оптимизированы не для времени обслуживания, а для времени обучения, что увеличивает риск задержки.

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

Скриптовые модели

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

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

Компромиссы и итеративный подход, основанный на гипотезах

Есть еще много механизмов для развертывания моделей, но это четыре канонических метода, которые позволяют нам идти на разумные компромиссы. Не для всех бизнес-кейсов требуется одинаковый уровень гибкости или надежности моделирования, и для одного бизнес-кейса эти требования также не находятся на одном уровне на разных этапах решения. . Например, если мы хотим создать рекомендательную систему, первая модель вполне может быть просто моделью популярности с двумя или тремя категориальными характеристиками, построенной только с использованием SQL, поэтому таблица поиска - идеальный подход на этом этапе, поскольку мы не используем Я не хочу, чтобы задержка вообще была проблемой в начале проекта. Следующим шагом может быть проверка гипотезы о том, что большее количество функций делает рекомендации более актуальными. Мы все еще можем сделать это с помощью таблицы поиска, но если количество функций слишком велико, GLM позволяет нам делать это без ущерба для задержки и дает нам свободу использовать язык программирования и библиотеку программного обеспечения, с которой мы наиболее удобны. По мере того, как проект будет успешным, модель будет развиваться в сторону большей сложности, мы можем отказаться от нашей гладкой линейной модели SKLearn, чтобы иметь возможность тестировать влияние нелинейностей с помощью случайных лесов, для которых H2O, развернутая как сериализованная модель, отлично справится с задачей. Наконец, зрелая модель может превратиться в мощную RNN, обученную в Pytorch, и мы даже можем быть готовы заплатить несколько миллисекунд за гораздо более точные рекомендации.

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

Гибкость можно разделить на гибкость в отношении пространства ввода, подхода к моделированию или стека (язык программирования и библиотеки). Аналогичным образом, надежность можно разделить на латентность, согласованность (между моделью обучения и фактически работающим артефактом) и наблюдаемость.

В следующей таблице показаны эти компромиссы с использованием системы оценки -1, 0 +1 (красный, желтый, зеленый) по этим 6 аспектам:

Суммирование оценок (при условии, что все они одинаково важны) позволяет нам разместить каждый метод в плоскости компромисса:

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

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

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

RS, наш производственный инструмент машинного обучения

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

Основная идея RS состоит в том, чтобы отделить обучение от прогнозирования. Не имеет значения, как была построена модель или какой метод производства был использован, потребители модели могут использовать один и тот же API. Эта простая, но мощная идея позволяет RS поддерживать огромное разнообразие.

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

Реализация

Модели можно загружать через программный интерфейс или через веб-портал. RS распределяет модель по узлам кластера, где процесс Java загружает их в память и делает их доступными для обслуживания прогнозов через стандартный интерфейс HTTP. Один узел RS обслуживает множество моделей, и любая данная модель загружается во многие узлы, этот подход помогает достичь требований высокой доступности и масштабируемости.

Таблицы поиска реализованы с использованием хранилища ключей и значений Cassandra (или в памяти, если они достаточно малы), пользователи могут указывать на таблицу в нашем кластере Hadoop, и RS импортирует ее в Cassandra. GLM обслуживаются с помощью собственной разработанной системы линейного прогнозирования, которая использует простые текстовые файлы в качестве дескрипторов модели. Собственные библиотеки поддерживаются через двоичные файлы H2O MOJOS, Tensorflow и Vowpal Wabbit. Это самые популярные библиотеки, используемые на Booking.com, и они совместимы с Java, что соответствует среде выполнения RS. Наконец, скриптовые модели - это скрипты Python, каждый из которых работает в своей собственной виртуальной среде, что позволяет пользователям загружать дополнительные модули и зависимости по мере необходимости.

Вдобавок к этому RS добавляет большую ценность за счет дополнительных функций, включая веб-портал, который позволяет искать и просматривать все доступные модели. Каждая модель имеет свою собственную страницу с подробной информацией, такой как эксперименты с использованием модели, инструменты мониторинга, документация, ссылка на обучающий код и т. Д. Она также предоставляет базовый конечный автомат, который позволяет автору переходить модель через состояния, такие как в стадии тестирования, готов к производству, отключен и т. д. Еще одна интересная функция - площадка для игр, которая позволяет случайным пользователям просто пойти дальше и использовать модель, чтобы увидеть что оно делает. Все это очень помогает с требованиями к наблюдаемости и возможности повторного использования.

RS также смягчает многие из красных флажков, выявленных в результате анализа компромиссов. Например, кеширование и пакетные запросы очень помогают с задержкой; система линейного прогнозирования была расширена для поддержки машин факторизации, что сгладило красный флаг гибкости модели; тестовые случаи применяются, когда модели загружаются, чтобы уменьшить красный флаг согласованности. Поддерживаемые собственные библиотеки совместимы с несколькими языками программирования (Python, Java, R, C), что снижает красный флаг гибкости стека. В целом RS предоставляет авторам моделей высокую гибкость и надежность, независимо от того, какой метод производства они выбирают.

Уроки выучены

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

Принятие разнообразия было, безусловно, самым важным фактором успеха, но мы также узнали много других вещей на этом пути, поэтому, чтобы подвести итог, давайте рассмотрим три из них:

Решение общих конкретных проблем

RS начинался как простая утилита для запуска линейных моделей на веб-сайте. Эта крошечная утилита добилась огромного эффекта, потому что решила общую и конкретную проблему того времени. Он устранил одно препятствие и открыл путь для того, что появилось позже.

Держать клиента рядом

С самого начала мы держали наших клиентов (авторов моделей) как можно ближе, вместе проводили мозговой штурм, вместе решали бизнес-кейсы, вместе выстраивали видение. Нам нравится думать, что RS создается нашим сообществом машинного обучения, а не только основной командой RS.

Изобретая колесо

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

Это все, ребята!

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

Я хочу поблагодарить Адольфо Мазорру и Джин Шмидт, двух основных разработчиков RS, за их проницательный вклад, Фемис Мавридис за рецензирование всей статьи и Стивена Багули за ее создание. человек читаемый.