Введение

Последний пост посвящен принципам проектирования, изложенным в статье Riselabs из Беркли для новой структуры, необходимой для развивающегося класса приложений ИИ. Этот пост будет основан на этих принципах дизайна и сделает глубокое погружение в каркас Ray, построенный в соответствии с этими принципами. Я настоятельно рекомендую ознакомиться с принципами дизайна, прежде чем переходить к этому. Этот пост будет основан на большом количестве материала, который был рассмотрен в предыдущем посте.

Подведем итоги последнего поста: на высоком уровне структура для нового класса приложений API должна будет поддерживать низкую задержку планирования, высокую пропускную способность для миллионов задач, динамическое создание задач, гетерогенные задачи, произвольные сложные зависимости потоков данных. . Ray поддерживает эти требования и, в свою очередь, обеспечивает новый класс приложений искусственного интеллекта, использующих обучение с подкреплением (RL), которые нуждаются в поддержке распределенного обучения, обслуживания моделей и запуска многих симуляций. Ray специализируется на выполнении легких задач без сохранения состояния, а также на длительных операциях с отслеживанием состояния, необходимых для обучения.

Типичный алгоритм RL

Типичный пример взаимодействия агента RL с окружающей средой проходит через следующий итерационный алгоритм:

  1. Начни с какой-нибудь модели
  2. Заставить политику (из модели) взаимодействовать со средой и выполнить рекомендованное действие (обслуживание модели)
  3. Получите награду, взаимодействуя с смоделированной средой (Симуляторы)
  4. Повторяйте шаги 2–3 до завершения моделирования.
  5. Используя результаты последнего шага, переобучите политику. (Обучение)
  6. Повторяйте шаги 1–5, пока результаты не сойдутся и вознаграждение не будет максимальным.

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

Примитивы Ray API

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

Задачи и актеры

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

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

Графики задач

Рэй создает динамический граф на основе программы, написанной пользователем. Этот граф формирует структуру зависимостей, и следующие задачи в графе выполняются системой, когда становятся доступными входные данные. Граф состоит из узлов, которые представляют объекты данных, удаленные вызовы функций (задачи). У графа тоже есть ребра. Границы потока данных фиксируют зависимость между задачами и объектами данных. Границы управления захватывают вложенные задачи или функции, которые создают дальнейшие удаленные функции. Пока мы не обсуждали Актеров в этой модели. Актеры снова похожи на задачи. Единственное отличие состоит в том, чтобы уловить состояние. Это делается путем добавления края с отслеживанием состояния. Когда Actor вызывает два метода M1 и M2, между двумя узлами задач, представленными M1 и M2, добавляется граница с отслеживанием состояния. Это означает, что цепочка ребер с сохранением состояния формируется для всех методов, вызываемых одним и тем же субъектом, а также помогает в построении линии передачи, что полезно для восстановления после сбоя.

Архитектура

Системная архитектура Ray состоит из прикладного и системного уровней. Давайте посмотрим, как работают два слоя.

Прикладной уровень

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

Системный уровень

Системный уровень состоит из трех основных компонентов, которые включают глобальное состояние управления (GCS), глобальный планировщик и распределенное хранилище в памяти + локальный планировщик.

Глобальное хранилище управления (GCS) используется для хранения такой информации, как все таблицы удаленных функций, журналы событий, таблицы объектов. По сути, это хранилище ключей и значений, дополненное функциональностью pub-sub. В этой таблице также хранится информация о том, где расположены объекты, чтобы ее можно было использовать для эффективного размещения задач и данных. Поскольку GCS поддерживает все состояние, он помогает масштабировать планировщик. Кроме того, GCS можно использовать для восстановления после сбоев. Грубое восстановление решается с помощью таких архитектур, как RDD, но для мелкозернистого восстановления требуется другой механизм, особенно для динамических задач, которые добавляются во время моделирования. Для решения этой проблемы необходимо, чтобы GCS сохранял информацию о происхождении для восстановления. Это позволяет всем другим компонентам системы не иметь состояния и не беспокоиться о восстановлении после сбоев.

