Ray 是一个用于构建和运行分布式应用程序的快速而简单的框架。它具有以下特点: - 提供简单的单元来构建和运行分布式应用程序; - 允许用户并行化单个机器代码,且几乎不需要更改代码; - 在 Ray Core 之上包含一个大型的应用程序、库和工具生态系统,以支持复杂的应用程序。
Ray Core 为应用程序构建提供了基本单元。在 Ray Core 之上有多个库用于解决机器学习中的问题,例如 Tune 用于可扩展的超参数调优,RLlib 用于可扩展的强化学习,RaySGD 用于分布式训练包装,Ray Serve 用于可扩展和可编程的服务。
RLlib 是基于 Ray 开发的强化学习框架,它为各种应用程序提供了高可扩展性和统一的 API。RLlib 本身支持 TensorFlow、TensorFlow Eager 和 PyTorch,但其大多数内部内容与框架无关。
Ray 的关键组件包括: - RayLet 进程:维护着一个 Node Manager(主要负责管理 Node 下的 Worker、调度在 Node 上的任务、管理任务间的依赖顺序等)和一个 Object Manager(主要提供从其他 Object Manager Pull/Push Object 的能力)。 - Plasma Store 进程:是一个共享内存的对象存储进程。
Ray 提交任务的方式与 Spark 类似,需要利用 Driver 来提交任务,而任务会在 Worker 上进行执行。Ray 支持的任务分为两类,分别是任务(Task)和 Actor 方法(ActorMethod)。任务是被打上了remote
注解的函数,其返回的是一个 Object ID,可通过ray.get(object_id)
获得实际结果;Actor 方法是被打上了remote
注解的类(即 Actor)的成员方法和构造方法,Actor 会保有自己的状态,所有的 Actor 方法需要在 Actor 所在的节点才能执行。
如果需要运行一个 Ray 集群,通常需要两个角色的节点,分别是 Head 和 Worker。可以在传统服务器上手动部署,或在 Kubernetes 上部署,也可利用 Ray Autoscaler 自动地创建集群,它能根据集群的负载情况自动地调整集群的规模。
在使用 RLlib 时,用户只需指定算法名称和环境就能开始训练,而算法中使用的深度神经网络模型以及策略中使用的损失函数和梯度优化器等组件都是封装好的。RLlib 中的一些关键概念包括:
-
策略(Policies):是定义智能体如何在环境中工作的 Python 类。在 Gym 中可能只有一个智能体和策略;在向量环境中,策略推理是针对多个代理的;在多代理中,可能有多个策略,每个策略控制一个或多个代理。
-
采样批次(Sample Batches):RLlib 中所有数据交换都是以批样的形式进行的。采样批次编码一个轨迹的一个或多个片段。通常,RLlib 从 rollout worker 中收集大小为
rollout_fragment_length
的批,并将一个或多个批连接到大小为train_batch_size
的批中,该批是随机梯度下降(SGD)的输入。 -
训练器(Trainers):每个策略都定义了一个
learn_on_batch()
方法,该方法根据输入的样例批处理改进策略。RLlibTrainer 类协调分布式工作流(启动 rollouts worker 和策略优化),利用 Ray actor 将训练从单个核扩展到集群中的数千个核。可以通过更改num_workers
参数来配置用于培训的并行性。
此外,RLlib 还支持离线数据集上的批处理训练,并为外部应用程序提供了各种集成策略,同时也提供了很多自定义训练过程中各个方面的方法,包括环境、神经网络模型、行动分布和策略定义等。
例如,安装 RLlib 及相关依赖(如 TensorFlow 或 PyTorch)后,可以使用如下代码训练一个在CartPole-v0
环境中使用 PPO 算法的智能体:
from ray.rllib.algorithms.ppo import PPOConfig
config = (
# 配置算法
PPOConfig()
.environment("CartPole-v0")
# 定义训练参数等
)
# 构建算法并训练
algorithm = config.build()
algorithm.train()
# 评估训练后的算法
algorithm.evaluate()