备注
Ray 2.10.0 引入了 RLlib 的“新 API 栈”的 alpha 阶段。Ray 团队计划将算法、示例脚本和文档迁移到新的代码库中,从而在 Ray 3.0 之前的后续小版本中逐步替换“旧 API 栈”(例如,ModelV2、Policy、RolloutWorker)。
然而,请注意,到目前为止,只有 PPO(单代理和多代理)和 SAC(仅单代理)支持“新 API 堆栈”,并且默认情况下继续使用旧 API 运行。您可以继续使用现有的自定义(旧堆栈)类。
请参阅此处 以获取有关如何使用新API堆栈的更多详细信息。
开始使用 RLlib#
所有 RLlib 实验都使用一个 Algorithm
类来运行,该类包含用于环境交互的策略。通过算法的接口,您可以训练策略、计算动作或存储算法的状态(检查点)。在多智能体训练中,算法同时管理多个策略的查询和优化。
在本指南中,我们将详细解释用于运行学习实验的 RLlib 的 Python API。
使用 Python API#
Python API 提供了将 RLlib 应用于任何类型问题所需的所有灵活性。
让我们从一个API基本用法的例子开始。我们首先创建一个 PPOConfig
实例,并通过配置类的各种方法设置一些属性。例如,我们可以通过调用配置的 environment
方法来设置我们想要使用的RL环境。为了扩展我们的算法并定义我们想要利用多少个环境工作者(EnvRunners),我们可以调用 env_runners
方法。在我们从其配置中 build
出 PPO
算法之后,我们可以对其进行一定次数的 train`(这里为 `10
次),并定期 save
生成的策略(这里每 5
次迭代保存一次)。
from pprint import pprint
from ray.rllib.algorithms.ppo import PPOConfig
config = (
PPOConfig()
.api_stack(
enable_rl_module_and_learner=True,
enable_env_runner_and_connector_v2=True,
)
.environment("CartPole-v1")
.env_runners(num_env_runners=1)
)
algo = config.build()
for i in range(10):
result = algo.train()
result.pop("config")
pprint(result)
if i % 5 == 0:
checkpoint_dir = algo.save_to_path()
print(f"Checkpoint saved in directory {checkpoint_dir}")
所有 RLlib 算法都与 Tune API 兼容。这使得它们可以轻松地用于 Ray Tune 的实验中。例如,以下代码执行了一个简单的 PPO 超参数扫描。
from ray import train, tune
config = (
PPOConfig()
.api_stack(
enable_rl_module_and_learner=True,
enable_env_runner_and_connector_v2=True,
)
.environment("CartPole-v1")
.training(
lr=tune.grid_search([0.01, 0.001, 0.0001]),
)
)
tuner = tune.Tuner(
"PPO",
param_space=config,
run_config=train.RunConfig(
stop={"env_runners/episode_return_mean": 150.0},
),
)
tuner.fit()
Tune 将安排试验在您的 Ray 集群上并行运行:
== Status ==
Using FIFO scheduling algorithm.
Resources requested: 4/4 CPUs, 0/0 GPUs
Result logdir: ~/ray_results/my_experiment
PENDING trials:
- PPO_CartPole-v1_2_lr=0.0001: PENDING
RUNNING trials:
- PPO_CartPole-v1_0_lr=0.01: RUNNING [pid=21940], 16 s, 4013 ts, 22 rew
- PPO_CartPole-v1_1_lr=0.001: RUNNING [pid=21942], 27 s, 8111 ts, 54.7 rew
Tuner.fit()
返回一个 ResultGrid
对象,该对象允许进一步分析训练结果并检索训练代理的检查点。
from ray import train, tune
# Tuner.fit() allows setting a custom log directory (other than ~/ray-results).
tuner = tune.Tuner(
"PPO",
param_space=config,
run_config=train.RunConfig(
stop={"num_env_steps_sampled_lifetime": 20000},
checkpoint_config=train.CheckpointConfig(checkpoint_at_end=True),
),
)
results = tuner.fit()
# Get the best result based on a particular metric.
best_result = results.get_best_result(
metric="env_runners/episode_return_mean", mode="max"
)
# Get the best checkpoint corresponding to the best result.
best_checkpoint = best_result.checkpoint
备注
你可以通过查看检查点目录中的 rllib_checkpoint.json
文件来找到检查点的版本。
从检查点加载和恢复训练好的算法很简单。假设你有一个名为 checkpoint_path
的本地检查点目录。要加载较新的 RLlib 检查点(版本 >= 1.0),请使用以下代码:
from ray.rllib.algorithms.algorithm import Algorithm
algo = Algorithm.from_checkpoint(checkpoint_path)
对于较旧的 RLlib 检查点版本(版本 < 1.0),您可以通过以下方式恢复算法:
from ray.rllib.algorithms.ppo import PPO
algo = PPO(config=config, env=env_class)
algo.restore(checkpoint_path)
计算动作#
从训练好的代理程序中以编程方式计算动作的最简单方法是使用 Algorithm.compute_single_action()
。此方法在将观察结果传递给代理策略之前对其进行预处理和过滤。以下是一个简单的示例,用于测试训练好的代理在一个回合中的表现:
import pathlib
import gymnasium as gym
import numpy as np
import torch
from ray.rllib.core.rl_module import RLModule
env = gym.make("CartPole-v1")
# Create only the neural network (RLModule) from our checkpoint.
rl_module = RLModule.from_checkpoint(
pathlib.Path(best_checkpoint.path) / "learner_group" / "learner" / "rl_module"
)["default_policy"]
episode_return = 0
terminated = truncated = False
obs, info = env.reset()
while not terminated and not truncated:
# Compute the next action from a batch (B=1) of observations.
torch_obs_batch = torch.from_numpy(np.array([obs]))
action_logits = rl_module.forward_inference({"obs": torch_obs_batch})[
"action_dist_inputs"
]
# The default RLModule used here produces action logits (from which
# we'll have to sample an action or use the max-likelihood one).
action = torch.argmax(action_logits[0]).numpy()
obs, reward, terminated, truncated, info = env.step(action)
episode_return += reward
print(f"Reached episode return of {episode_return}.")
关于计算动作和其他功能的更高级用法,您可以查阅 RLlib 算法 API 文档。
访问策略状态#
通常需要访问算法的内部状态,例如设置或获取模型权重。
在 RLlib 算法中,状态在集群中的多个 *rollout workers*(Ray 角色)之间复制。然而,你可以通过 Algorithm.env_runner_group.foreach_worker()
或 Algorithm.env_runner_group.foreach_worker_with_index()
在调用 train()
之间轻松获取和更新此状态。这些函数接受一个 lambda 函数,该函数以 worker 作为参数应用。这些函数以列表形式返回每个 worker 的值。
你也可以通过 Algorithm.get_policy()
或 Algorithm.env_runner
访问算法的“主”副本状态,但请注意,这里的更新可能不会立即反映在你的回滚工作者中(如果你配置了 num_env_runners > 0
)。以下是一个快速访问模型状态的示例:
from ray.rllib.algorithms.ppo import PPOConfig
algo = (
PPOConfig()
.api_stack(
enable_rl_module_and_learner=True,
enable_env_runner_and_connector_v2=True,
)
.environment("CartPole-v1")
.env_runners(num_env_runners=2)
).build()
# Get weights of the algo's RLModule.
algo.get_module().get_state()
# Same as above
algo.env_runner.module.get_state()
# Get list of weights of each EnvRunner, including remote replicas.
algo.env_runner_group.foreach_worker(lambda env_runner: env_runner.module.get_state())
# Same as above, but with index.
algo.env_runner_group.foreach_worker_with_id(
lambda _id, env_runner: env_runner.module.get_state()
)
访问模型状态#
类似于访问策略状态,您可能希望获取对正在训练的基础神经网络模型的引用。例如,您可能希望单独对其进行预训练,或者在RLlib之外更新其权重。这可以通过访问策略的 model
来实现。
备注
要运行这些示例,您需要安装一些额外的依赖项,即 pip install "gym[atari]" "gym[accept-rom-license]" atari_py
。
下面你将找到三个显式示例,展示如何访问算法的模型状态。
示例:预处理观测数据以供模型输入
然后对于代码:
try:
import gymnasium as gym
env = gym.make("ALE/Pong-v5")
obs, infos = env.reset()
except Exception:
import gym
env = gym.make("PongNoFrameskip-v4")
obs = env.reset()
# RLlib uses preprocessors to implement transforms such as one-hot encoding
# and flattening of tuple and dict observations.
from ray.rllib.models.preprocessors import get_preprocessor
prep = get_preprocessor(env.observation_space)(env.observation_space)
# <ray.rllib.models.preprocessors.GenericPixelPreprocessor object at 0x7fc4d049de80>
# Observations should be preprocessed prior to feeding into a model
obs.shape
# (210, 160, 3)
prep.transform(obs).shape
# (84, 84, 3)
示例:查询策略的动作分布
# Get a reference to the policy
import numpy as np
from ray.rllib.algorithms.dqn import DQNConfig
algo = (
DQNConfig()
.environment("CartPole-v1")
.framework("tf2")
.env_runners(num_env_runners=0)
.build()
)
# <ray.rllib.algorithms.ppo.PPO object at 0x7fd020186384>
policy = algo.get_policy()
# <ray.rllib.policy.eager_tf_policy.PPOTFPolicy_eager object at 0x7fd020165470>
# Run a forward pass to get model output logits. Note that complex observations
# must be preprocessed as in the above code block.
logits, _ = policy.model({"obs": np.array([[0.1, 0.2, 0.3, 0.4]])})
# (<tf.Tensor: id=1274, shape=(1, 2), dtype=float32, numpy=...>, [])
# Compute action distribution given logits
policy.dist_class
# <class_object 'ray.rllib.models.tf.tf_action_dist.Categorical'>
dist = policy.dist_class(logits, policy.model)
# <ray.rllib.models.tf.tf_action_dist.Categorical object at 0x7fd02301d710>
# Query the distribution for samples, sample logps
dist.sample()
# <tf.Tensor: id=661, shape=(1,), dtype=int64, numpy=..>
dist.logp([1])
# <tf.Tensor: id=1298, shape=(1,), dtype=float32, numpy=...>
# Get the estimated values for the most recent forward pass
policy.model.value_function()
# <tf.Tensor: id=670, shape=(1,), dtype=float32, numpy=...>
policy.model.base_model.summary()
"""
Model: "model"
_____________________________________________________________________
Layer (type) Output Shape Param # Connected to
=====================================================================
observations (InputLayer) [(None, 4)] 0
_____________________________________________________________________
fc_1 (Dense) (None, 256) 1280 observations[0][0]
_____________________________________________________________________
fc_value_1 (Dense) (None, 256) 1280 observations[0][0]
_____________________________________________________________________
fc_2 (Dense) (None, 256) 65792 fc_1[0][0]
_____________________________________________________________________
fc_value_2 (Dense) (None, 256) 65792 fc_value_1[0][0]
_____________________________________________________________________
fc_out (Dense) (None, 2) 514 fc_2[0][0]
_____________________________________________________________________
value_out (Dense) (None, 1) 257 fc_value_2[0][0]
=====================================================================
Total params: 134,915
Trainable params: 134,915
Non-trainable params: 0
_____________________________________________________________________
"""
示例:从DQN模型获取Q值
# Get a reference to the model through the policy
import numpy as np
from ray.rllib.algorithms.dqn import DQNConfig
algo = DQNConfig().environment("CartPole-v1").framework("tf2").build()
model = algo.get_policy().model
# <ray.rllib.models.catalog.FullyConnectedNetwork_as_DistributionalQModel ...>
# List of all model variables
model.variables()
# Run a forward pass to get base model output. Note that complex observations
# must be preprocessed. An example of preprocessing is
# examples/offline_rl/saving_experiences.py
model_out = model({"obs": np.array([[0.1, 0.2, 0.3, 0.4]])})
# (<tf.Tensor: id=832, shape=(1, 256), dtype=float32, numpy=...)
# Access the base Keras models (all default models have a base)
model.base_model.summary()
"""
Model: "model"
_______________________________________________________________________
Layer (type) Output Shape Param # Connected to
=======================================================================
observations (InputLayer) [(None, 4)] 0
_______________________________________________________________________
fc_1 (Dense) (None, 256) 1280 observations[0][0]
_______________________________________________________________________
fc_out (Dense) (None, 256) 65792 fc_1[0][0]
_______________________________________________________________________
value_out (Dense) (None, 1) 257 fc_1[0][0]
=======================================================================
Total params: 67,329
Trainable params: 67,329
Non-trainable params: 0
______________________________________________________________________________
"""
# Access the Q value model (specific to DQN)
print(model.get_q_value_distributions(model_out)[0])
# tf.Tensor([[ 0.13023682 -0.36805138]], shape=(1, 2), dtype=float32)
# ^ exact numbers may differ due to randomness
model.q_value_head.summary()
# Access the state value model (specific to DQN)
print(model.get_state_value(model_out))
# tf.Tensor([[0.09381643]], shape=(1, 1), dtype=float32)
# ^ exact number may differ due to randomness
model.state_value_head.summary()
这在使用 自定义模型类 时特别有用。
配置 RLlib 算法#
你可以通过使用所谓的 AlgorithmConfig
对象以模块化的方式配置 RLlib 算法。本质上,你首先创建一个 config = AlgorithmConfig()
对象,然后调用其方法来设置所需的配置选项。每个 RLlib 算法都有自己的配置类,该类继承自 AlgorithmConfig
。例如,要创建一个 PPO
算法,你从 PPOConfig
对象开始,要使用 DQN
算法,你从 DQNConfig
对象开始,等等。
备注
每个算法都有其特定的设置,但大多数配置选项是共享的。我们在下面讨论常见的选项,并参考 RLlib 算法指南 获取算法特定的属性。算法之间的差异主要在于它们的 训练
设置。
下面你将找到 AlgorithmConfig
类的基本签名,以及一些高级用法示例:
- class ray.rllib.algorithms.algorithm_config.AlgorithmConfig(algo_class: type | None = None)[源代码]
RLlib 的 AlgorithmConfig 根据给定的配置构建一个 RLlib 算法。
from ray.rllib.algorithms.ppo import PPOConfig from ray.rllib.algorithms.callbacks import MemoryTrackingCallbacks # Construct a generic config object, specifying values within different # sub-categories, e.g. "training". config = (PPOConfig().training(gamma=0.9, lr=0.01) .environment(env="CartPole-v1") .resources(num_gpus=0) .env_runners(num_env_runners=0) .callbacks(MemoryTrackingCallbacks) ) # A config object can be used to construct the respective Algorithm. rllib_algo = config.build()
from ray.rllib.algorithms.ppo import PPOConfig from ray import tune # In combination with a tune.grid_search: config = PPOConfig() config.training(lr=tune.grid_search([0.01, 0.001])) # Use `to_dict()` method to get the legacy plain python config dict # for usage with `tune.Tuner().fit()`. tune.Tuner("PPO", param_space=config.to_dict())
由于 RLlib 算法相当复杂,它们带有许多配置选项。为了简化操作,算法的常见属性自然地被分组为以下类别:
让我们逐一讨论每个类别,从训练选项开始。
指定训练选项#
备注
例如,一个 DQNConfig
接受一个 double_q
训练
参数来指定是否使用双Q DQN,而在 PPOConfig
中这没有意义。
对于单个算法,这可能是最相关的配置组,因为所有算法特定的选项都在这里。但 AlgorithmConfig
的 training
基础配置实际上非常小:
- AlgorithmConfig.training(*, gamma: float | None = <ray.rllib.utils.from_config._NotProvided object>, lr: float | ~typing.List[~typing.List[int | float]] | None = <ray.rllib.utils.from_config._NotProvided object>, grad_clip: float | None = <ray.rllib.utils.from_config._NotProvided object>, grad_clip_by: str | None = <ray.rllib.utils.from_config._NotProvided object>, train_batch_size: int | None = <ray.rllib.utils.from_config._NotProvided object>, train_batch_size_per_learner: int | None = <ray.rllib.utils.from_config._NotProvided object>, model: dict | None = <ray.rllib.utils.from_config._NotProvided object>, optimizer: dict | None = <ray.rllib.utils.from_config._NotProvided object>, max_requests_in_flight_per_sampler_worker: int | None = <ray.rllib.utils.from_config._NotProvided object>, learner_class: ~typing.Type[Learner] | None = <ray.rllib.utils.from_config._NotProvided object>, learner_connector: ~typing.Callable[[RLModule], ConnectorV2 | ~typing.List[ConnectorV2]] | None = <ray.rllib.utils.from_config._NotProvided object>, add_default_connectors_to_learner_pipeline: bool | None = <ray.rllib.utils.from_config._NotProvided object>, learner_config_dict: ~typing.Dict[str, ~typing.Any] | None = <ray.rllib.utils.from_config._NotProvided object>) AlgorithmConfig [源代码]
设置与训练相关的配置。
- 参数:
gamma – 指定马尔可夫决策过程的折扣因子的浮点数。
lr – 学习率(浮点数)或学习率调度表,格式为 [[时间步, 学习率值], [时间步, 学习率值], …]。如果是调度表,中间的时间步将被分配为线性插值的学习率值。调度表配置的第一个条目必须从时间步 0 开始,即:[[0, 初始值], […]]。注意:如果您需要 a) 多个优化器(每个 RLModule),b) 非 Adam 类型的优化器,c) 非线性插值的分段调度表,或 d) 指定优化器的构造函数参数(如 Adam 的 epsilon),则必须重写 Learner 的
configure_optimizer_for_module()
方法,并自行处理学习率调度。grad_clip – 如果为 None,则不会应用梯度裁剪。否则,根据
grad_clip_by
的设置,grad_clip
的(浮点)值将产生以下效果:如果grad_clip_by=value
:将在区间 [-grad_clip
, +`grad_clip`] 内单独裁剪所有计算的梯度。如果grad_clip_by=norm
,将分别计算每个权重/偏置梯度张量的 L2 范数,然后裁剪所有梯度,使得这些 L2 范数不超过grad_clip
。张量的 L2 范数通过以下方式计算:sqrt(SUM(w0^2, w1^2, ..., wn^2))
,其中 w[i] 是张量的元素(无论张量的形状如何)。如果grad_clip_by=global_norm
,将分别计算每个权重/偏置梯度张量的 L2 范数的平方,将所有这些平方的 L2 范数在所有给定的梯度张量(例如,要更新的整个模块)上求和,对总和进行平方根运算,然后裁剪所有梯度,使得这个全局 L2 范数不超过给定值。一组张量(例如 W 和 V)的全局 L2 范数通过以下方式计算:sqrt[SUM(w0^2, w1^2, ..., wn^2) + SUM(v0^2, v1^2, ..., vm^2)]
,其中 w[i] 和 v[j] 是张量 W 和 V 的元素(无论这些张量的形状如何)。grad_clip_by – 参见
grad_clip
以了解此设置对梯度裁剪的影响。允许的值为value
、norm
和global_norm
。train_batch_size_per_learner – 每个 Learner 工作者的训练批次大小。此设置仅适用于新的 API 堆栈。可以通过
config.resources( num_learners=...)
设置 Learner 工作者的数量。总的有效批次大小为num_learners
xtrain_batch_size_per_learner
,并且可以通过属性AlgorithmConfig.total_train_batch_size
访问它。train_batch_size – 训练批次大小,如果适用。在新API栈上时,不应再使用此设置。相反,应使用
train_batch_size_per_learner`(结合 `num_learners
)。model – 传递给策略模型的参数。有关可用模型选项的完整列表,请参见 models/catalog.py。TODO: 提供 ModelConfig 对象而不是字典。
optimizer – 传递给策略优化器的参数。当
enable_rl_module_and_learner=True
时,此设置不使用。max_requests_in_flight_per_sampler_worker – 每个采样工作者的最大并发请求数。更多详情请参见FaultTolerantActorManager类。在运行大型样本批次实验时,调整这些值非常重要,因为存在对象存储可能填满的风险,导致对象溢出到磁盘。这可能会使任何异步请求变得非常慢,从而使您的实验运行缓慢。您可以通过在头节点上调用ray memory,并使用ray仪表板来检查实验期间的对象存储。如果您发现对象存储正在填满,请减少并发远程请求的数量,或在实验的时间步长中启用压缩。
learner_class – 用于(分布式)更新 RLModule 的
Learner
类。仅在enable_rl_module_and_learner=True
时使用。learner_connector – 一个可调用对象,接受环境观察空间和环境动作空间作为输入,并返回一个学习者 ConnectorV2(可能是一个管道)对象。
add_default_connectors_to_learner_pipeline – 如果为 True(默认),RLlib 的学习者将自动为 LearnerPipeline 添加默认的 Learner ConnectorV2 组件。这些自动执行以下操作:a) 如果用户提供的连接器组件尚未完成,则将来自剧集的观察结果添加到训练批次中;b) 如果 RLModule 是有状态的,则向训练批次添加时间等级,对数据进行零填充,并添加正确的状态输入,前提是用户提供的连接器组件尚未完成此操作;c) 如果用户提供的连接器组件尚未完成,则将所有其他信息(动作、奖励、终止等)添加到训练批次中。只有在你确切知道自己在做什么的情况下,才应将此设置设置为 False。请注意,此设置仅在使用新 API 堆栈(包括新的 EnvRunner 类)时相关。
learner_config_dict – 一个字典,用于插入学习者实例中可访问的任何设置。这应仅在与自定义学习者子类一起使用时使用,并且当用户不想仅为向基础算法的配置类添加几个设置而编写额外的
AlgorithmConfig
子类时。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定环境#
- AlgorithmConfig.environment(env: str | ~typing.Any | gymnasium.Env | None = <ray.rllib.utils.from_config._NotProvided object>, *, env_config: dict | None = <ray.rllib.utils.from_config._NotProvided object>, observation_space: gymnasium.spaces.Space | None = <ray.rllib.utils.from_config._NotProvided object>, action_space: gymnasium.spaces.Space | None = <ray.rllib.utils.from_config._NotProvided object>, env_task_fn: ~typing.Callable[[~typing.Dict, ~typing.Any | gymnasium.Env, ~ray.rllib.env.env_context.EnvContext], ~typing.Any] | None = <ray.rllib.utils.from_config._NotProvided object>, render_env: bool | None = <ray.rllib.utils.from_config._NotProvided object>, clip_rewards: bool | float | None = <ray.rllib.utils.from_config._NotProvided object>, normalize_actions: bool | None = <ray.rllib.utils.from_config._NotProvided object>, clip_actions: bool | None = <ray.rllib.utils.from_config._NotProvided object>, disable_env_checking: bool | None = <ray.rllib.utils.from_config._NotProvided object>, is_atari: bool | None = <ray.rllib.utils.from_config._NotProvided object>, action_mask_key: str | None = <ray.rllib.utils.from_config._NotProvided object>, auto_wrap_old_gym_envs=-1) AlgorithmConfig [源代码]
设置配置的 RL-环境设置。
- 参数:
env – 环境指定符。这可以是通过
tune.register_env([name], lambda env_ctx: [env object])
注册的调谐环境,或者是一个 RLlib 支持类型的字符串指定符。在后一种情况下,RLlib 将尝试将指定符解释为 Farama-Foundation gymnasium 环境、PyBullet 环境或一个完全限定的环境类路径,例如 “ray.rllib.examples.envs.classes.random_env.RandomEnv”。env_config – 传递给环境创建者的参数字典,作为 EnvContext 对象(这是一个字典,加上属性:
num_env_runners
、worker_index
、vector_index
和remote
)。observation_space – 该算法策略的观察空间。
action_space – 该算法策略的动作空间。
env_task_fn – 一个可调用对象,接受最后的训练结果、基础环境和环境上下文作为参数,并返回一个新的任务来设置环境。环境必须是
TaskSettableEnv
的子类才能工作。有关示例,请参见examples/curriculum_learning.py
。render_env – 如果为 True,尝试在本地工作进程或工作进程 1(如果 num_env_runners > 0)上渲染环境。对于向量化环境,这通常意味着只有第一个子环境将被渲染。为了使这工作,你的环境必须实现
render()
方法,该方法要么:a) 自行处理窗口生成和渲染(返回 True),要么 b) 返回形状为 [高度 x 宽度 x 3 (RGB)] 的 numpy uint8 图像。clip_rewards – 是否在策略的后处理过程中裁剪奖励。None(默认):仅对Atari裁剪(r=sign(r))。True:r=sign(r):固定奖励 -1.0, 1.0, 或 0.0。False:从不裁剪。[浮点数值]:在 -value 和 +value 处裁剪。Tuple[value1, value2]:在 value1 和 value2 处裁剪。
normalize_actions – 如果为 True,RLlib 将在一个归一化的动作空间内完全学习(以 0.0 为中心,具有小的标准差;仅影响 Box 组件)。RLlib 将在将动作发送回环境之前,将动作解归一化(并裁剪,以防万一)到环境的动作空间边界。
clip_actions – 如果为 True,RLlib 默认的 ModuleToEnv 连接器将根据环境的界限裁剪动作(在调用
env.step()
之前)。disable_env_checking – 在 EnvRunner 中构建了 gymnasium.Env 实例后,禁用 RLlib 的环境检查。请注意,这些检查包括
env.reset()
和 `env.step()`(使用随机动作),这可能会干扰您的环境逻辑和行为,从而对样本收集和/或学习行为产生负面影响。is_atari – 此配置可用于明确指定环境是否为 Atari 环境。如果未指定,RLlib 将尝试自动检测。
action_mask_key – 如果观察是一个字典,期望通过键
action_mask_key
包含一个有效的动作掩码(numpy.int8
数组,由零和一组成)。默认为 “action_mask”。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定框架选项#
- AlgorithmConfig.framework(framework: str | None = <ray.rllib.utils.from_config._NotProvided object>, *, eager_tracing: bool | None = <ray.rllib.utils.from_config._NotProvided object>, eager_max_retraces: int | None = <ray.rllib.utils.from_config._NotProvided object>, tf_session_args: ~typing.Dict[str, ~typing.Any] | None = <ray.rllib.utils.from_config._NotProvided object>, local_tf_session_args: ~typing.Dict[str, ~typing.Any] | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_learner: bool | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_learner_what_to_compile: str | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_learner_dynamo_mode: str | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_learner_dynamo_backend: str | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_worker: bool | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_worker_dynamo_backend: str | None = <ray.rllib.utils.from_config._NotProvided object>, torch_compile_worker_dynamo_mode: str | None = <ray.rllib.utils.from_config._NotProvided object>, torch_ddp_kwargs: ~typing.Dict[str, ~typing.Any] | None = <ray.rllib.utils.from_config._NotProvided object>, torch_skip_nan_gradients: bool | None = <ray.rllib.utils.from_config._NotProvided object>) AlgorithmConfig [源代码]
设置配置的深度学习框架设置。
- 参数:
framework – torch: PyTorch; tf2: TensorFlow 2.x (eager execution 或 eager_tracing=True 时 traced); tf: TensorFlow (静态图);
eager_tracing – 在急切模式下启用跟踪。这大大提高了性能(速度提升约2倍),但由于在初始急切传递后不会评估Python代码,因此调试起来稍微困难一些。仅在框架=tf2时可能。
eager_max_retraces – 在引发运行时错误之前,tf.function 重新追踪的最大次数。这是为了防止
..._eager_traced
策略中方法的未被注意的重新追踪,这可能会使执行速度降低4倍,而用户可能不会注意到导致这种减速的根本原因。仅在 framework=tf2 时需要。设置为 None 以忽略重新追踪计数,并且永远不会抛出错误。tf_session_args – 默认配置TF以进行单进程操作。
local_tf_session_args – 在本地工作节点上覆盖以下 tf 会话参数
torch_compile_learner – 如果为 True,学习器上的 TorchRLModules 的 forward_train 方法将被编译。如果未指定,默认情况下会在学习器上编译 forward_train。
torch_compile_learner_what_to_compile – 一个指定在 torch_compile_learner 为 True 时,学习者端需要编译内容的 TorchCompileWhatToCompile 模式。详情及使用建议请参阅 TorchCompileWhatToCompile。
torch_compile_learner_dynamo_backend – 在学习者上使用的 torch dynamo 后端。
torch_compile_learner_dynamo_mode – 在学习者上使用的 torch dynamo 模式。
torch_compile_worker – 如果为 True,则在工作者上的 TorchRLModules 上的前向探索和推理方法将被编译。如果未指定,默认情况下不会在工作者上编译前向方法,因为重新追踪可能会很昂贵。
torch_compile_worker_dynamo_backend – 在工作者上使用的 torch dynamo 后端。
torch_compile_worker_dynamo_mode – 在工作者上使用的 torch dynamo 模式。
torch_ddp_kwargs – 在使用
num_learners > 1
时传递给torch.nn.parallel.DistributedDataParallel
的 kwargs。这在搜索未使用的参数时特别有用,这些参数在反向传播过程中未被使用。这可以为自定义模型中的错误提供提示,其中某些参数虽然在反向传播中应该被触及,但实际上并未被触及。torch_skip_nan_gradients – 如果带有
nan
梯度的更新应该完全跳过。如果它们包含任何nan
梯度,这将完全跳过优化器中的更新。这有助于避免偏移基于移动平均的优化器 - 如 Adam。这可以在训练阶段帮助避免策略更新高度不稳定的情况,例如在训练的早期阶段或使用高度探索性策略时。在这些阶段,许多梯度可能会变为nan
,将它们设置为零可能会破坏优化器的内部状态。默认值为False
,并将nan
梯度设置为零。如果遇到许多nan
梯度,请考虑 (a) 通过将AlgorithmConfig
中的log_gradients
设置为True
来监控梯度,(b) 通过AlgorithmConfig.rl_module
中的model_config_dict
使用适当的权重初始化(例如 Xavier、Kaiming),和/或 (c) 通过AlgorithmConfig.training
中的grad_clip
进行梯度裁剪。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定推出工作器#
- AlgorithmConfig.rollouts(**kwargs)
指定评估选项#
- AlgorithmConfig.evaluation(*, evaluation_interval: int | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_duration: int | str | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_duration_unit: str | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_sample_timeout_s: float | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_parallel_to_training: bool | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_force_reset_envs_before_iteration: bool | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_config: ~ray.rllib.algorithms.algorithm_config.AlgorithmConfig | dict | None = <ray.rllib.utils.from_config._NotProvided object>, off_policy_estimation_methods: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, ope_split_batch_by_episode: bool | None = <ray.rllib.utils.from_config._NotProvided object>, evaluation_num_env_runners: int | None = <ray.rllib.utils.from_config._NotProvided object>, custom_evaluation_function: ~typing.Callable | None = <ray.rllib.utils.from_config._NotProvided object>, always_attach_evaluation_results=-1, evaluation_num_workers=-1) AlgorithmConfig [源代码]
设置配置的评估设置。
- 参数:
evaluation_interval – 在每次
evaluation_interval
训练迭代时进行评估。评估统计数据将在“evaluation”指标键下报告。设置为 None(或 0)以禁用评估。evaluation_duration – 每次
evaluation_interval
运行评估的持续时间。持续时间的单位可以通过evaluation_duration_unit
设置为“episodes”(默认)或“timesteps”。如果在evaluation_num_env_runners > 1
设置中使用多个评估工作线程(EnvRunners),则运行的 episodes/timesteps 数量将在这之间分配。如果evaluation_parallel_to_training=True
,可以使用特殊值“auto”。这是在尝试尽可能节省评估时间时的推荐方式。算法将通过评估工作线程运行尽可能多的 timesteps,同时不超过并行运行的训练步骤,从而不会在训练或评估工作线程上浪费任何空闲时间。当使用此设置(evaluation_duration="auto"
)时,强烈建议同时设置evaluation_interval=1
和evaluation_force_reset_envs_before_iteration=True
。evaluation_duration_unit – 用于计算评估持续时间的单位。可以是“episodes”(默认)或“timesteps”。请注意,如果
evaluation_duration="auto"
,则此设置将被忽略。evaluation_sample_timeout_s – 在以下情况下,评估工作者的超时时间(以秒为单位)用于采样一个完整的情节:
evaluation_duration != auto
且evaluation_duration_unit=episode
。超过此时间后,用户将收到警告并获得如何解决问题的指示。evaluation_parallel_to_training – 是否在调用
Algorithm.training_step()
时使用线程并行运行评估。默认=False。例如,对于 evaluation_interval=1 -> 在每次调用Algorithm.train()
时,Algorithm.training_step()
和Algorithm.evaluate()
调用将并行运行。请注意,此设置虽然非常高效,因为它不会浪费额外的时间进行评估,但会导致评估结果比训练结果滞后一次迭代。这在选择一个好的检查点时非常重要。例如,如果第42次迭代报告了良好的评估episode_return_mean
,请注意这些结果是在第41次迭代训练的权重上取得的,因此您可能应该选择第41次迭代的检查点。evaluation_force_reset_envs_before_iteration – 是否在迭代评估步骤开始之前强制重置所有环境(即使它们尚未完成)。将其设置为 True(默认值)将确保评估结果不会被实际上(至少部分)使用较早权重集实现的剧情节统计数据所污染。请注意,此设置仅在新 API 堆栈 w/ EnvRunners 和 ConnectorV2 上受支持(
config.enable_rl_module_and_learner=True
和config.enable_env_runner_and_connector_v2=True
)。evaluation_config – 典型用法是将额外参数传递给评估环境创建者,并通过计算确定性动作来禁用探索。重要提示:策略梯度算法能够找到最优策略,即使这是一个随机的策略。在此处设置“explore=False”将导致评估工作线程不使用此最优策略!
off_policy_estimation_methods – 指定如何评估当前策略,以及任何可选的配置参数。这仅在读取离线经验时有效(“input”不是“sampler”)。可用键:{ope_method_name: {“type”: ope_type, …}},其中
ope_method_name
是用户定义的字符串,用于保存OPE结果,ope_type
可以是任何OffPolicyEstimator的子类,例如 ray.rllib.offline.estimators.is::ImportanceSampling 或您自己的自定义子类,或者是子类的完整类路径。您还可以在字典中添加额外的配置参数,传递给OffPolicyEstimator,例如 {“qreg_dr”: {“type”: DoublyRobust, “q_model_type”: “qreg”, “k”: 5}}ope_split_batch_by_episode – 是否使用 SampleBatch.split_by_episode() 在估计ope指标之前将输入批次按剧集分割。对于强盗问题,您应该将其设置为False以提高ope评估速度。对于强盗问题,不按剧集分割是可以的,因为每个记录已经是一个时间步。默认值为True。
evaluation_num_env_runners – 用于评估的并行 EnvRunner 数量。请注意,默认情况下此值设置为零,这意味着评估将在算法进程中运行(仅当
evaluation_interval
不为 0 或 None 时)。如果增加此值,将增加算法的 Ray 资源使用量,因为评估工作线程是与用于采样训练数据的 EnvRunner 分开创建的。custom_evaluation_function – 自定义评估方法。这必须是一个签名函数 (algo: Algorithm, eval_workers: EnvRunnerGroup) -> (metrics: dict, env_steps: int, agent_steps: int) (如果
enable_env_runner_and_connector_v2=True
,则为 metrics: dict),其中env_steps
和agent_steps
定义了评估迭代期间采样的步数。请参阅 Algorithm.evaluate() 方法以查看默认实现。算法保证在此函数被调用之前,所有评估工作器都具有最新的策略状态。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定离线数据选项#
- AlgorithmConfig.offline_data(*, input_: str | ~typing.Callable[[~ray.rllib.offline.io_context.IOContext], ~ray.rllib.offline.input_reader.InputReader] | None = <ray.rllib.utils.from_config._NotProvided object>, input_read_method: str | ~typing.Callable | None = <ray.rllib.utils.from_config._NotProvided object>, input_read_method_kwargs: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, input_read_schema: ~typing.Dict[str, str] | None = <ray.rllib.utils.from_config._NotProvided object>, input_read_episodes: bool | None = <ray.rllib.utils.from_config._NotProvided object>, input_read_sample_batches: bool | None = <ray.rllib.utils.from_config._NotProvided object>, input_filesystem: str | None = <ray.rllib.utils.from_config._NotProvided object>, input_filesystem_kwargs: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, input_compress_columns: ~typing.List[str] | None = <ray.rllib.utils.from_config._NotProvided object>, map_batches_kwargs: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, iter_batches_kwargs: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, prelearner_class: ~typing.Type | None = <ray.rllib.utils.from_config._NotProvided object>, prelearner_module_synch_period: int | None = <ray.rllib.utils.from_config._NotProvided object>, dataset_num_iters_per_learner: int | None = <ray.rllib.utils.from_config._NotProvided object>, input_config: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, actions_in_input_normalized: bool | None = <ray.rllib.utils.from_config._NotProvided object>, postprocess_inputs: bool | None = <ray.rllib.utils.from_config._NotProvided object>, shuffle_buffer_size: int | None = <ray.rllib.utils.from_config._NotProvided object>, output: str | None = <ray.rllib.utils.from_config._NotProvided object>, output_config: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, output_compress_columns: ~typing.List[str] | None = <ray.rllib.utils.from_config._NotProvided object>, output_max_file_size: float | None = <ray.rllib.utils.from_config._NotProvided object>, output_max_rows_per_file: int | None = <ray.rllib.utils.from_config._NotProvided object>, output_write_method: str | None = <ray.rllib.utils.from_config._NotProvided object>, output_write_method_kwargs: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, output_filesystem: str | None = <ray.rllib.utils.from_config._NotProvided object>, output_filesystem_kwargs: ~typing.Dict | None = <ray.rllib.utils.from_config._NotProvided object>, output_write_episodes: bool | None = <ray.rllib.utils.from_config._NotProvided object>, offline_sampling: str | None = <ray.rllib.utils.from_config._NotProvided object>) AlgorithmConfig [源代码]
设置配置的离线数据设置。
- 参数:
input – 指定如何生成经验: - “sampler”:通过在线(环境)模拟生成经验(默认)。 - 本地目录或文件全局表达式(例如,”/tmp/.json”)。 - 单个文件路径/URI 列表(例如,[“/tmp/1.json”, “s3://bucket/2.json”])。 - 带有字符串键和采样概率作为值的字典(例如,{“sampler”: 0.4, “/tmp/.json”: 0.4, “s3://bucket/expert.json”: 0.2})。 - 一个可调用对象,它以
IOContext
对象作为唯一参数并返回一个 ray.rllib.offline.InputReader。 - 一个字符串键,索引一个带有 tune.registry.register_input 的可调用对象。input_read_method –
ray.data.Dataset
的read
方法用于从input_
读取离线数据。默认情况下,对于 Parquet 文件使用read_parquet
。更多关于ray.data
中可用的读取方法的信息,请参见 https://docs.ray.io/en/latest/data/api/input_output.html。input_read_method_kwargs –
input_read_method
的kwargs
。这些将被传递到读取方法中而不进行检查。如果没有传递参数,则使用默认参数{'override_num_blocks': max(num_learners * 2, 2)}
。使用这些kwargs
与map_batches_kwargs
和iter_batches_kwargs
一起调整数据管道的性能。input_read_schema – 用于将离线数据转换为片段的表格模式。此模式将离线数据列映射到
ray.rllib.core.columns. Columns
:{Columns.OBS: ‘o_t’, Columns.ACTIONS: ‘a_t’, …}。数据集中未通过此模式映射的列将被排序到片段的extra_model_outputs
中。如果没有传递模式,则使用默认模式ray.rllib.offline.offline_data.SCHEMA
。如果您的数据集已经包含此模式中的名称,则不需要input_read_schema
。input_read_episodes – 无论离线数据是否已经存储在 RLlib 的
EpisodeType
格式中,即ray.rllib.env.SingleAgentEpisode`(多智能体计划中但尚未支持)。直接读取剧集可以避免额外的转换步骤,并且通常更快,因此当您的应用程序完全在 RLlib 的模式内时,这是推荐的格式。另一种格式是列式格式,并且与使用的 RL 框架无关。如果您不确定何时使用数据或在哪个 RL 框架中使用数据,请使用后一种格式。默认是读取列数据,即 `False
。input_read_episodes
和inpuit_read_sample_batches
不能同时为True
。另请参阅output_write_episodes
以定义记录时的输出数据格式。input_read_sample_batches – 离线数据是否存储在RLlib的旧堆栈
SampleBatch
类型中。这通常是使用RLlib以JSON行格式记录的旧数据的情形。读取SampleBatch
数据需要额外的转换,并且可能无法将数据中包含在不同SampleBatch
中的片段拼接成完整的片段。如果可能,避免读取SampleBatch
并将它们以受控的形式转换为RLlib的EpisodeType`(即 `SingleAgentEpisode
或MultiAgentEpisode
)。默认值为False
。input_read_episodes
和inpuit_read_sample_batches
不能同时为True
。input_filesystem – 一个云文件系统,用于在读取经验时处理对云存储的访问。应为
gcs
表示 Google Cloud Storage,s3
表示 AWS S3 存储桶,或abs
表示 Azure Blob 存储。input_filesystem_kwargs – 一个包含
input_filesystem
指定的文件系统 kwargs 的字典。对于 GCS,请参阅gcsfs.GCSFilesystem
;对于 S3,请参阅pyarrow.fs.S3FileSystem
;对于 ABS 文件系统参数,请参阅ablfs.AzureBlobFilesystem
。input_compress_columns – 输入数据中哪些输入列使用LZ4进行压缩。如果数据存储在
RLlib
的SingleAgentEpisode
中(MultiAgentEpisode
尚不支持)。注意,rllib.core.columns.Columns.OBS
也会尝试解压缩rllib.core.columns.Columns.NEXT_OBS
。map_batches_kwargs –
map_batches
方法的kwargs
。这些将在不检查的情况下传递给ray.data.Dataset.map_batches
方法。如果没有传递参数,则使用默认参数{ 'concurrency': max(2, num_learners), 'zero_copy_batch': True}
。将这些kwargs
与input_read_method_kwargs
和iter_batches_kwargs
一起使用,以调整数据管道的性能。iter_batches_kwargs –
iter_batches
方法的kwargs
。这些参数将在不进行检查的情况下采样时传递给ray.data.Dataset.iter_batches
方法。如果没有传递任何参数,则使用默认参数{ 'prefetch_batches': 2, 'local_buffer_shuffle_size': train_batch_size_per_learner * 4}
。将这些kwargs
与input_read_method_kwargs
和map_batches_kwargs
一起使用,以调整数据管道的性能。prelearner_class – 一个可选的
OfflinePreLearner
类,用于在OfflineData
类中通过ray.data.map_batches
转换数据批次,将数据从列转换为可用于Learner
的update
方法的批次。如果需要对您的数据或损失进行特定的进一步转换,请重写OfflinePreLearner
类并将您的派生类传递到这里。默认值为None
,使用在ray.rllib.offline.offline_prelearner
中定义的基本OfflinePreLearner
。prelearner_module_synch_period – 在
PreLearner
持有的RLModule
应该同步权重的周期(转换的批次数量)之后。PreLearner
用于为学习者预处理批次。这个值越高,PreLearner
的模块将越偏离策略。值太小会迫使PreLearner
更频繁地同步,从而可能会减慢数据管道。OfflinePreLearner
选择的默认值是 10。dataset_num_iters_per_learner – 在每次训练迭代中,每个学习者运行的迭代次数。如果为
None
,则每个学习者在其数据块(数据集被划分为与学习者数量相同的块)上运行一个完整的 epoch。默认值为None
。input_config – 描述读取输入设置的参数。如果输入是
sample
,这将是环境配置,例如env_name
和env_config
等。更多信息请参见EnvContext
。如果输入是dataset
,这将是例如format
、path
。actions_in_input_normalized – 是的,如果给定离线“输入”中的动作已经归一化(介于 -1.0 和 1.0 之间)。当离线文件由另一个 RLlib 算法(例如 PPO 或 SAC)生成,并且“normalize_actions”设置为 True 时,通常就是这种情况。
postprocess_inputs – 是否对来自离线输入的轨迹片段运行 postprocess_trajectory()。请注意,后处理将使用*当前*策略进行,而不是*行为*策略,这对于同策略算法通常是不希望的。
shuffle_buffer_size – 如果为正,输入批次将通过此批次数量的滑动窗口缓冲区进行洗牌。如果输入数据的顺序不够随机,请使用此选项。输入将延迟,直到洗牌缓冲区被填满。
output – 指定经验应保存的位置: - None:不保存任何经验 - “logdir” 保存到代理日志目录 - 保存到自定义输出目录的路径/URI(例如,”s3://bckt/”) - 返回 rllib.offline.OutputWriter 的函数
output_config – 可从 IOContext 访问的参数,用于配置自定义输出。
output_compress_columns – 在输出数据中,哪些样本批次列需要使用LZ4压缩。注意,
rllib.core.columns.Columns.OBS
也会压缩rllib.core.columns.Columns.NEXT_OBS
。output_max_file_size – 滚动到新文件前的最大输出文件大小(以字节为单位)。
output_max_rows_per_file – 滚动到新文件前的最大输出行数。
output_write_method – 为
ray.data.Dataset
编写write
方法,将离线数据写入output
。默认情况下,对于 Parquet 文件使用read_parquet
。有关ray.data
中可用读取方法的更多信息,请参见 https://docs.ray.io/en/latest/data/api/input_output.html。output_write_method_kwargs –
output_write_method
的kwargs
。这些将被不加检查地传递到写入方法中。output_filesystem – 一个云文件系统,用于在编写体验时处理对云存储的访问。应为
gcs
表示 Google Cloud Storage,s3
表示 AWS S3 存储桶,或abs
表示 Azure Blob Storage。output_filesystem_kwargs – 一个包含
output_filesystem
指定的文件系统的 kwargs 的字典。对于 GCS,请参见gcsfs.GCSFilesystem
;对于 S3,请参见pyarrow.fs.S3FileSystem
;对于 ABS 文件系统参数,请参见ablfs.AzureBlobFilesystem
。offline_sampling – 算法是否通过读取离线数据进行采样。如果为 True,EnvRunners 将不会根据工作线程中的子环境数量(没有子环境存在)限制在同一
sample()
调用中收集的批次数量。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定多代理选项#
- AlgorithmConfig.multi_agent(*, policies: ~typing.Dict[str, PolicySpec] | ~typing.Collection[str] | None = <ray.rllib.utils.from_config._NotProvided object>, policy_map_capacity: int | None = <ray.rllib.utils.from_config._NotProvided object>, policy_mapping_fn: ~typing.Callable[[~typing.Any, OldEpisode], str] | None = <ray.rllib.utils.from_config._NotProvided object>, policies_to_train: ~typing.Collection[str] | ~typing.Callable[[str, SampleBatch | MultiAgentBatch | ~typing.Dict[str, ~typing.Any]], bool] | None = <ray.rllib.utils.from_config._NotProvided object>, policy_states_are_swappable: bool | None = <ray.rllib.utils.from_config._NotProvided object>, observation_fn: ~typing.Callable | None = <ray.rllib.utils.from_config._NotProvided object>, count_steps_by: str | None = <ray.rllib.utils.from_config._NotProvided object>, algorithm_config_overrides_per_module=-1, replay_mode=-1, policy_map_cache=-1) AlgorithmConfig [源代码]
设置配置的多代理设置。
验证新的多智能体设置,并将所有内容转换为统一的多智能体设置格式。例如,
policies
列表或 ID 集合被正确转换为将这些 ID 映射到 PolicySpecs 的字典。- 参数:
policies – 从策略ID映射到4元组(policy_cls, obs_space, act_space, config)或PolicySpecs的MultiAgentPolicyConfigDict类型映射。这些元组或PolicySpecs定义了策略的类、策略的观察和动作空间,以及任何额外的配置。
policy_map_capacity – 在将最近最少使用的策略写入磁盘/S3之前,在“policy_map”中保留这些策略。
policy_mapping_fn – 函数映射代理ID到策略ID。签名是:
(agent_id, episode, worker, **kwargs) -> PolicyID
。policies_to_train – 确定应更新的策略。选项包括:- 无,用于训练所有策略。- 应训练的PolicyIDs的可迭代对象。- 一个可调用对象,接受PolicyID和一个SampleBatch或MultiAgentBatch,并返回一个布尔值(指示在给定特定批次的情况下,给定策略是否可训练)。这允许你仅在特定数据上训练策略(例如,在与特定对手对战时)。
policy_states_are_swappable – 此映射中的所有策略对象是否可以通过简单的
state = A.get_state(); B.set_state(state)
进行“交换”,其中A
和B
是此映射中的策略实例。如果你的所有策略都共享相同的神经网络架构和优化器类型,你应该将此设置为 True,以显著加快 PolicyMap 的缓存查找时间。如果为 True,PolicyMap 将不需要垃圾回收旧的、最近最少使用的策略,而是将它们保留在内存中,并简单地用最近访问的策略的状态覆盖它们的状态。例如,在基于联盟的训练设置中,你的映射中可能有数百个相同的策略(以各种组合相互对战),但它们都共享相同的状态结构(可以“交换”)。observation_fn – 可选函数,可用于增强本地代理的观察结果以包含更多状态。更多信息请参见 rllib/evaluation/observation_function.py。
count_steps_by – 在构建 MultiAgentBatch 时,使用哪个指标作为“批量大小”。支持的两个值是:“env_steps”:每次环境“步进”时计数(无论传递了多少多智能体动作/在前一步中返回了多少多智能体观察结果)。“agent_steps”:将每个单独的智能体步进计为一步。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定报告选项#
- AlgorithmConfig.reporting(*, keep_per_episode_custom_metrics: bool | None = <ray.rllib.utils.from_config._NotProvided object>, metrics_episode_collection_timeout_s: float | None = <ray.rllib.utils.from_config._NotProvided object>, metrics_num_episodes_for_smoothing: int | None = <ray.rllib.utils.from_config._NotProvided object>, min_time_s_per_iteration: float | None = <ray.rllib.utils.from_config._NotProvided object>, min_train_timesteps_per_iteration: int | None = <ray.rllib.utils.from_config._NotProvided object>, min_sample_timesteps_per_iteration: int | None = <ray.rllib.utils.from_config._NotProvided object>) AlgorithmConfig [源代码]
设置配置的报告设置。
- 参数:
keep_per_episode_custom_metrics – 存储原始自定义指标,不计算最大值、最小值、平均值
metrics_episode_collection_timeout_s – 最多等待指标批次这么多秒。那些未及时返回的将在下一次训练迭代中收集。
metrics_num_episodes_for_smoothing – 如果可能,在此多集上平滑推出指标。如果推出(样本收集)刚刚开始,缓冲区中可能少于此多集,我们将计算这些可用集的指标。如果在一个训练迭代中收集的集数超过此数,则使用所有这些集进行指标计算,即不要裁剪任何“多余”集。将其设置为1以禁用平滑,并始终仅报告最近收集的集的回报。
min_time_s_per_iteration – 在一个
Algorithm.train()
调用中累积的最短时间(以秒为单位)。此值不影响学习,只影响Algorithm.train()
调用Algorithm.training_step()
的次数。如果在一次这样的步骤尝试后,所用时间未达到min_time_s_per_iteration
,将执行 n 次更多的Algorithm.training_step()
调用,直到达到最短时间。设置为 0 或 None 表示没有最短时间。min_train_timesteps_per_iteration – 在单个
train()
调用中累积的最小训练时间步数。此值不影响学习,仅影响Algorithm.train()
调用Algorithm.training_step()
的次数。如果在一次这样的步骤尝试后,训练时间步数尚未达到,将执行 n 次更多的training_step()
调用,直到达到最小时间步数。设置为 0 或 None 表示没有最小时间步数。min_sample_timesteps_per_iteration – 在一个
train()
调用中累积的最小环境采样时间步数。此值不影响学习,仅影响Algorithm.train()
调用Algorithm.training_step()
的次数。如果在一次这样的步骤尝试后,环境采样时间步数尚未达到,将执行 n 次更多的training_step()
调用,直到执行了最小时间步数。设置为 0 或 None 表示没有最小时间步数。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定检查点选项#
- AlgorithmConfig.checkpointing(export_native_model_files: bool | None = <ray.rllib.utils.from_config._NotProvided object>, checkpoint_trainable_policies_only: bool | None = <ray.rllib.utils.from_config._NotProvided object>) AlgorithmConfig [源代码]
设置配置的检查点设置。
- 参数:
export_native_model_files – 无论是单个策略还是算法的检查点是否也包含(tf 或 torch)原生模型文件。这些文件可以用来恢复这些文件中的神经网络模型,而不需要 RLlib。这些文件是通过调用实际模型上的 tf 或 torch 内置保存实用方法生成的。
checkpoint_trainable_policies_only – 是否仅将策略添加到算法检查点(在子目录“policies/”中),这些策略根据本地工作者的
is_trainable_policy
可调用函数是可训练的。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定调试选项#
- AlgorithmConfig.debugging(*, logger_creator: ~typing.Callable[[], ~ray.tune.logger.logger.Logger] | None = <ray.rllib.utils.from_config._NotProvided object>, logger_config: dict | None = <ray.rllib.utils.from_config._NotProvided object>, log_level: str | None = <ray.rllib.utils.from_config._NotProvided object>, log_sys_usage: bool | None = <ray.rllib.utils.from_config._NotProvided object>, fake_sampler: bool | None = <ray.rllib.utils.from_config._NotProvided object>, seed: int | None = <ray.rllib.utils.from_config._NotProvided object>, _run_training_always_in_thread: bool | None = <ray.rllib.utils.from_config._NotProvided object>, _evaluation_parallel_to_training_wo_thread: bool | None = <ray.rllib.utils.from_config._NotProvided object>) AlgorithmConfig [源代码]
设置配置的调试设置。
- 参数:
logger_creator – 创建 ray.tune.Logger 对象的可调用对象。如果未指定,则创建默认记录器。
logger_config – 定义日志记录器的特定配置,在日志记录器内部使用。默认值 None 允许使用嵌套字典进行覆盖。
log_level – 设置代理进程及其工作者的 ray.rllib.* 日志级别。应为 DEBUG、INFO、WARN 或 ERROR 之一。DEBUG 级别还将定期打印出相关内部数据流的摘要(这也会在启动时以 INFO 级别打印一次)。
log_sys_usage – 将系统资源指标记录到结果中。这需要安装
psutil
以获取系统统计信息,以及gputil
以获取 GPU 指标。fake_sampler – 使用假(无限速度)采样器。仅用于测试。
seed – 此参数与 worker_index 结合使用,为每个工作线程设置随机种子,从而使配置相同的试验具有相同的结果。这使得实验可重复。
_run_training_always_in_thread – 在每次迭代中,n 个
training_step()
调用总是在一个单独的线程中运行(就像我们在evaluation_parallel_to_training=True
时所做的那样,即使没有进行评估,甚至在算法中没有创建评估工作者)。_evaluation_parallel_to_training_wo_thread – 仅在
evaluation_parallel_to_training
为 True 时相关。此时,为了实现并行性,RLlib 将不会使用线程池(通常在这种情况下会使用)。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定回调选项#
- AlgorithmConfig.callbacks(callbacks_class) AlgorithmConfig [源代码]
设置回调配置。
- 参数:
callbacks_class – Callbacks 类,其方法将在训练和环境样本收集的各个阶段运行。更多使用信息请参见
DefaultCallbacks
类和examples/metrics/custom_metrics_and_callbacks.py
。- 返回:
这个更新的 AlgorithmConfig 对象。
指定资源#
你可以通过设置大多数算法的 num_env_runners
超参数来控制并行度。算法将构建那么多“远程工作者”实例(参见 RolloutWorker 类),这些实例作为 ray.remote 角色构建,再加上一个“本地工作者”,一个 EnvRunner
对象,它不是一个 ray 角色,而是直接存在于算法内部。对于大多数算法,学习更新在本地工作者上执行,从一个或多个环境中收集样本由远程工作者(并行)执行。例如,设置 num_env_runners=0
将只创建本地工作者,在这种情况下,样本收集和训练都将由本地工作者完成。另一方面,设置 num_env_runners=5
将创建本地工作者(负责训练更新)和 5 个远程工作者(负责样本收集)。
由于学习大部分时间是在本地工作者上完成的,因此通过 num_gpus
设置为该工作者提供一个或多个GPU可能会有所帮助。同样,您可以使用 num_cpus_per_env_runner
、num_gpus_per_env_runner
和 custom_resources_per_env_runner
来控制远程工作者的资源分配。
GPU的数量可以是分数(例如,0.5),以仅分配GPU的一部分。例如,使用DQN,您可以通过设置 num_gpus: 0.2
将五个算法打包到一个GPU上。请参阅 这里的分数GPU示例,该示例还展示了需要GPU的环境(在远程工作者上运行)如何从 num_gpus_per_env_runner
设置中受益。
对于像PPO和A2C这样的同步算法,驱动程序和工作程序可以利用相同的GPU。要做到这一点,对于一定数量的 n
个GPU:
gpu_count = n
num_gpus = 0.0001 # Driver GPU
num_gpus_per_env_runner = (gpu_count - num_gpus) / num_env_runners
如果你指定了 num_gpus
而你的机器没有足够的GPU可用,相应的worker将会抛出一个RuntimeError。另一方面,如果你设置 num_gpus=0
,你的策略将仅在CPU上构建,即使机器上有GPU可用。
- AlgorithmConfig.resources(*, num_cpus_for_main_process: int | None = <ray.rllib.utils.from_config._NotProvided object>, num_gpus: int | float | None = <ray.rllib.utils.from_config._NotProvided object>, _fake_gpus: bool | None = <ray.rllib.utils.from_config._NotProvided object>, placement_strategy: str | None = <ray.rllib.utils.from_config._NotProvided object>, num_cpus_per_worker=-1, num_gpus_per_worker=-1, custom_resources_per_worker=-1, num_learner_workers=-1, num_cpus_per_learner_worker=-1, num_gpus_per_learner_worker=-1, local_gpu_idx=-1, num_cpus_for_local_worker=-1) AlgorithmConfig [源代码]
指定为算法及其 ray 角色/工作者分配的资源。
- 参数:
num_cpus_for_main_process – 为主算法进程分配的CPU数量,该进程运行
Algorithm.training_step()
。注意:这仅在通过 Tune 运行 RLlib 时相关。否则,Algorithm.training_step()
在主程序(驱动程序)中运行。num_gpus – 分配给算法进程的GPU数量。请注意,并非所有算法都能利用GPU。目前仅支持tf-[PPO/IMPALA/DQN/PG]的多GPU。这可以是分数(例如,0.3个GPU)。
_fake_gpus – 在CPU机器上调试(多)GPU功能时设置为True。在这种情况下,GPU塔将由位于CPU上的图形模拟。使用
num_gpus
来测试不同数量的假GPU。placement_strategy – 由
Algorithm.default_resource_request()
返回的放置组工厂的策略。放置组定义了哪些设备(资源)应始终位于同一节点上。例如,一个具有2个EnvRunners和1个Learner(带1个GPU)的算法将请求一个包含以下捆绑包的放置组:[{‘cpu’: 1}, {‘gpu’: 1, ‘cpu’: 1}, {‘cpu’: 1}, {‘cpu’: 1}],其中第一个捆绑包用于本地(主算法)进程,第二个用于1个Learner工作线程,最后两个捆绑包用于两个EnvRunners。这些捆绑包现在可以根据placement_strategy
的值被“放置”在同一节点或不同节点上:’PACK’:将捆绑包尽可能少地打包到节点中。’SPREAD’:尽可能均匀地将捆绑包分布在不同的节点上。’STRICT_PACK’:将捆绑包打包到一个节点中。不允许组跨多个节点。’STRICT_SPREAD’:将捆绑包分布在不同的节点上。
- 返回:
这个更新的 AlgorithmConfig 对象。
指定实验性功能#
- AlgorithmConfig.experimental(*, _torch_grad_scaler_class: ~typing.Type | None = <ray.rllib.utils.from_config._NotProvided object>, _torch_lr_scheduler_classes: ~typing.List[~typing.Type] | ~typing.Dict[str, ~typing.Type] | None = <ray.rllib.utils.from_config._NotProvided object>, _tf_policy_handles_more_than_one_loss: bool | None = <ray.rllib.utils.from_config._NotProvided object>, _disable_preprocessor_api: bool | None = <ray.rllib.utils.from_config._NotProvided object>, _disable_action_flattening: bool | None = <ray.rllib.utils.from_config._NotProvided object>, _disable_initialize_loss_from_dummy_batch: bool | None = <ray.rllib.utils.from_config._NotProvided object>, _enable_new_api_stack=-1) AlgorithmConfig [源代码]
设置配置的实验性设置。
- 参数:
_torch_grad_scaler_class – 用于 torch 损失缩放(和梯度反缩放)的类。该类必须实现以下方法才能与
TorchLearner
兼容。这些方法/API 与 torch 自己的torch.amp.GradScaler
完全匹配(更多详情请参见 https://pytorch.org/docs/stable/amp.html#gradient-scaling):scale([loss])
用于按某个因子缩放损失。get_scale()
用于获取当前缩放因子值。step([optimizer])
用于反缩放梯度(除以缩放因子)并执行给定的优化器步骤。update()
用于在优化器步骤后更新缩放器(例如调整缩放因子)。_torch_lr_scheduler_classes – 一个
torch.lr_scheduler.LRScheduler
类(更多详情请参见 https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate)列表,或一个将模块ID映射到此类调度器类列表的字典。可以按顺序应用多个调度器类,并将按照此处定义的顺序进行步进。注意,大多数学习率调度器需要配置参数,即你需要在列表中部分初始化调度器。_tf_policy_handles_more_than_one_loss – 实验性标志。如果为 True,TFPolicy 将处理多个损失/优化器。如果你希望从
loss_fn
返回多个损失项,并从optimizer_fn
返回相同数量的优化器,请将其设置为 True。未来,此项的默认值将为 True。_disable_preprocessor_api – 实验性标志。如果为 True,则不会创建(观察)预处理器,观察结果将按环境返回的方式传递给模型。未来,此项的默认值将为 True。
_disable_action_flattening – 实验性标志。如果为 True,RLlib 将不再将策略计算的动作展平为一个单一的张量(用于存储在 SampleCollectors/输出文件等中),而是保持(可能嵌套的)动作不变。禁用展平会影响: - SampleCollectors:必须存储可能嵌套的动作结构。 - 将先前动作作为输入一部分的模型。 - 从离线文件读取的算法(包括动作信息)。
- 返回:
这个更新的 AlgorithmConfig 对象。
RLlib 扩展指南#
以下是使用RLlib进行训练扩展的一些经验法则。
如果环境运行缓慢且无法复制(例如,因为它需要与物理系统交互),那么你应该使用一种样本效率高的离策略算法,如 DQN 或 SAC。这些算法默认在单进程操作中使用
num_env_runners: 0
。如果你想使用GPU,请确保设置num_gpus: 1
。还可以考虑使用 离线数据 API 进行批量RL训练。
2. If the environment is fast and the model is small (most models for RL are), use time-efficient algorithms such as PPO, or IMPALA.
These can be scaled by increasing num_env_runners
to add rollout workers. It may also make sense to enable vectorization for
inference. Make sure to set num_gpus: 1
if you want to use a GPU. If the learner becomes a bottleneck, you can use multiple GPUs for learning by setting
num_gpus > 1
.
如果模型计算密集(例如,一个大型的深度残差网络)且推理是瓶颈,考虑通过设置
num_gpus_per_env_runner: 1
为工作者分配GPU。如果你只有一个GPU,考虑num_env_runners: 0
以使用学习者的GPU进行推理。为了高效利用GPU时间,使用少量GPU工作者和大量 每个工作者的环境。最后,如果模型和环境都是计算密集型的,那么可以通过设置
remote_worker_envs: True
和可选的remote_env_batch_wait_ms
来启用 远程工作环境 和 异步批处理。这会在回滚工作者的GPU上批量进行推理,同时让环境在单独的演员中异步运行,类似于 SEED 架构。工作者数量和每个工作者环境数量应调整以最大化GPU利用率。
如果你使用大量工作进程(num_env_runners >> 10
)并且你观察到由于任何原因导致的工作进程失败,这些失败通常会中断你的 RLlib 训练运行,可以考虑使用配置设置 ignore_env_runner_failures=True
、recreate_failed_env_runners=True
或 restart_failed_sub_environments=True
:
ignore_env_runner_failures
: 当设置为 True 时,您的算法不会因为单个工作者的错误而崩溃,而是会继续运行,只要至少有一个功能正常的工作者存在。recreate_failed_env_runners
: 当设置为 True 时,您的算法将尝试用新创建的工作者替换/重新创建任何失败的工作者。这样,即使某些工作者偶尔失败,您的工作者数量也不会减少。restart_failed_sub_environments
: 当设置为 True 并且在您的一个工作者中的一个向量化子环境中发生故障时,该工作者将尝试仅重新创建失败的子环境,并将新创建的子环境重新集成到该工作者上的向量化环境堆栈中。
请注意,ignore_env_runner_failures
或 recreate_failed_env_runners
中只能有一个设置为 True(它们是互斥的设置)。然而,你可以将这些设置与 restart_failed_sub_environments=True
设置结合使用。使用这些选项将使你的训练运行更加稳定,并且更能抵御偶尔的 OOM 或其他类似的“偶尔”错误,这些错误可能发生在你的工作节点本身或你的环境中。
调试 RLlib 实验#
急切模式#
使用 build_tf_policy
构建的策略(大多数参考算法都是)可以通过设置 "framework": "tf2"
/ "eager_tracing": true
配置选项在急切模式下运行。这将告诉 RLlib 在急切模式下执行模型前向传递、动作分布、损失和统计函数。
急切模式使得调试变得更加容易,因为现在你可以使用带断点的逐行调试或 Python 的 print()
来检查中间张量的值。然而,除非启用追踪,否则急切模式可能比图模式更慢。
Episode Traces
#
你可以使用 数据输出API 来保存用于调试的片段轨迹。例如,以下命令将在保存片段轨迹到 /tmp/debug
的同时运行PPO。
cd rllib/tuned_examples/ppo
python cartpole_ppo.py --output /tmp/debug
# episode traces will be saved in /tmp/debug, for example
output-2019-02-23_12-02-03_worker-2_0.json
output-2019-02-23_12-02-04_worker-1_0.json
日志详细程度#
你可以通过 "log_level"
标志控制日志级别。有效值为 “DEBUG”、”INFO”、”WARN”(默认)和 “ERROR”。这可以用来增加或减少内部日志的详细程度。例如:
cd rllib/tuned_examples/ppo
python atari_ppo.py --env ALE/Pong-v5 --log-level INFO
python atari_ppo.py --env ALE/Pong-v5 --log-level DEBUG
默认日志级别是 WARN
。我们强烈建议在开发中至少使用 INFO
级别的日志记录。
堆栈跟踪#
你可以使用 ray stack
命令来转储单个节点上所有 Python 工作者的堆栈跟踪。这对于调试意外挂起或性能问题非常有用。
下一步#
要检查您的应用程序的运行情况,您可以使用 Ray 仪表盘。