Ray Tune 并行与资源指南#
并行性由每个 trial 的资源(默认每个 trial 1 个 CPU,0 个 GPU)和 Tune 可用的资源(ray.cluster_resources())决定。
默认情况下,Tune 会自动运行 N 个并发 trial,其中 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 来覆盖每个 trial 的资源。在这里,您可以使用字典或 PlacementGroupFactory 对象来指定您的资源请求。无论哪种情况,Ray Tune 都会尝试为每个 trial 启动一个 placement group。
# 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 的指定,为每个单独的 trial 分配指定的 GPU 和 CPU。即使 trial 目前无法被调度,Ray Tune 仍会尝试启动相应的 placement group。如果可用资源不足,当您使用 Ray 集群启动器时,这将触发自动扩展行为。
还可以指定内存("memory",以字节为单位)和自定义资源需求。
如果您的可训练函数启动了更多的远程 worker,您需要传递所谓的 placement group factory 对象来请求这些资源。有关更多信息,请参阅 PlacementGroupFactory 文档。当您使用其他利用 Ray 的库(例如 Modin)时,也适用此规则。如果未能正确设置资源,可能会导致死锁,使集群“挂起”。
注意
以这种方式指定的资源仅用于调度 Tune trial。这些资源不会自动强制应用到您的目标函数(Tune 可训练函数)上。您需要确保您的可训练函数有足够的资源来运行(例如,通过相应地设置 scikit-learn 模型的 n_jobs)。
如何在 Tune 中利用 GPU?#
要利用 GPU,您必须在 tune.with_resources(trainable, resources_per_trial) 中设置 gpu。这将自动为每个 trial 设置 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 示例 中找到一个示例。
警告
如果未设置 gpu,则 CUDA_VISIBLE_DEVICES 环境变量将设置为空,从而禁止 GPU 访问。
故障排除:有时,在运行新 trial 时可能会遇到 GPU 内存问题。这可能是由于前一个 trial 未能足够快地清理其 GPU 状态。为避免这种情况,您可以使用 tune.utils.wait_for_gpu。
如何使用 Tune 进行分布式训练?#
要对分布式训练作业进行调优,您可以使用 Ray Tune 和 Ray Train。Ray Tune 将并行运行多个 trial,每个 trial 都运行使用 Ray Train 的分布式训练。
有关更多详细信息,请参阅 Ray Train 超参数优化。
如何限制 Tune 中的并发性?#
要指定要并发运行的 trial 的最大数量,请在 TuneConfig 中设置 max_concurrent_trials。
请注意,实际的并行性可能小于 max_concurrent_trials,并将由有多少 trial 可以同时适合集群决定(即,如果您有一个需要 16 个 GPU 的 trial,您的集群有 32 个 GPU,并且 max_concurrent_trials=10,那么 Tuner 只能同时运行 2 个 trial)。
from ray.tune import TuneConfig
config = TuneConfig(
# ...
num_samples=100,
max_concurrent_trials=10,
)