RLlib Training APIs

RLlib Training APIs 文档内容

Getting Started

在高层次上,RLlib 提供了一个包含环境交互策略的 Trainer 类。通过训练器接口,可以训练策略、设置检查点或计算动作。在多智能体训练中,Trainer同时管理多个策略的查询和优化。
在这里插入图片描述
(上图所示,在每个Rollout Workers内,交换完成之后,交由Trainer进行策略改进,计算动作等操作)
您可以使用以下命令训练一个简单的 DQN 训练器:

pip install "ray[rllib]" tensorflow
rllib train --run DQN --env CartPole-v0  # --config '{"framework": "tf2", "eager_tracing": true}' for eager execution

默认情况下,结果将记录到 ~/ray_results 的子目录中。此子目录将包含一个包含超参数的文件 params.json、一个包含每个情节的训练摘要的文件 result.json 和一个可用于通过运行使用 TensorBoard 可视化训练过程的 TensorBoard 文件

tensorboard --logdir=~/ray_results

rllib train 命令(与 repo 中的 train.py 脚本相同)具有许多选项,您可以通过运行来显示:

rllib train --help
-or-
python ray/rllib/train.py --help

(上述的代码均在terminal界面输入)
最重要的选项是使用 --env 选择环境(可以使用任何 OpenAI gym环境,包括用户注册的环境)和使用 --run 选择算法(可用选项包括 SAC、PPO、PG、A2C、A3C 、IMPALA、ES、DDPG、DQN、MARWIL、APEX 和 APEX_DDPG)。

Evaluating Trained Policies(评估训练的政策)

为了保存用于评估策略的检查点,请在运行 rllib train 时设置 --checkpoint-freq(检查点之间的训练迭代次数)
评估先前训练的 DQN 策略的示例如下:

rllib rollout ~/ray_results/default/DQN_CartPole-v0_0upjmdgr0/checkpoint_1/checkpoint-1 --run DQN --env CartPole-v0 --steps 10000

rollout.py 帮助程序脚本从位于 ~/ray_results/default/DQN_CartPole-v0_0upjmdgr0/checkpoint_1/checkpoint-1 的检查点重建 DQN 策略,并在 --env 指定的环境中呈现其行为。(输入 rllib rollout --help 查看可用的评估选项。)

Configuration(配置)

  • Specifying Parameters(指定参数)
    除了一些常见的超参数之外,每个算法都有可以使用 --config 设置的特定超参数。有关更多信息,请参阅算法文档。 在下面的示例中,我们通过配置标志指定 8 个workers来训练 A2C。
rllib train --env=PongDeterministic-v4 --run=A2C --config '{"num_workers": 8}'
  • Specifying Resources(指定资源)
    您可以通过为大多数算法设置 num_workers 超参数来控制使用的并行度。 Trainer 将构造许多“remote worker”实例(参见 RolloutWorker 类),这些实例被构造为 ray.remote actor,再加上一个“本地 worker”,即 RolloutWorker 对象,它不是 ray actor,但直接存在于 Trainer 中。对于大多数算法,学习更新是在local worker上执行的,并且来自一个或多个环境的样本收集由remote worker(并行)执行。例如,设置 num_workers=0 只会创建local worker,在这种情况下,样本收集和训练都将由local worker完成。另一方面,设置 num_workers=5 将创建local worker(负责培训更新)和 5 个remote worker(负责样本收集)
    由于学习大部分时间是在local worker上完成的,因此通过 num_gpus 设置为该worker提供一个或多个 GPU 可能会有所帮助。同样,可以通过 num_cpus_per_worker、num_gpus_per_worker和custom_resources_per_worker 控制对远程工作人员的资源分配。
    GPU 的数量可以是分数(例如 0.5)以仅分配 GPU 的一小部分。 例如,使用 DQN,您可以通过设置 num_gpus: 0.2 将五个训练器打包到一个 GPU 上。 在这里查看这个分数 GPU 示例,它还演示了需要 GPU 的环境(在远程工作人员上运行)如何从 num_gpus_per_worker 设置中受益。
    对于 PPO 和 A2C 等同步算法,驱动程序和worker可以使用相同的 GPU。要对 n 个 GPUS 执行此操作:
gpu_count = n
num_gpus = 0.0001 # Driver GPU
num_gpus_per_worker = (gpu_count - num_gpus) / num_workers

在这里插入图片描述
(上图可以看出来,一个Trainer可以由n个worker来提供数据,而这每一个worker里面,由m个env可以交互,产生数据)
如果您指定 num_gpus 并且您的机器没有所需数量的可用 GPU,则相应的工作人员将抛出 RuntimeError。另一方面,如果您设置 num_gpus=0,您的策略将仅在 CPU 上构建,即使机器上有可用的 GPU。

Scaling Guide(扩展指导)