Глобальный планировщик. Глобальный планировщик - это действительно гибридный планировщик, работающий снизу вверх, в котором задачи передаются локальному планировщику. Локальный планировщик сначала пытается запланировать данную задачу на том же узле. Если это невозможно из-за ограничений (отсутствие графического процессора) или из-за высокой нагрузки на локальный узел, он отправит задачу в глобальный планировщик. Глобальный планировщик осведомлен об общем использовании системы на всех узлах и потребностях в данных для различных задач через GCS. Затем эти задачи могут быть отправлены локальному планировщику на узле, выбранном глобальным планировщиком. Глобальный планировщик может найти несколько узлов, которые удовлетворяют потребности в емкости для этой задачи. Поскольку задачи в Ray очень чувствительны к задержкам, планировщик выбирает узел, который минимизирует время ожидания для задачи. Время ожидания определяется как сумма «времени, проведенного в очередях на выбранном узле» и «времени, затраченного на передачу входных данных на этот узел». GCS использует тактовые импульсы для получения информации о пропускной способности передачи данных, а также о размерах очередей на каждом узле. Кроме того, если планировщик становится узким местом, то можно масштабировать планировщик, используя GCS в качестве источника данных.

См. Рисунок ниже, который упрощает рабочий процесс планирования задач.

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

Выполнение удаленной задачи в Ray

Давайте рассмотрим последовательность шагов, необходимых для выполнения функции в Ray, и шаги, необходимые для получения результатов. Представьте, что в системе есть два узла N1 и N2. Объявляется удаленная функция, она регистрируется в GCS и затем передается рабочим на N1 и N2 (шаг 0 на рисунке выше). Приложение работает на N1 и хочет выполнить операцию «добавления» для двух объектов a и b. Эта операция возвращает будущий «id», а затем приложение на N1 вызывает get () для будущего «id», что является блокирующим вызовом. Теперь сначала давайте рассмотрим, что происходит в системе при выполнении операции добавления. Это показано на рисунке (а).

  1. Задача добавления отправляется локальному планировщику на N1.
  2. Локальный планировщик понимает, что у него есть только объект «а», доступный локально. Таким образом, он отправляет задачу в глобальный планировщик.
  3. Глобальный планировщик смотрит в GCS, где присутствуют объекты «a» и «b», а затем решает запланировать это на N2.
  4. Локальный планировщик на N2 получает информацию о «a» из локального хранилища объектов. «B» доступно локально.
  5. Поскольку в хранилище объектов нет «а», его необходимо получить из узла, в котором он присутствует.
  6. Хранилище объектов на N2 узнает от GCS, что «a» находится на N1.
  7. «A» реплицируется на N2 через репликацию хранилища объектов с N1
  8. Локальный планировщик планирует добавление задач с помощью локальных работников
  9. Локальный работник использует хранилище объектов для извлечения «a» и «b» для выполнения добавления.

Вторая часть приложения - получить результат сложения с использованием будущего «id», на которое ссылается приложение на N2. Это показано на рисунке (b).

  1. Локальный планировщик на N1 выполняет переход на будущий «id». Он проверяет хранилище объектов локально, в котором еще нет записи для id.
  2. Локальное хранилище объектов запрашивает у GCS «идентификатор». Поскольку в GCS этого нет, обратный вызов регистрируется в GCS.
  3. Тем временем добавление завершается на узле N2. Данные хранятся в хранилище объектов на N2.
  4. Хранилище объектов N2 сообщает GCS о наличии результатов «id». Это зарегистрировано в таблице объектов.
  5. GCS вызывает обратный вызов на N1, указывая на доступность «id» на N2.
  6. Хранилище объектов на N1 копирует «id» из N2.
  7. Теперь задача на N1, ожидающая future-get (ray.get), разблокирована.

Оценка приложений RL

В этой статье также сравнивается производительность платформы Ray с двумя алгоритмами RL и их эталонными реализациями. Эти два алгоритма - стратегии эволюции и ближайшая оптимизация политики. В обоих случаях алгоритм на основе лучей работает намного лучше по сравнению с одноразовыми решениями, созданными для этих проблем. Имейте в виду, что создание таких одноразовых решений довольно сложно. Для ES эталонное решение не масштабируется за пределы 1024 узлов, в то время как лучи масштабируются до 8192 узлов. Точно так же для PPO луч превосходит реализацию OpenMPI по гораздо более низкой цене (что улучшает использование кластера) и требует гораздо меньшего количества графических процессоров. Это стало возможным, потому что задачи и субъекты могут запрашивать определенные разнородные ресурсы и лучше использовать локальность данных при закреплении этих ресурсов.

Вывод

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

Получайте лучшие предложения по программному обеспечению прямо в свой почтовый ящик