环境#
在线强化学习 (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 actors 可以访问您的自定义环境。
在前面的示例中,env_creator 函数接受一个 config 参数。此配置主要是一个包含必需设置的字典。但是,您也可以在 config 变量中访问其他属性。例如,使用 config.worker_index 来获取远程 EnvRunner 的索引,或使用 config.num_workers 来获取 EnvRunner 的总数。此方法有助于自定义 ensemble 中的环境,并使某些 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 workers 中运行)。Ray 之前的日志配置将被忽略。使用以下代码连接到 Ray 的日志实例
import logging
logger = logging.getLogger("ray.rllib")
性能和扩展#
EnvRunner 和 gym.Env 设置:RLlib 中的环境位于 EnvRunner actors 中,其数量 (n) 可以通过 config.env_runners(num_env_runners=..) 设置进行扩展。每个 EnvRunner actor 可以包含多个 gymnasium 环境(矢量化)。您可以设置每个 EnvRunner 的单个环境副本数量,通过 config.env_runners(num_envs_per_env_runner=..) 进行设置。#
有两种方法可以扩展 RLlib 和 gymnasium 环境的样本收集。您可以将两者结合使用。
跨多个进程分发:RLlib 创建多个
EnvRunner实例,每个实例都是一个 Ray actor,用于收集经验,这可以通过您的AlgorithmConfig进行控制:config.env_runners(num_env_runners=..)。单个进程内的矢量化:许多环境可以实现每核心高帧率,但受限于策略推理延迟。为了解决此限制,请在每个进程中创建多个环境,以将策略前向传递跨这些矢量化环境进行批处理。将
config.env_runners(num_envs_per_env_runner=..)设置为每个EnvRunneractor 创建多个环境副本。此外,您可以通过 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=..)