以下是使用 RLlib 扩展训练的一些经验法则

  • 如果环境很慢并且无法复制(例如,因为它需要与物理系统交互),那么您应该使用样本高效的离策略算法,例如 DQN 或 SAC。这些算法默认为 num_workers: 0 用于单进程操作。如果要使用 GPU,请确保设置 num_gpus: 1。还可以考虑使用离线数据 API 进行批量 RL 训练。
  • 如果环境很快并且模型很小(大多数 RL 模型都是),请使用省时算法,例如 PPO、IMPALA 或 APEX。这些可以通过增加 num_workers 来添加部署工作人员来扩展。启用向量化以进行推理也可能有意义。如果要使用 GPU,请确保设置 num_gpus: 1。如果学习器成为限制了训练速度,可以通过设置 num_gpus > 1 使用多个 GPU 进行学习
  • 如果模型是计算密集型的(例如,大型深度残差网络)并且推理限制了速度,请考虑通过设置 num_gpus_per_worker: 1 将 GPU 分配给工作人员。如果您只有一个 GPU,请考虑 num_workers: 0 将学习器 GPU 用于推理。为了有效利用 GPU 时间,请使用少量的 GPU worker 和每个worker配置尽可能多的环境
  • 最后,如果模型和环境都是计算密集型的,则通过设置 remote_worker_envs: True 和可选的 remote_env_batch_wait_ms 来启用具有异步批处理的远程工作人员环境。 这会在 rollout worker 中对 GPU 进行批量推理,同时让 env 在单独的参与者中异步运行,类似于 SEED 架构。 应调整工作人员的数量和每个工作人员的环境数量,以最大限度地提高 GPU 利用率。 如果您的环境需要 GPU 才能运行,或者如果需要多节点 SGD,那么还要考虑 DD-PPO

Common Parameters(常用参数)

以下是常用算法超参数列表:

