雷:使用人工智能的分布式系统

大家好

我们希望在8月底之前开始翻译一本小巧但真正基础的书,介绍有关Python中AI功能的实现。



礼物先生,也许不需要额外的广告(出于好奇-GitHub上的管理员资料):



今天提供的文章将简要介绍由加利福尼亚大学(伯克利分校)开发,并在彼得的书中以小巧的形式提及的Ray库。 我们希望作为一个早期的预告片-您需要什么。 猫下欢迎

随着机器学习算法和技术的发展,越来越多的机器学习应用程序需要立即在多台机器上运行,并且它们必须并发。 但是,仍然可以根据情况形成在集群上执行机器学习的基础结构。 现在已经有很好的解决方案(例如,参数服务器或搜索超参数)和高质量的分布式系统(例如,Spark或Hadoop),最初不是为与AI一起使用而创建的,但是从业人员经常为他们自己的分布式系统创建基础架构。 为此付出了很多额外的努力。

例如,考虑一个概念上简单的算法,例如用于强化学习的进化策略 。 在伪代码上,此算法适合大约十几行,并且在Python中的实现略大。 但是,在大型计算机或群集上有效使用此算法需要复杂得多的软件工程。 在本文作者的这种算法的实现中,有成千上万的代码行,这里有必要确定通信协议,消息序列化和反序列化策略以及各种数据处理方法。

Ray的目标之一是通过添加相对较少的代码行来帮助从业人员将笔记本电脑上运行的原型算法转变为高性能的分布式应用程序,该程序可以在集群(或单台多核计算机)上高效地工作。 在性能方面,这样的框架应该具有手动优化系统的所有优点,并且不需要用户考虑调度,数据传输和机器崩溃的问题。

免费的AI框架

与其他深度学习框架链接 :Ray与TensorFlow,PyTorch和MXNet 等深度学习框架完全兼容,因此在许多应用程序中,将一个或多个其他深度学习框架与Ray一起使用是完全自然的(例如,积极地在我们的强化学习库中应用TensorFlow和PyTorch)。

与其他分布式系统的通信 :如今,使用了许多流行的分布式系统,但是大多数设计都没有考虑与AI相关的任务,因此它们不具备支持AI所需的性能,也没有表达AI应用方面的API。 在现代的分布式系统中,没有(必要,取决于系统)以下必要功能:

  • 毫秒级任务支持,每秒支持数百万个任务
  • 嵌套并行性(任务在任务内的并行化,例如,在搜索超参数时进行并行模拟)(请参见下图)
  • 任务之间的任意依赖关系,在执行期间动态变化(例如,不必等待,根据慢工的节奏进行调整)
  • 在共享变量状态下运行的任务(例如,神经网络或模拟器中的权重)
  • 支持异构资源(CPU,GPU等)




嵌套并发的简单示例。 在我们的应用程序中,并行执行两个实验(每个实验都是一项长期任务),并且在每个实验中都模拟了几个并行过程(每个过程也是一项任务)。

使用Ray的主要方法有两种:通过其低级API和通过高级库。 高级库建立在低级API的基础上。 这些当前包括Ray RLlib (用于增强学习的可伸缩库)和Ray.tune (用于分布式搜索超参数的有效库)。

射线低级API

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中使用Actor抽象来封装许多任务之间共享的可变状态。 这是一个说明性示例,演示了如何使用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)) 


尽管非常简单,但是actor的使用非常灵活。 例如,模拟器或神经网络策略可以封装在参与者中,也可以用于分布式训练(例如与参数服务器一起使用)或在“实时”应用程序中提供策略。



左:演员为许多客户流程提供预测/动作。 正确:参数服务器的许多参与者对许多工作流执行分布式培训。

参数服务器示例

可以将参数服务器实现为Ray actor,如下所示:

 @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 


这是一个更完整的示例

要实例化参数服务器,我们需要这样做。

 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 RLlib是一个可扩展的强化学习库,旨在用于多台计算机。 可以使用作为示例提供的训练脚本以及通过Pytho API启用它。 当前,它包括算法的实现:

  • A3C
  • Dqn
  • 进化策略
  • PPO


其他算法的实现正在进行中。 RLlib与OpenAI Gym完全兼容。

Ray.tune是用于超参数的分布式搜索的有效库。 它提供了一个Python API,用于深度学习,强化学习以及其他需要大量处理能力的任务。 这是这种说明性的示例:

 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]), }, } }) 


可以使用特殊工具(例如,来自rllab的Tensorboard和VisKit)将当前结果动态可视化(或直接读取JSON日志)。 Ray.tune支持网格搜索,随机搜索以及更多非平凡的早期停止算法,例如HyperBand。

更多关于雷

Source: https://habr.com/ru/post/zh-CN420695/


All Articles