环境#
注意
Ray 2.40 默认使用 RLlib 的新 API 栈。Ray 团队已基本完成算法、示例脚本和文档向新代码库的迁移。
如果你仍在使用旧 API 栈,请参阅新 API 栈迁移指南了解如何迁移的详细信息。
在在线强化学习(RL)中,算法通过使用 RL 环境或模拟器实时收集数据来训练策略神经网络。智能体在环境中导航,根据该策略选择行动,并收集环境的观测和奖励。算法的目标是根据收集的数据训练策略,以便策略的行动选择最终能够最大化智能体生命周期内的累积奖励。
单智能体设置:一个智能体生活在环境中,并执行由单个策略计算的行动。智能体到策略的映射是固定的(“default_agent” 映射到 “default_policy”)。有关此设置在多智能体情况下的泛化方式,请参阅多智能体环境。#
Farama Gymnasium#
RLlib 依赖 Farama 的 Gymnasium API 作为其主要的 RL 环境接口,用于进行单智能体训练(多智能体请参见此处)。要使用 gymnasium
实现自定义逻辑并将其集成到 RLlib 配置中,请参阅此SimpleCorridor 示例。
提示
并非所有动作空间都与所有 RLlib 算法兼容。有关详细信息,请参阅算法概述。特别是,要注意哪些算法支持离散动作空间,哪些支持连续动作空间,或者两者都支持。
有关构建自定义 Farama Gymnasium 环境的更多详细信息,请参阅 gymnasium.Env 类定义。
对于多智能体训练,请参阅RLlib 的多智能体 API 和支持的第三方 API。
配置环境#
要指定用于训练的 RL 环境,可以提供字符串名称或必须继承自 gymnasium.Env 的 Python 类。
通过字符串指定#
默认情况下,RLlib 将字符串值解释为已注册的 gymnasium 环境名称。
例如
config = (
PPOConfig()
# Configure the RL environment to use as a string (by name), which
# is registered with Farama's gymnasium.
.environment("Acrobot-v1")
)
algo = config.build()
print(algo.train())
通过 gymnasium.Env 的子类指定#
如果你正在使用自定义的 gymnasium.Env 类子类,可以直接传递该类而不是注册的字符串。你的子类必须在其构造函数中接受一个 config
参数(可以默认为 None
)。
例如
import gymnasium as gym
import numpy as np
from ray.rllib.algorithms.ppo import PPOConfig
class MyDummyEnv(gym.Env):
# Write the constructor and provide a single `config` arg,
# which may be set to None by default.
def __init__(self, config=None):
# As per gymnasium standard, provide observation and action spaces in your
# constructor.
self.observation_space = gym.spaces.Box(-1.0, 1.0, (1,), np.float32)
self.action_space = gym.spaces.Discrete(2)
def reset(self, seed=None, options=None):
# Return (reset) observation and info dict.
return np.array([1.0]), {}
def step(self, action):
# Return next observation, reward, terminated, truncated, and info dict.
return np.array([1.0]), 1.0, False, False, {}
config = (
PPOConfig()
.environment(
MyDummyEnv,
env_config={}, # `config` to pass to your env class
)
)
algo = config.build()
print(algo.train())
通过 Tune 注册的 Lambda 指定#
向配置提供环境信息的第三种选项是使用 Ray Tune 注册一个环境创建函数(或 lambda)。该创建函数必须接受一个 config
参数,并返回一个非向量化的 gymnasium.Env 实例。
例如
from ray.tune.registry import register_env
def env_creator(config):
return MyDummyEnv(config) # Return a gymnasium.Env instance.
register_env("my_env", env_creator)
config = (
PPOConfig()
.environment("my_env") # <- Tune registered string pointing to your custom env creator.
)
algo = config.build()
print(algo.train())
有关使用自定义环境的完整示例,请参阅 custom_gym_env.py 示例脚本。
警告
由于 Ray 的分布式特性,gymnasium 自身的注册表与 Ray 不兼容。请始终使用此处介绍的注册方法,以确保远程 Ray actor 可以访问你的自定义环境。
在前面的示例中,env_creator
函数接受一个 config
参数。此配置主要是一个包含所需设置的字典。然而,你也可以在 config
变量中访问其他属性。例如,使用 config.worker_index
获取远程 EnvRunner 索引,或使用 config.num_workers
获取使用的 EnvRunner 总数。这种方法有助于自定义集成中的环境,并使在某些 EnvRunner 上运行的环境与在其他 EnvRunner 上运行的环境表现不同。
例如
class EnvDependingOnWorkerAndVectorIndex(gym.Env):
def __init__(self, config):
# Pick actual env based on worker and env indexes.
self.env = gym.make(
choose_env_for(config.worker_index, config.vector_index)
)
self.action_space = self.env.action_space
self.observation_space = self.env.observation_space
def reset(self, seed, options):
return self.env.reset(seed, options)
def step(self, action):
return self.env.step(action)
register_env("multi_env", lambda config: MultiEnv(config))
提示
在环境内部使用日志记录时,必须在环境内部(在 Ray worker 中运行)完成配置。Ray 之前的日志记录配置将被忽略。使用以下代码连接到 Ray 的日志记录实例
import logging
logger = logging.getLogger("ray.rllib")
性能和扩缩容#
EnvRunner 与 gym.Env 设置:RLlib 中的环境位于 EnvRunner
actor 内,您可以通过 config.env_runners(num_env_runners=..)
设置来扩展其数量 (n
)。每个 EnvRunner
actor 可以容纳多个 gymnasium 环境(向量化)。您可以通过 config.env_runners(num_envs_per_env_runner=..)
设置每个 EnvRunner 中的单个环境副本数量。此外,您可以通过 gymnasium 使用的 Python 多进程将向量中的单个子环境设为独立进程。设置 config.env_runners(remote_worker_envs=True)
可以将单个子环境创建为单独的进程并并行进行步进。#
使用 RLlib 和 gymnasium 环境扩展样本收集有两种方法。你可以结合使用这两种方法。
跨多个进程分发: RLlib 创建多个
EnvRunner
实例(每个实例都是一个 Ray actor),用于收集经验,通过你的AlgorithmConfig
进行控制:config.env_runners(num_env_runners=..)
。
单进程内的向量化:许多环境可以达到较高的每核帧率,但受限于策略推理延迟。为了解决这一限制,可以在每个进程中创建多个环境,以在这向量化环境上批量进行策略前向传播。设置
config.env_runners(num_envs_per_env_runner=..)
可以为每个EnvRunner
actor 创建多个环境副本。此外,您可以通过 gymnasium 使用的 Python 多进程将向量中的单个子环境设为独立进程。设置config.env_runners(remote_worker_envs=True)
可以将单个子环境创建为单独的进程并并行进行步进。
注意
多智能体设置目前还不能向量化。Ray 团队正在利用 gymnasium >= 1.x
的自定义向量化功能来解决这一限制。
提示
有关大规模 RLlib 训练的更多信息,请参阅扩缩容指南。
昂贵的环境#
某些环境初始化和运行可能需要大量资源。如果你的环境每个 EnvRunner
需要超过 1 个 CPU,可以通过设置以下配置选项为每个 actor 提供更多资源:config.env_runners(num_cpus_per_env_runner=.., num_gpus_per_env_runner=..)