COMMON_CONFIG: TrainerConfigDict = {
    # === Rollout Worker设置===
    # 要为并行采样创建的推出工作角色的数量。 将此设置为 0 将强制在 trainer actor 中进行部署。
    "num_workers": 2,
    # 每个工作人员按向量评估的环境数量。 这启用了模型推理批处理,这可以提高推理瓶颈工作负载的性能。
    "num_envs_per_worker": 1,
    # 当 `num_workers` > 0 时,驱动程序 (local_worker; worker-idx=0) 不需要环境。 
    # 这是因为它不必采样(由 remote_workers 完成;worker_indices > 0)也不必评估(由评估工作者完成;见下文)。
    "create_env_on_driver": False,# 在local worker上是否创建环境,当上述都为0是,这里需要创建
    # 在rollout期间,将episode 分成这么多step(就是该参数的大小)的fragments。 
    # 这种大小的sample batches是从rollout workers那里收集的,并组合成更大的批次“train_batch_size”用于学习。
    # 比如, 设置 rollout_fragment_length=100 和 train_batch_size=1000:
    #   1. RLlib 从 rollout workers 收集 10 个fragments,每个fragments 100 个step
    #   2. 这些fragments被连接起来,我们执行一个 SGD 优化(1 epoch)
    #
    # 当每个worker使用多个环境时,片段大小乘以`num_envs_per_worker`。 
    # 这是因为我们从多个环境并行收集步骤。 例如,如果 num_envs_per_worker=5,那么 rollout worker 将以 5*100 = 500 步的块返回经验。
    #
	# 这里的数据流可能因算法而异。 
	# 例如,PPO 进一步将 train batch 划分为 minibatch,用于多 epoch SGD。
    "rollout_fragment_length": 200,
    # 如何构建 per-Sampler (RolloutWorker) 批次,然后通常将其连接以形成训练批次(train batch)。 
    # 请注意,下面的“步骤”可能意味着不同的东西(环境或agent步骤),并且取决于下面的 `count_steps_by`(multi-agent)设置。
	# truncate_episodes: 每个生产的批次(当调用 RolloutWorker.sample() 时)将完全包含 rollout_fragment_length step。 
    # 这种模式保证批量大小均匀,但增加现在必须在截断边界处估计未来收益的方差。
    #  (因为每个worker只能产生rollout_fragment_length长度的经验,后续的经验是没有的,所以在估计未来收益时会产生误差)
    # complete_episodes:从头到尾,每次展开都发生在1个episode内。 除非情节终止或配置的边界条件(硬或软)终止,否则数据收集不会停止。
    "batch_mode": "truncate_episodes", # batch_mode 参数从上述的两种方式中提取

    # === 设置Trainer的流程 ===
    # 马尔可夫决策过程的衰减因子
    "gamma": 0.99,
    # 学习率.
    "lr": 0.0001,
    # 训练批量大小(如果适用), 应该 >= rollout_fragment_length。 样本批次将连接在一起成为此大小的批次,然后传递给 SGD。该部分是与上述的rollout_fragment_length有联系的参数
    "train_batch_size": 200,
    # 传递给策略模型的参数。 有关可用模型选项的完整列表,请参见 models/catalog.py。
    "model": MODEL_DEFAULTS,
    # 传递给策略优化器的参数。 这些因优化器而异。
    "optimizer": {},

    # === 环境设置 ===
	# episode 被迫终止的步数。 gym环境默认为 `env.spec.max_episode_steps`(如果存在).
    "horizon": None,
	# 计算奖励,但到达最大步数(horizon)时不要重置环境。 
	# 这允许价值估计和 RNN 状态跨越由horizon表示的逻辑情节。 这仅在 Horizon != inf 时有效.
    "soft_horizon": False,
    # Don't set 'done' at the end of the episode. 不要在episode结束时设置“done”。
    # In combination with `soft_horizon`, this works as follows:
    # 与 `soft_horizon` 结合使用,其工作原理如下:
    # - no_done_at_end=False soft_horizon=False:
    #   重置 env 并在每个episode 结尾添加 `done=True`。
    # - no_done_at_end=True soft_horizon=False:
    #   重置环境,但不要在episode末尾添加 `done=True`。
    # - no_done_at_end=False soft_horizon=True:
    #   不要在horizon上重置 env,而是在horizon结束之后上添加 `done=True`
    #   (假装这一episode已经结束).
    # - no_done_at_end=True soft_horizon=True:
    #   不要在horizon上重置 env 并且不要在horizon上添加 `done=True`.
    "no_done_at_end": False,
    # 环境说明符:
    # 这可以是通过 `tune.register_env([name], lambda env_ctx: [env object])` 注册的调优环境,也可以是 RLlib 支持类型的字符串说明符。 
    # 在后一种情况下,RLlib 将尝试将说明符解释为 openAI gym env、PyBullet env、ViZDoomGym env 或 Env 类的完全限定类路径,例如 “ray.rllib.examples.env.random_env.RandomEnv”。
    "env": None,
	# 该trainer的policy的观察和行动空间。 使用 None 将从给定的环境中自动推断这些。
    "observation_space": None,
    "action_space": None,
	# 参数 dict 作为 EnvContext 对象传递给 env 创建者
	# (它是一个 dict 加上属性:num_workers、worker_index、vector_index 和 remote)。
    "env_config": {},
    # 如果使用 num_envs_per_worker > 1,是否在远程进程而不是在同一个 worker 中创建这些新 env。 
    # 这会增加开销,但如果您的环境可能需要很多时间来步进/重置(例如,对于星际争霸),这可能是有意义的。 谨慎使用它; 开销很大。
    "remote_worker_envs": False,
	# remote_worker在轮询环境时等待的超时。 0(当至少一个环境准备好时继续)是一个合理的默认值,但可以通过测量您的环境步骤/重置和模型推理性能来获得最佳值。
    "remote_env_batch_wait_ms": 0,
    # 一个可调用的,将最后一次训练结果、基本环境和环境上下文作为参数并返回一个新任务以将环境设置为。
    # env 必须是一个 `TaskSettableEnv` 子类才能工作。 有关示例,请参阅 `examples/curriculum_learning.py`。
    "env_task_fn": None,
	# 如果为 True,尝试在本地工作人员或工作人员 1 上渲染环境(如果 num_workers > 0)。 
	# 对于矢量化环境,这通常意味着只会渲染第一个子环境。 
	# 为了让它工作,你的环境必须实现 `render()` 方法:a)处理窗口生成和渲染本身(返回 True)或 b)返回形状为 [height x width x 的 numpy uint8 图像 3 (RGB)]。
    "render_env": False,
	# 如果为 True,则将视频存储在默认输出目录 (~/ray_results/...) 内的此相对目录中。 
	# 或者,您可以指定一个绝对路径 (str),而应该在其中存储 env 记录。
	# 设置为 False 不记录任何内容。 注意:此设置替换了已弃用的 `monitor` 键.
    "record_env": False,
	# 是否在 Policy 的后处理过程中裁剪奖励。
    # 无(默认):仅适用于 Atari 的剪辑(r=sign(r))。
    # True: r=sign(r): 固定奖励 -1.0、1.0 或 0.0。
    # False:从不剪辑。
    # [float value]: 在 -value 和 + value 处剪辑。
    # Tuple[value1, value2]: 在 value1 和 value2 处剪辑。
    "clip_rewards": None,
	# 如果为真,RLlib 将完全在规范化的动作空间内学习
    #(0.0 为均值,以小的 stddev 为方差;仅影响 Box 组件)。
    # 在将动作发送回 env 之前,我们将取消压缩动作(和剪辑,以防万一)到 env 动作空间的边界。
    "normalize_actions": True,
	# 如果为 True,RLlib 将根据 env 的边界剪辑动作,然后再将它们发送回 env。 
	# TODO: (sven) 这个选项应该被废弃并且总是 False。
    "clip_actions": False,
	# 是否使用“rllib”或“deepmind”预处理器默认设置为无,不使用预处理器。 
	# 在这种情况下,模型将不得不处理来自环境的可能复杂的观察。
    "preprocessor_pref": "deepmind",

    # === Debug Settings ===
	# 为agent进程及其worker设置 ray.rllib.* 日志级别。 应该是 DEBUG、INFO、WARN 或 ERROR 之一。 DEBUG 级别还将定期打印出相关内部数据流的摘要(这也将在 INFO 级别启动时打印一次)。 
	# 使用 `rllib train` 命令时,您还可以使用 `-v` 和 `-vv` 标志作为 INFO 和 DEBUG 的简写。
    "log_level": "WARN",
	# 将在训练的各个阶段运行的回调。 有关更多使用信息,请参阅 `DefaultCallbacks` 类和 `examples/custom_metrics_and_callbacks.py`。
    "callbacks": DefaultCallbacks,
	# 如果worker崩溃,是否尝试继续训练。 
	# 当前健康worker的数量报告为“num_healthy_workers”指标。
    "ignore_worker_failures": False,
	# 将系统资源指标记录到结果中。 这需要为系统统计安装“psutil”,为 GPU 指标安装“gputil”。
    "log_sys_usage": True,
    # 使用假(无限速)采样器。 仅用于测试。
    "fake_sampler": False,

    # === 深度学习框架设置 ===
    # tf: TensorFlow (static-graph)
    # tf2: TensorFlow 2.x (eager or traced, if eager_tracing=True)
    # tfe: TensorFlow eager (or traced, if eager_tracing=True)
    # torch: PyTorch
    "framework": "tf",
	# 在eager模式下启用跟踪。 这极大地提高了性能(加速约 2 倍),但使调试变得稍微困难,因为 Python 代码在初始化通过后不会被评估。 
	# 只有当 framework=[tf2|tfe] 时才可以被设置。
    "eager_tracing": False,
	# 引发运行时错误之前的最大 tf.function 重新跟踪次数。 这是为了防止 `..._eager_traced` 策略中的方法被不注意的回溯,这可能会使执行速度减慢 4 倍,而用户没有注意到这种减慢的根本原因可能是什么。
	# 仅对 framework=[tf2|tfe] 是必需的。 设置为 None 以忽略重新跟踪计数并且从不抛出错误。
    "eager_max_retraces": 20,

    # === 探索设置 ===
	# 默认探索行为,如果 `explore`=None 被传递到 compute_action(s)。
	# 设置为 False 表示没有探索行为(例如,用于评估)。
    "explore": True,
    # 提供一个 dict 指定 Exploration 对象的配置。
    "exploration_config": {
		# 要使用的探索类。 在最简单的情况下,这是 `rllib.utils.exploration` 包中存在的任何类的名称 (str)。
        # 你也可以直接提供 python 类或你的类的完整位置(例如“ray.rllib.utils.exploration.epsilon_greedy.EpsilonGreedy”)。
        "type": "StochasticSampling",
        # 在此处添加构造函数 kwargs(如果有).
    },
    # === 评估设置 ===
	# 使用每个 `evaluation_interval` 训练迭代进行评估。 评估统计数据将在“评估”指标键下报告。
    # 请注意,对于 Ape-X 指标,仅报告了最低 epsilon 工作人员(最少随机工作人员)。 
    # 设置为无(或 0)不进行评估。
    "evaluation_interval": None,
	# 每个`evaluation_interval`运行评估的持续时间。
    # 持续时间的单位可以通过 `evaluation_duration_unit` 设置为“episodes”(默认)或“timesteps”。
    # 如果使用多个评估工作人员(evaluation_num_workers > 1),运行的负载将在这些工作人员之间分配。
    # 如果值为“auto”: - For `evaluation_parallel_to_training=True`:将运行适合(并行)训练步骤的尽可能多的情节/时间步长。
    # - 对于`evaluation_parallel_to_training=False`:错误。
    "evaluation_duration": 10,
	# 计算评估持续时间的单位。 “episodes”(默认)或“timesteps”。
    "evaluation_duration_unit": "episodes",
	# 是否使用线程与 Trainer.train() 调用并行运行评估。 默认=False。
    # 例如 evaluation_interval=2 -> 对于所有其他训练迭代,Trainer.train() 和 Trainer.evaluate() 调用并行运行。
    # 注意:这是实验性的。 可能的陷阱可能是在评估循环开始时权重同步的竞争条件。
    "evaluation_parallel_to_training": False,
    # 为评估工作人员设置为 True 的内部标志。
    "in_evaluation": False,
	# 典型用法是将额外的参数传递给评估环境创建者,并通过计算确定性操作来禁用探索。
    # 重要提示:策略梯度算法能够找到最优策略,即使这是一个随机策略。 在此处设置“explore=False”将导致评估工作人员不使用此最佳策略!
    "evaluation_config": {
		# 示例:覆盖 env_config、exploration 等:
         # "env_config": {...},
         #"explore": False
    },
	# 用于评估的并行工作者数量。 请注意,默认情况下将其设置为零,这意味着评估将在训练器进程中运行(仅当评估间隔不为无时)。
	# 如果你增加它,它将增加训练器的 Ray 资源使用量,因为评估工作人员是与推出工作人员分开创建的(用于对训练数据进行采样)。
    "evaluation_num_workers": 0,
	# 自定义评估方法。 这必须是签名的函数(trainer: Trainer, eval_workers: WorkerSet)-> metrics: dict. 请参阅 Trainer.evaluate() 方法以查看默认实现。
    # Trainer 保证所有 eval 工作人员在调用此函数之前都具有最新的策略状态。
    "custom_eval_function": None,
	# 确保最新的可用评估结果始终附加到步骤结果字典。
    # 如果 Tune 或其他一些元控制器需要一直访问评估指标,这可能很有用。
    "always_attach_evaluation_results": False,
    # 存储原始自定义指标而不计算最大值、最小值、平均值
    "keep_per_episode_custom_metrics": False,

    # === 高级rollout设置 ===
	# 使用后台线程进行采样(稍微偏离政策,通常不建议打开,除非您的环境特别需要它)。
    "sample_async": False,

	# 用于收集和检索环境、模型和采样器数据的 SampleCollector 类。
	# 覆盖 SampleCollector 基类以实现您自己的收集/缓冲/检索逻辑。
    "sample_collector": SimpleListCollector,

    # 逐元素观察过滤器,“NoFilter”或“MeanStdFilter”。
    "observation_filter": "NoFilter",
    # 是否同步远程过滤器的统计信息。
    "synchronize_filters": True,
    # 默认情况下将 TF 配置为单进程操作。
    "tf_session_args": {
        # 注意:被 `local_tf_session_args` 覆盖
        "intra_op_parallelism_threads": 2,
        "inter_op_parallelism_threads": 2,
        "gpu_options": {
            "allow_growth": True,
        },
        "log_device_placement": False,
        "device_count": {
            "CPU": 1
        },
        # 多 GPU 需要 (num_gpus > 1)。
        "allow_soft_placement": True,
    },
    # 在local worker 上覆盖以下 tf 会话参数
    "local_tf_session_args": {
		# 默认情况下允许更高级别的并行性,但不是无限制的,因为这可能会导致许多并发驱动程序崩溃。
        "intra_op_parallelism_threads": 8,
        "inter_op_parallelism_threads": 8,
    },
    # 是否要 LZ4 压缩单个观测值。
    "compress_observations": False,
	# 最多等待度量批次这么多秒。 那些没有及时返回的将在下一次训练迭代中收集。
    "metrics_episode_collection_timeout_s": 180,
    # 这么多episodes的平滑指标.
    "metrics_num_episodes_for_smoothing": 100,
	# 运行一次 `train()` 调用的最小时间间隔:
    # 如果 - 在一个 `step_attempt()` 之后,还没有达到这个时间限制,将执行 n 次更多的 `step_attempt()` 调用,直到这个最小时间被消耗完。 设置为 None 或 0 表示没有最短时间。
    "min_time_s_per_reporting": None,
# 为每个 `train()` 调用优化的最小训练/样本时间步长。
    # 这个值不影响学习,只影响训练迭代的长度。
    # 如果 - 在一个 `step_attempt()` 之后,时间步数(采样或训练)尚未达到,将再执行 n 次 `step_attempt()` 调用,直到执行了最小时间步。
    # 设置为 None 或 0 表示没有最小时间步长。
    "min_train_timesteps_per_reporting": None,
    "min_sample_timesteps_per_reporting": None,
	# 此参数与worker_index 一起设置每个worker 的随机种子,因此配置相同的试验将具有相同的结果。 
	# 这使得实验具有可重复性。
    "seed": None,
    # 要在trainer进程中设置的任何额外的 python 环境变量,例如,
    # {"OMP_NUM_THREADS": "16"}
    "extra_python_environs_for_driver": {},
    # 需要为工作进程设置额外的 python 环境。
    "extra_python_environs_for_worker": {},

    # === 资源设置 ===
	# 分配给训练器进程的 GPU 数量。 请注意,并非所有算法都可以利用 GPU。 对多 GPU 的支持目前仅适用于 tf-[PPO/IMPALA/DQN/PG]。
     # 这可以是分数(例如,0.3 个 GPU)。
    "num_gpus": 0,
	# 设置为 True 以调试(多)CPU 机器上的 GPU 功能。
    # 在这种情况下,GPU 将由位于 CPU 上的图形模拟。
    # 使用 `num_gpus` 来测试不同数量的假 GPU。
    "_fake_gpus": False,
    # 每个工作人员分配的 CPU 数量。
    "num_cpus_per_worker": 1,
	# 每个工作人员分配的 GPU 数量。 这可以是分数。 这通常仅在您的环境本身需要 GPU(即,它是 GPU 密集型视频游戏)或模型推理异常昂贵时才需要。
    "num_gpus_per_worker": 0,
    # Any custom Ray resources to allocate per worker.
    "custom_resources_per_worker": {},
	# 分配给训练器的 CPU 数量。 注意:这仅在 Tune 中运行时生效。 否则,训练器在主程序中运行。
    "num_cpus_for_driver": 1,
	# 返回的归置组工厂策略
    # `Trainer.default_resource_request()`。 PlacementGroup 定义了哪些设备(资源)应始终位于同一节点上。
    # 例如,一个有 2 个 rollout worker 的 Trainer,以 num_gpus=1 运行,将请求一个带有 bundles 的归置组:[{"gpu": 1, "cpu": 1}, {"cpu": 1}, {" cpu": 1}],其中第一个包用于驱动程序,其他 2 个包用于两个工作人员。 现在可以根据 `placement_strategy` 的值将这些捆绑包“放置”在相同或不同的节点上:
    # "PACK": 将包打包到尽可能少的节点中。
    # “SPREAD”:尽可能均匀地将包放置在不同的节点上。
    # “STRICT_PACK”:将捆绑包打包到一个节点中。 不允许组 跨越多个节点。
    # “STRICT_SPREAD”:跨不同节点打包包。
    "placement_strategy": "PACK",

    # TODO(jungong, sven): we can potentially unify all input types
    #     under input and input_config keys. E.g.
    #     input: sample
    #     input_config {
    #         env: Cartpole-v0
    #     }
    #     or:
    #     input: json_reader
    #     input_config {
    #         path: /tmp/
    #     }
    #     or:
    #     input: dataset
    #     input_config {
    #         format: parquet
    #         path: /tmp/
    #     }
    # === 离线数据集 ===
    # 指定如何产生经验:
    #  - "sampler": 通过在线 (env) 模拟(默认)生成体验。
    # - 本地目录或文件 glob 表达式(例如,“/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": "sampler",
    # 可从 IOContext 访问的参数,用于配置自定义输入
    "input_config": {},
	# True,如果给定离线“输入”中的动作已经标准化(介于 -1.0 和 1.0 之间)。 当离线文件由另一个 RLlib 算法(例如 PPO 或 SAC)生成时,通常会出现这种情况,而“normalize_actions”设置为 True。
    "actions_in_input_normalized": False,
	# 指定如何评估当前策略。 这仅在加载离线经验时有效(“input”不是“sampler”)。
    # 可用选项:
    #  - "wis": 加权逐步重要性抽样估计器。
    #  - "is":逐步重要性抽样估计器。
    #  - "simulation": 在后台运行环境,但将此数据仅用于评估而不用于学习。
    "input_evaluation": ["is", "wis"],
	# 是否对来自离线输入的轨迹片段运行 postprocess_trajectory()。 
	# 请注意,后处理将使用 *current* 策略完成,而不是 *behavior* 策略,这通常不适合 on-policy 算法。
    "postprocess_inputs": False,
	# 如果为正数,输入批次将通过此批次数量的滑动窗口进行打乱。 如果输入数据的顺序不够随机,请使用此选项。 输入被延迟,直到 shuffle 缓冲区被填满。
    "shuffle_buffer_size": 0,
	# 指定应保存经验的位置:
    # - 无:不保存任何经验
    # - "logdir" 保存到代理日志目录
    # - 保存到自定义输出目录的路径/URI(例如,“s3://bucket/”)
    # - 一个返回 rllib.offline.OutputWriter 的函数
    "output": None,
    # 可从 IOContext 访问的参数,用于配置自定义输出
    "output_config": {},
    # LZ4 在输出数据中压缩了哪些样本批处理列。
    "output_compress_columns": ["obs", "new_obs"],
    # 到新文件之前的最大输出文件大小(以字节为单位)。
    "output_max_file_size": 64 * 1024 * 1024,

    # === 多agnet环境的设置 ===
    "multiagent": {
		# MultiAgentPolicyConfigDict 类型的映射,从策略 id 到 (policy_cls, obs_space, act_space, config) 的元组。 这定义了策略和任何额外配置的观察和操作空间。
        "policies": {},
		# 在“policy_map”中保留这么多策略(在将最近最少使用的策略写入磁盘/S3 之前)。
        "policy_map_capacity": 100,
		# 在哪里存储溢出(最近最少使用)的策略? 可以是目录 (str) 或 S3 位置。 None 用于使用默认输出目录。
        "policy_map_cache": None,
        # 将agent ID 映射到policy ID。
        "policy_mapping_fn": None,
        # 确定应更新的策略。
        # Options are:
        # - None, for all policies.
        # - 应该更新的 Policy ID 
        # - 一个可调用的,采用 Policy ID 的 SampleBatch 或 MultiAgentBatch
		# 并返回一个布尔值(指示给定策略是否可训练,给定特定批次)。
		# 这使您可以仅对某些数据进行训练(例如,在与某个对手比赛时)。
        "policies_to_train": None,
		# 可用于增强本地代理观察以包含更多状态的可选功能。 有关更多信息,请参见rllib/evaluation/observation_function.py。
        "observation_fn": None,
		# 当 replay_mode=lockstep 时,RLlib 将在一个特定的时间步长的所有代理转换一起重播。 这允许策略在该时间步长控制的代理之间实现可区分的共享计算。 
		# 当 replay_mode=independent 时,每个策略独立地重放转换。
        "replay_mode": "independent",
		# 在构建 MultiAgentBatch 时使用哪个度量作为“批量大小”。 支持的两个值是:
        # env_steps:每次 env “步进”时计数(无论传递了多少多智能体操作/在上一步中返回了多少多智能体观察值)。
        # agent_steps:将每个单独的代理步骤计为一个步骤。
        "count_steps_by": "env_steps",
    },

    # === Logger ===
	# 定义要在 Logger 中使用的特定于 logger 的配置
    # 默认值 None 允许用嵌套的 dicts 覆盖
    "logger_config": None,

    # === API 弃用/简化/更改 ===
    # 实验标志.
	# 如果为真,TFPolicy 将处理多个损失/优化器。
    # 如果你想从 `loss_fn` 中返回多个损失项,并从 `optimizer_fn` 中返回相同数量的优化器,请将此设置为 True。
    # 将来,默认值为 True。
    "_tf_policy_handles_more_than_one_loss": False,
	# 实验标志。
    # 如果为真,则不会创建(观察)预处理器,并且观察将在环境返回时到达模型中。
    # 将来,默认值为 True。
    "_disable_preprocessor_api": False,
    # Experimental flag.
	# 如果为 True,RLlib 将不再将策略计算的动作扁平化为单个张量(用于存储在 SampleCollectors/输出文件/等中),而是保持(可能是嵌套的)动作原样。 禁用展平会影响:
    # - SampleCollectors:必须存储可能嵌套的动作结构。
    # - 将先前操作作为其输入的一部分的模型。
    # - 从离线文件中读取的算法(包括动作信息)。
    "_disable_action_flattening": False,
    # Experimental flag.
	# 如果为True,则不使用执行计划API。 相反,每次训练迭代都会按原样调用 Trainer 的 `training_iteration` 方法。
    "_disable_execution_plan_api": False,

    # 如果为 True,则禁用环境预检查模块.
    "disable_env_checking": False,

    # === 已弃用的keys ===
	# 使用同步样本优化器而不是多 GPU 优化器。 这通常较慢,但如果您遇到默认优化器的问题,您可能想尝试一下。 这将从现在开始自动设置。
    "simple_optimizer": DEPRECATED_VALUE,
	# 是否将剧集统计信息和视频写入代理日志目录。 这通常位于 ~/ray_results 中。
    "monitor": DEPRECATED_VALUE,
	# 替换为 `evaluation_duration=10` 和`evaluation_duration_unit=episodes`。
    "evaluation_num_episodes": DEPRECATED_VALUE,
    # 请改用“metrics_num_episodes_for_smoothing”。
    "metrics_smoothing_episodes": DEPRECATED_VALUE,
    # Use `min_[env|train]_timesteps_per_reporting` instead.
    "timesteps_per_iteration": 0,
    # Use `min_time_s_per_reporting` instead.
    "min_iter_time_s": DEPRECATED_VALUE,
    # Use `metrics_episode_collection_timeout_s` instead.
    "collect_metrics_timeout": DEPRECATED_VALUE,
}

