Tune 如何工作?#
本页面提供了 Tune 内部工作原理的概述。我们将详细介绍调用 Tuner.fit() 时会发生什么,Tune trial 的生命周期是什么样的,以及 Tune 的架构组件是什么。
提示
在继续之前,请务必阅读 Tune 关键概念页面。
在 Tuner.fit 中会发生什么?#
调用以下代码时
space = {"x": tune.uniform(0, 1)}
tuner = tune.Tuner(
my_trainable,
param_space=space,
tune_config=tune.TuneConfig(num_samples=10),
)
results = tuner.fit()
提供的 my_trainable 会与不同的超参数(从 uniform(0, 1) 中采样)并行执行多次。
每次 Tune 运行都包含一个“驱动进程”和许多“工作进程”。驱动进程是调用 Tuner.fit() 的 Python 进程(该进程在后台调用 ray.init())。Tune 驱动进程运行在运行脚本(调用 Tuner.fit() 的脚本)的节点上,而 Ray Tune trainable “actors” 则运行在任何节点上(无论是同一节点还是工作节点(仅限分布式 Ray))。
注意
Ray Actors 允许您并行化 Python 类的一个实例。当您实例化一个 Ray actor 类时,Ray 将在单独的进程中启动该类的一个实例,该进程可能位于同一台机器上(或者,如果运行的是 Ray 集群,则位于另一台分布式机器上)。然后,该 actor 可以异步执行方法调用并维护其自己的内部状态。
驱动程序会生成并行工作进程(Ray actors),这些进程负责使用超参数配置和提供的可训练对象来评估每个 trial。
在可训练对象执行期间(Tune 中可训练对象的执行),Tune 驱动程序通过 actor 方法与每个 actor 通信,以接收中间训练结果并暂停/停止 actor(参见 Tune Trial 的生命周期)。
当可训练对象终止(或被停止)时,actor 也会终止。
Tune 中可训练对象的执行#
Tune 使用 Ray actors 来并行评估多个超参数配置。每个 actor 是一个 Python 进程,它执行用户提供的可训练对象的一个实例。
用户提供的可训练对象的定义将通过 cloudpickle 进行序列化,并发送到每个 actor 进程。每个 Ray actor 将启动一个可执行的可训练对象实例。
如果可训练对象是一个类,它将通过调用 train/step 来迭代执行。每次调用后,驱动程序都会收到一个“结果字典”已准备好的通知。然后,驱动程序将通过 ray.get 拉取结果。
如果可训练对象是一个可调用对象或函数,它将在 Ray actor 进程的单独执行线程中执行。每当调用 tune.report 时,执行线程将暂停并等待驱动程序拉取结果(参见 function_trainable.py)。拉取后,actor 的执行线程将自动恢复。
Tune 中的资源管理#
在运行 trial 之前,Ray Tune 驱动程序将检查集群上是否有可用资源(参见 指定任务或 Actor 的资源要求)。它会将可用资源与 trial 所需的资源进行比较。
如果在集群上有空间,则 Tune 驱动程序将启动一个 Ray actor(worker)。该 actor 将被调度并在具有可用资源的某个节点上执行。有关更多信息,请参见 Ray Tune 的并行性和资源指南。
Tune Trial 的生命周期#
一个 trial 的生命周期包含 6 个阶段
初始化(生成):Trial 首先作为一个超参数样本生成,并根据 `Tuner` 中提供的内容配置其参数。然后,Trial 被放入队列以待执行(状态为 PENDING)。
PENDING:Pending trial 是将在机器上执行的 trial。每个 trial 都配置有资源值。只要 trial 的资源值可用,Tune 就会运行该 trial(通过启动一个持有配置和训练函数的 ray actor)。
RUNNING:Running trial 被分配了一个 Ray Actor。可以有多个 Running trial 并行运行。有关更多详细信息,请参见 trainable execution 部分。
ERRORED:如果一个正在运行的 trial 抛出异常,Tune 将捕获该异常并将 trial 标记为 errored。请注意,异常可能会从 actor 传播到主 Tune 驱动程序进程。如果设置了 max_retries,Tune 将将 trial 设置回“PENDING”状态,并稍后从最后一个检查点重新启动它。
TERMINATED:如果一个 trial 被 Stopper/Scheduler 停止,它将被终止。如果使用 Function API,当函数停止时,trial 也会被终止。
PAUSED:Trial 可以被 Trial scheduler 暂停。这意味着 trial 的 actor 将被停止。暂停的 trial 稍后可以从最近的检查点恢复。
Tune 的架构#
蓝色框表示内部组件,绿色框表示面向公众的组件。
Tune 的主要组件包括 TuneController、Trial 对象、一个 SearchAlgorithm、一个 TrialScheduler 和一个 Trainable。
这是高层训练流程以及某些组件如何交互的图示
注意:此图可水平滚动
TuneController#
[源代码] 这是训练循环的主要驱动程序。此组件使用 TrialScheduler 来确定 trial 的优先级并执行它们,向 SearchAlgorithm 查询要评估的新配置,并处理容错逻辑。
容错:TuneController 在设置了 checkpoint_freq 时执行检查点,并在 trial 失败时自动重新启动 trial(如果设置了 max_failures)。例如,如果一个节点在 trial(特别是 trial 对应的 Trainable)在该节点上执行且启用了检查点时丢失,那么当 trial 重新运行时,它将被恢复到“PENDING”状态并从最后一个可用检查点恢复。TuneController 还负责在每次循环迭代时对整个实验执行状态进行检查点。这使用户能够在发生机器故障时重新启动实验。
请参见 TuneController 的文档字符串。
Trial 对象#
[源代码] 这是一个内部数据结构,包含每个训练运行的元数据。每个 Trial 对象与 Trainable 对象是一对一映射的,但它们本身不是分布式/远程的。Trial 对象在以下状态之间转换:“PENDING”、“RUNNING”、“PAUSED”、“ERRORED”和“TERMINATED”。
请参见 Trial 的文档字符串。
SearchAlg#
[源代码] SearchAlgorithm 是一个用户提供的对象,用于查询要评估的新超参数配置。
SearchAlgorithms 将在每次 trial 完成一个训练步骤(train())的执行、每次 trial 出错以及每次 trial 完成时收到通知。
TrialScheduler#
[源代码] TrialSchedulers 在一组可能运行的 trial 上进行操作,在给定可用集群资源的情况下确定 trial 执行的优先级。
TrialSchedulers 可以杀死或暂停 trial,并且还可以重新排序/确定传入 trial 的优先级。
Trainables#
[源代码] 这些是用户提供的用于训练过程的对象。如果提供的是一个类,则期望它符合 Trainable 接口。如果提供的是一个函数,则将其包装成一个 Trainable 类,并在单独的线程中执行函数本身。
Trainables 将执行一步 train(),然后通知 TrialRunner。