Ray Tune 的并行性和资源指南#

并行性由每个试验的资源决定(默认每个试验使用1个CPU,0个GPU)以及Tune可用的资源(ray.cluster_resources())。

默认情况下,Tune 会自动运行 N 个并发试验,其中 N 是您机器上的 CPU(核心)数量。

# If you have 4 CPUs on your machine, this will run 4 concurrent trials at a time.
tuner = tune.Tuner(
    trainable,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

你可以使用 tune.with_resources 为每次试验覆盖此资源。在这里,你可以使用字典或 PlacementGroupFactory 对象指定资源请求。无论哪种情况,Ray Tune 都会尝试为每次试验启动一个放置组。

# If you have 4 CPUs on your machine, this will run 2 concurrent trials at a time.
trainable_with_resources = tune.with_resources(trainable, {"cpu": 2})
tuner = tune.Tuner(
    trainable_with_resources,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

# If you have 4 CPUs on your machine, this will run 1 trial at a time.
trainable_with_resources = tune.with_resources(trainable, {"cpu": 4})
tuner = tune.Tuner(
    trainable_with_resources,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

# Fractional values are also supported, (i.e., {"cpu": 0.5}).
# If you have 4 CPUs on your machine, this will run 8 concurrent trials at a time.
trainable_with_resources = tune.with_resources(trainable, {"cpu": 0.5})
tuner = tune.Tuner(
    trainable_with_resources,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

# Custom resource allocation via lambda functions are also supported.
# If you want to allocate gpu resources to trials based on a setting in your config
trainable_with_resources = tune.with_resources(trainable,
    resources=lambda spec: {"gpu": 1} if spec.config.use_gpu else {"gpu": 0})
tuner = tune.Tuner(
    trainable_with_resources,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

Tune 将根据 tune.with_resources 指定的 GPU 和 CPU 分配给每个单独的试验。即使当前无法调度试验,Ray Tune 仍会尝试启动相应的放置组。如果没有足够的资源可用,如果你使用的是 Ray 集群启动器,这将触发 自动扩展行为

警告

tune.with_resources 不能与 Ray Train 训练器 一起使用。如果你将训练器传递给调优器,请使用 ScalingConfig 在训练器实例中指定资源需求。下面概述的一般原则仍然适用。

还可以指定内存("memory",以字节为单位)和自定义资源需求。

如果你的可训练函数启动了更多的远程工作者,你需要传递所谓的放置组工厂对象来请求这些资源。更多信息请参阅 PlacementGroupFactory 文档。如果你使用其他利用 Ray 的库,如 Modin,这也适用。未能正确设置资源可能会导致死锁,使集群“挂起”。

备注

这种方式指定的资源将仅用于调度 Tune 试验。这些资源不会自动强制应用于你的目标函数(Tune 可训练对象)。你需要确保你的可训练对象有足够的资源来运行(例如,通过相应地设置 n_jobs 来调整 scikit-learn 模型)。

如何在 Tune 中利用 GPU?#

要利用GPU,你必须在 tune.with_resources(trainable, resources_per_trial) 中设置 gpu。这将自动为每个试验设置 CUDA_VISIBLE_DEVICES

# If you have 8 GPUs, this will run 8 trials at once.
trainable_with_gpu = tune.with_resources(trainable, {"gpu": 1})
tuner = tune.Tuner(
    trainable_with_gpu,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

# If you have 4 CPUs and 1 GPU on your machine, this will run 1 trial at a time.
trainable_with_cpu_gpu = tune.with_resources(trainable, {"cpu": 2, "gpu": 1})
tuner = tune.Tuner(
    trainable_with_cpu_gpu,
    tune_config=tune.TuneConfig(num_samples=10)
)
results = tuner.fit()

你可以在 Keras MNIST 示例 中找到这个的示例。

警告

如果未设置 gpuCUDA_VISIBLE_DEVICES 环境变量将被设置为空,从而禁止访问 GPU。

故障排除:偶尔,在运行新试验时,您可能会遇到GPU内存问题。这可能是由于前一次试验没有足够快地清理其GPU状态。为了避免这种情况,您可以使用 tune.utils.wait_for_gpu

如何使用 Tune 进行分布式训练?#

要调整分布式训练任务,您可以使用 Ray Tune 与 Ray Train。Ray Tune 将并行运行多个试验,每个试验使用 Ray Train 进行分布式训练。

更多详情,请参阅 Ray Train 超参数优化

如何在 Tune 中限制并发?#

要指定同时运行的最大试验次数,请在 TuneConfig 中设置 max_concurrent_trials

请注意,实际的并行度可能小于 max_concurrent_trials,并将由集群中一次可以容纳的试验数量决定(例如,如果您有一个需要 16 个 GPU 的试验,您的集群有 32 个 GPU,并且 max_concurrent_trials=10,则 Tuner 只能同时运行 2 个试验)。

from ray.tune import TuneConfig

config = TuneConfig(
    # ...
    num_samples=100,
    max_concurrent_trials=10,
)