Tuned Examples(调整示例)

存储库中提供了一些好的超参数和设置(其中一些经过调整以在 GPU 上运行)。如果您在不同的域中找到更好的设置或调整算法,请考虑提交拉取请求!

rllib train -f /path/to/tuned/example.yaml

Basic Python API

Python API 提供了将 RLlib 应用于新问题所需的灵活性。如果您希望使用自定义环境、预处理器或带有 RLlib 的模型,则需要使用此 API。
下面是一个基本用法示例(更完整的示例,请参见 custom_env.py)

import ray
import ray.rllib.agents.ppo as ppo
from ray.tune.logger import pretty_print

ray.init()
# 加载ppo的默认参数
config = ppo.DEFAULT_CONFIG.copy()
# 设置gpu数目,以及worker的数目
config["num_gpus"] = 0
config["num_workers"] = 1
# 设置ppo的训练器,环境为CartPole-v0
trainer = ppo.PPOTrainer(config=config, env="CartPole-v0")

# 可以选择调用 trainer.restore(path) 来加载检查点。

for i in range(1000):
   # 使用 PPO 执行一次迭代训练策略
   result = trainer.train()
   print(pretty_print(result))

   if i % 100 == 0:
       checkpoint = trainer.save()
       print("checkpoint saved at", checkpoint)

