- PVSM.RU - https://www.pvsm.ru -
Здравствуйте, коллеги.
Надеемся еще до конца августа приступить к переводу небольшой, но поистине базовой книги [1] о реализации возможностей ИИ на языке Python.
Господин Гифт, пожалуй, в дополнительной рекламе не нуждается (для любопытствующих — профиль мэтра [2] на GitHub):
В предлагаемой сегодня статье будет коротко рассказано о библиотеке Ray, разработанной в Калифорнийском университете (Беркли) и упомянутой в книге Гифта мелким петитом. Надеемся, что в качестве раннего тизера — то, что надо. Добро пожаловать под кат
По мере развития алгоритмов и приемов машинного обучения, все больше и больше приложений для машинного обучения требуется запускать сразу на множестве машин, и они не могут обойтись без параллелизма. Однако инфраструктура для выполнения машинного обучения на кластерах по-прежнему формируется ситуативно. Сейчас уже существуют хорошие решения (например, серверы параметров или поиск гиперпараметров) и высококачественные распределенные системы (например, Spark или Hadoop), исходно создававшиеся не для работы с ИИ, но практикующие специалисты часто создают инфраструктуру для собственных распределенных систем с нуля. На это тратится масса лишних усилий.
В качестве примера рассмотрим концептуально простой алгоритм, скажем, Эволюционные стратегии для обучения с подкреплением [3]. На псевдокоде этот алгоритм укладывается примерно в дюжину строк, и его реализация на Python немногим больше. Однако, для эффективного использования этого алгоритма на более крупной машине или кластере требуется значительно более сложная программная инженерия. В реализации этого алгоритма от авторов данной статьи – тысячи строк кода, здесь необходимо определять протоколы связи, стратегии сериализации и десериализации сообщений, а также различные способы обработки данных.
Одна из целей Ray [4] — помочь специалисту-практику превратить алгоритм-прототип, запускаемый на ноутбуке, в высокопроизводительное распределенное приложение, эффективно работающее на кластере (или на отдельно взятой многоядерной машине), добавив относительно немногочисленные строки кода. Такой фреймворк должен по части производительности обладать всеми преимуществами системы, оптимизированной вручную, и не требовать, чтобы пользователь сам задумывался о планировании, передаче данных и машинных сбоях.
Свободный фреймворк для ИИ
Связь с другими фреймворками глубокого обучения: Ray полностью совместим с такими фреймворками глубокого обучения как TensorFlow, PyTorch и MXNet, поэтому во многих приложениях совершенно естественно использовать вместе с Ray один или более других фреймворков глубокого обучения (например, в наших библиотеках для обучения с подкреплением активно применяются TensorFlow и PyTorch).
Связь с другими распределенными системами: Сегодня используется много популярных распределенных систем, однако, большинство из них проектировалось без учета задач, связанных с ИИ, поэтому не обладают требуемой производительностью для поддержки ИИ и не имеют API для выражения прикладных аспектов ИИ. В современных распределенных системах отсутствуют (те или иные, в зависимости от системы) такие нужные возможности:
Простой пример вложенного параллелизма. В нашем приложении параллельно выполняется два эксперимента (каждый из них – это долгосрочная задача), и в каждом эксперименте моделируется несколько параллельных процессов (каждый процесс — это тоже задача).
Существует два основных способа использования Ray: через его низкоуровневые API и через высокоуровневые библиотеки. Высокоуровневые библиотеки надстраиваются поверх низкоуровневых API. В настоящее время к их числу относятся Ray RLlib [5] (масштабируемая библиотека для обучения с подкреплением) и Ray.tune [6], эффективная библиотека для распределенного поиска гиперпараметров.
Низкоуровневые API Ray
Цель Ray API – обеспечить естественное выражение самых общих вычислительных паттернов и прикладных задач, не ограничиваясь при этом такими фиксированными паттернами как MapReduce.
Динамические графы задач
Базовый примитив в приложении (задании) Ray — динамический граф задач. Он очень отличается от вычислительного графа в TensorFlow. Тогда как в TensorFlow вычислительный граф представляет нейронную сеть и выполняется по множеству раз в каждом отдельном приложении, в Ray граф задач соответствует целому приложению и выполняется всего один раз. Граф задач заранее не известен. Он строится динамически, пока работает приложение, и выполнение одной задачи может инициировать выполнение многих других задач.
Пример вычислительного графа. В белых овалах показаны задачи, а в голубых прямоугольниках – объекты. Стрелками указано, что одни задачи зависят от объектов, а другие – создают объекты.
Произвольные функции Python можно выполнять как задачи, причем, они в произвольном порядке могут зависеть от вывода других задач. См. пример ниже.
# Определяем две удаленные функции. При вызове этих функций создаются задачи,
# выполняемые удаленно.
@ray.remote
def multiply(x, y):
return np.dot(x, y)
@ray.remote
def zeros(size):
return np.zeros(size)
# Параллельно запускаем две задачи. Они сразу же возвращают футуры,
# и эти задачи выполняются в фоновом режиме.
x_id = zeros.remote((100, 100))
y_id = zeros.remote((100, 100))
# Запускаем третью задачу. Она не будет назначена, пока первые две задачи
# не завершатся.
z_id = multiply.remote(x_id, y_id)
# Получаем результат. Он останется заблокирован до тех пор, пока не завершится третья задача.
z = ray.get(z_id)
Акторы
При помощи одних только удаленных функций и вышеописанного обращения с задачами невозможно добиться, чтобы несколько задач одновременно работали над одним и тем же разделяемым изменяемым состоянием. Такая проблема при машинном обучении возникает в разных контекстах, где разделяемым может быть состояние симулятора, весовые коэффициенты в нейронной сети, что-нибудь совершенно иное. Абстракция актора используется в Ray для инкапсуляции изменяемого состояния, разделяемого между множеством задач. Вот иллюстративный пример, демонстрирующий, как это делается с симулятором Atari.
import gym
@ray.remote
class Simulator(object):
def __init__(self):
self.env = gym.make("Pong-v0")
self.env.reset()
def step(self, action):
return self.env.step(action)
# Создаем симулятор, он запускает удаленный процесс, который, в свою очередь,
# запустит все методы этого актора
simulator = Simulator.remote()
observations = []
for _ in range(4):
# Совершаем в симулятор действие 0. Этот вызов не приводит к блокировке
# и возвращает футуру
observations.append(simulator.step.remote(0))
При всей простоте актор очень гибок в использовании. Например, в акторе может инкапсулироваться симулятор или политика нейронной сети, также он может использоваться для распределенного обучения (как, например, с сервером параметров) или для обеспечения политик в «живом» приложении.
Слева: Актор выдает прогнозы/действия некоторому количеству клиентских процессов. Справа: Множество акторов сервера параметров выполняют распределенное обучение множества рабочих процессов.
Пример с сервером параметров
Сервер параметров можно реализовать в виде актора Ray следующим образом:
@ray.remote
class ParameterServer(object):
def __init__(self, keys, values):
# Эти значения будут изменяться, поэтому необходимо создать локальную копию.
values = [value.copy() for value in values]
self.parameters = dict(zip(keys, values))
def get(self, keys):
return [self.parameters[key] for key in keys]
def update(self, keys, values):
# Эта функция обновления выполняет сложение с имеющимися значениями, но
# функцию обновления можно определять произвольно
for key, value in zip(keys, values):
self.parameters[key] += value
Вот более полный пример [7].
Чтобы инстанцировать сервер параметров, поступим так.
parameter_server = ParameterServer.remote(initial_keys, initial_values)
Чтобы создать четыре долгоиграющих работника, постоянно извлекающих и обновляющих параметры, сделаем так.
@ray.remote
def worker_task(parameter_server):
while True:
keys = ['key1', 'key2', 'key3']
# Получаем наиболее актуальные параметры
values = ray.get(parameter_server.get.remote(keys))
# Вычисляем некоторые обновления параметров
updates = …
# Обновляем параметры
parameter_server.update.remote(keys, updates)
# Запускаем 4 долгосрочные задачи
for _ in range(4):
worker_task.remote(parameter_server)
Высокоуровневые библиотеки Ray
Ray RLlib [5] – это масштабируемая библиотека для обучения с подкреплением, созданная для использования на множестве машин. Ее можно задействовать при помощи приведенных для примера обучающих сценариев, а также через API на Pytho. В настоящее время он включает реализации алгоритмов:
Идет работа и над реализацией других алгоритмов. RLlib полностью совместима с OpenAI gym [8].
Ray.tune [6] – эффективная библиотека для распределенного поиска гиперпараметров. В ней предоставляется API на Python для решения задач глубокого обучения, обучения с подкреплением и других задач, требующих большой вычислительной мощности. Вот иллюстративный пример такого рода:
from ray.tune import register_trainable, grid_search, run_experiments
# Функция для оптимизации. Гиперпараметры находятся в аргументе config
def my_func(config, reporter):
import time, numpy as np
i = 0
while True:
reporter(timesteps_total=i, mean_accuracy=(i ** config['alpha']))
i += config['beta']
time.sleep(0.01)
register_trainable('my_func', my_func)
run_experiments({
'my_experiment': {
'run': 'my_func',
'resources': {'cpu': 1, 'gpu': 0},
'stop': {'mean_accuracy': 100},
'config': {
'alpha': grid_search([0.2, 0.4, 0.6]),
'beta': grid_search([1, 2]),
},
}
})
Текущие результаты можно динамически визуализировать при помощи специальных инструментов, например, Tensorboard и VisKit от rllab (либо напрямую читать логи JSON). Ray.tune поддерживает поиск по сетке, случайный поиск и более нетривиальные алгоритмы раннего останова, например, HyperBand.
Подробнее о Ray
Автор: ph_piter
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/289827
Ссылки в тексте:
[1] базовой книги: https://www.amazon.com/Pragmatic-AI-Introduction-Cloud-Based-Learning/dp/0134863860/
[2] профиль мэтра: https://github.com/noahgift/
[3] Эволюционные стратегии для обучения с подкреплением: https://arxiv.org/abs/1703.03864
[4] Ray: https://github.com/ray-project/ray
[5] Ray RLlib: https://ray.readthedocs.io/en/latest/rllib.html
[6] Ray.tune: https://ray.readthedocs.io/en/latest/tune.html
[7] более полный пример: https://ray.readthedocs.io/en/latest/example-parameter-server.html
[8] OpenAI gym: https://gym.openai.com/docs/
[9] Академическая статья: https://arxiv.org/abs/1712.05889
[10] Документация: https://ray.readthedocs.io/en/latest/index.html
[11] Источник: https://habr.com/post/420695/?utm_campaign=420695
Нажмите здесь для печати.