# 此外,如果您在 ray/RLlib 之外训练了一个模型并创建了一个包含权重值的 h5 文件,例如
# my_keras_model_trained_outside_rllib.save_weights("model.h5")
# (see: https://keras.io/models/about-keras-models/)

# ... 您可以通过执行以下操作将 h5-weights 加载到 Trainer's Policy 的 ModelV2(tf 或 torch)中:
trainer.import_model("my_weights.h5")
# NOTE: 为了使其工作,您的(自定义)模型需要实现 `import_from_h5` 方法。
# See https://github.com/ray-project/ray/blob/master/rllib/tests/test_model_imports.py
# for detailed examples for tf- and torch trainers/models.

建议您使用 Tune 运行 RLlib 训练器,以便于实验管理和结果可视化。 只需在实验配置中设置 “run”: ALG_NAME, “env”: ENV_NAME。
所有 RLlib 训练器都与 Tune API 兼容。 这使它们能够轻松地用于 Tune 实验。 例如,以下代码执行 PPO 的简单超参数扫描:

import ray
from ray import tune

ray.init()
tune.run(
    "PPO",
    stop={"episode_reward_mean": 200},
    config={
        "env": "CartPole-v0",
        "num_gpus": 0,
        "num_workers": 1,
        "lr": tune.grid_search([0.01, 0.001, 0.0001]),
    },
)

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-v0_2_lr=0.0001:     PENDING
RUNNING trials:
 - PPO_CartPole-v0_0_lr=0.01:       RUNNING [pid=21940], 16 s, 4013 ts, 22 rew
 - PPO_CartPole-v0_1_lr=0.001:      RUNNING [pid=21942], 27 s, 8111 ts, 54.7 rew

tune.run() 返回一个 ExperimentAnalysis 对象,允许进一步分析训练结果并检索受训代理的检查点。 它还简化了保存训练后的的代理。 例如

# tune.run() allows setting a custom log directory (other than ``~/ray-results``)
# and automatically saving the trained agent
analysis = ray.tune.run(
    ppo.PPOTrainer,
    config=config,
    local_dir=log_dir,
    stop=stop_criteria,
    checkpoint_at_end=True)

# 列表列表:每个检查点一个列表; 每个检查点列表包含第一个路径,第二个度量值
checkpoints = analysis.get_trial_checkpoints_paths(
    trial=analysis.get_best_trial("episode_reward_mean"),
    metric="episode_reward_mean")

# 或者简单地获取最后一个检查点(具有最高的“training_iteration”)
last_checkpoint = analysis.get_last_checkpoint()
# 如果有多个试验,选择特定试验或根据给定指标自动选择最佳试验
last_checkpoint = analysis.get_last_checkpoint(
    metric="episode_reward_mean", mode="max"
)

从检查点加载和恢复训练好的的agent很简单:

agent = ppo.PPOTrainer(config=config, env=env_class)
agent.restore(checkpoint_path)

Computing Actions(计算动作)

从受过训练的代理以编程方式计算动作的最简单方法是使用 trainer.compute_action()。 此方法在将观察传递给代理策略之前对其进行预处理和过滤。 下面是一个简单的例子,测试一个trained的agent一个episode:
(需要先定义agent)

agent = ppo.PPOTrainer(config=config, env=env_class)
agent.restore(checkpoint_path)
# instantiate env class
env = env_class(env_config)

# run until episode ends
episode_reward = 0
done = False
obs = env.reset()
while not done:
    action = agent.compute_action(obs)
    obs, reward, done, info = env.step(action)
    episode_reward += reward

对于更高级的用法,您可以像 compute_action() 那样直接访问训练器持有的worker和policy:

class Trainer(Trainable):

  @PublicAPI
  def compute_action(self,
                     observation,
                     state=None,
                     prev_action=None,
                     prev_reward=None,
                     info=None,
                     policy_id=DEFAULT_POLICY_ID,
                     full_fetch=False):
      """Computes an action for the specified policy.

      Note that you can also access the policy object through
      self.get_policy(policy_id) and call compute_actions() on it directly.

      Arguments:
          observation (obj): observation from the environment.
          state (list): RNN hidden state, if any. If state is not None,
                        then all of compute_single_action(...) is returned
                        (computed action, rnn state, logits dictionary).
                        Otherwise compute_single_action(...)[0] is
                        returned (computed action).
          prev_action (obj): previous action value, if any
          prev_reward (int): previous reward, if any
          info (dict): info object, if any
          policy_id (str): policy to query (only applies to multi-agent).
          full_fetch (bool): whether to return extra action fetch results.
              This is always set to true if RNN state is specified.

      Returns:
          Just the computed action if full_fetch=False, or the full output
          of policy.compute_actions() otherwise.
      """

      if state is None:
          state = []
      preprocessed = self.workers.local_worker().preprocessors[
          policy_id].transform(observation)
      filtered_obs = self.workers.local_worker().filters[policy_id](
          preprocessed, update=False)
      if state:
          return self.get_policy(policy_id).compute_single_action(
              filtered_obs,
              state,
              prev_action,
              prev_reward,
              info,
              clip_actions=self.config["clip_actions"])
      res = self.get_policy(policy_id).compute_single_action(
          filtered_obs,
          state,
          prev_action,
          prev_reward,
          info,
          clip_actions=self.config["clip_actions"])
      if full_fetch:
          return res
      else:
          return res[0]  # backwards compatibility

Accessing Policy State(访问策略状态)

通常需要访问训练器的内部状态,例如,设置或获取内部权重。 在 RLlib 中,训练器状态在集群中的多个部署工作人员(Ray 演员)之间复制。 但是,您可以通过 trainer.workers.foreach_worker() 或 trainer.workers.foreach_worker_with_index() 在调用 train() 之间轻松获取和更新此状态。 这些函数采用一个 lambda 函数,该函数作为 arg 与 worker 一起应用。 您还可以从这些函数返回值,这些值将作为列表返回。
您还可以通过 trainer.get_policy() 或 trainer.workers.local_worker() 仅访问训练器状态的“主”副本,但请注意,如果您已配置 num_workers > 0,此处的更新可能不会立即反映在远程副本中。 例如,要访问本地 TF 策略的权重,您可以运行 trainer.get_policy().get_weights()。 这也等价于 trainer.workers.local_worker().policy_map[“default_policy”].get_weights():
(获取训练参数)

# Get weights of the default local policy
trainer.get_policy().get_weights()

# Same as above
trainer.workers.local_worker().policy_map["default_policy"].get_weights()

# Get list of weights of each worker, including remote replicas
trainer.workers.foreach_worker(lambda ev: ev.get_policy().get_weights())

# Same as above
trainer.workers.foreach_worker_with_index(lambda ev, i: ev.get_policy().get_weights())

Accessing Model State(访问模型状态)

与访问策略状态类似,您可能希望获得对正在训练的底层神经网络模型的引用。 例如,您可能希望单独对其进行预训练,或者在 RLlib 之外更新其权重。 这可以通过访问策略模型来完成:
示例:预处理观察以输入模型
首先,安装依赖项:

# The "Pong-v0" Atari environment requires a few additional gym installs:
pip install "ray[rllib]" tensorflow torch "gym[atari]" "gym[accept-rom-license]" atari_py

然后对于代码:

>>> import gym
>>> env = gym.make("Pong-v0")

# 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
>>> env.reset().shape
(210, 160, 3)
>>> prep.transform(env.reset()).shape
(84, 84, 3)

示例:查询策略的动作分布

# Get a reference to the policy
>>> from ray.rllib.agents.ppo import PPOTrainer
>>> trainer = PPOTrainer(env="CartPole-v0", config={"framework": "tf2", "num_workers": 0})
>>> policy = trainer.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.from_batch({"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
>>> from ray.rllib.agents.dqn import DQNTrainer
>>> trainer = DQNTrainer(env="CartPole-v0", config={"framework": "tf2"})
>>> model = trainer.get_policy().model
<ray.rllib.models.catalog.FullyConnectedNetwork_as_DistributionalQModel ...>

# List of all model variables
>>> model.variables()
[<tf.Variable 'default_policy/fc_1/kernel:0' shape=(4, 256) dtype=float32>, ...]

# Run a forward pass to get base model output. Note that complex observations
# must be preprocessed. An example of preprocessing is examples/saving_experiences.py
>>> model_out = model.from_batch({"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)
>>> model.get_q_value_distributions(model_out)
[<tf.Tensor: id=891, shape=(1, 2)>, <tf.Tensor: id=896, shape=(1, 2, 1)>]

>>> model.q_value_head.summary()
Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
model_out (InputLayer)       [(None, 256)]             0
_________________________________________________________________
lambda (Lambda)              [(None, 2), (None, 2, 1), 66306
=================================================================
Total params: 66,306
Trainable params: 66,306
Non-trainable params: 0
_________________________________________________________________

# Access the state value model (specific to DQN)
>>> model.get_state_value(model_out)
<tf.Tensor: id=913, shape=(1, 1), dtype=float32>

>>> model.state_value_head.summary()
Model: "model_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
model_out (InputLayer)       [(None, 256)]             0
_________________________________________________________________
lambda_1 (Lambda)            (None, 1)                 66049
=================================================================
Total params: 66,049
Trainable params: 66,049
Non-trainable params: 0
_________________________________________________________________

这在与自定义模型类一起使用时特别有用。

Advanced Python APIs(高级Python API)

这里都是自定义训练内容。包括自定义回调函数(在每个过程结束之后),自定义指标检测,有需要可以从
高级python API进行自行学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值