Ray RLlib DQN(D3QN)单训练迭代多次环境重置问题咨询
Ray RLlib DQN单次训练迭代多次重置环境问题排查与解决
问题背景
在基于极简自定义Gym环境测试Ray RLlib的DQN(Dueling Double DQN)算法时,发现单次训练迭代中环境会被多次重置,尽管每个episode仅执行1步就结束。调整批量大小、horizon等参数后问题仍存在。
1. 自定义环境
import gymnasium as gym from gymnasium import spaces from ray.tune.registry import register_env class SimpleEnv(gym.Env): def __init__(self, config): self.observation_space = spaces.Box(low=0, high=1, shape=(1,), dtype=float) self.action_space = spaces.Discrete(2) self.step_count = 0 self.horizon = config.get("horizon", 1) def reset(self, seed=None, options=None): self.step_count = 0 print("=== RESET ===") # 多次打印此信息 return [0.0], {} def step(self, action): self.step_count += 1 done = self.step_count >= self.horizon print(f"Step: {self.step_count}, Done: {done}") return [0.0], 1.0, done, done, {} register_env("SimpleEnv-v0", lambda cfg: SimpleEnv(cfg))
- horizon设为1,每个episode应仅包含1步。
2. 原DQN配置
from ray.rllib.algorithms.dqn import DQNConfig config = DQNConfig() # Environment config.environment("SimpleEnv-v0", env_config={"horizon": 1}) # Runner settings config.env_runners( num_env_runners=0, rollout_fragment_length=1, batch_mode="complete_episodes" ) # Training settings config.training( dueling=True, double_q=True, train_batch_size=50, train_batch_size_per_learner=50, minibatch_size=25, num_steps_sampled_before_learning_starts=50, target_network_update_freq=1, ) # Episode termination config.soft_horizon = True config.no_done_at_end = False # API stack config.api_stack( enable_rl_module_and_learner=True, enable_env_runner_and_connector_v2=True ) algo = config.build_algo() algo.train()
3. 观测到的输出
=== RESET === Step: 1, Done: True === RESET === Step: 1, Done: True === RESET === Step: 1, Done: True ... 重复多次 ... === RESET ===
尽管设置了batch_mode="complete_episodes"、rollout_fragment_length=1和horizon=1,RLlib仍会在每次训练更新前收集多个episode。
4. 已尝试的方案
- 调整
train_batch_size、train_batch_size_per_learner、num_steps_sampled_before_learning_starts、target_network_update_freq等参数,开关RLModule API栈; - 切换单智能体/多智能体重放缓冲区;
- 使用
.env_runners(...)和.rollouts(...)两种配置方式。
以上操作均无法阻止RLlib在单迭代内多次重置环境。
5. 核心问题
- 为何在设置
batch_mode="complete_episodes"和horizon=1的情况下,Ray RLlib仍会在单次训练迭代中多次重置环境? - 使用RLlib的DQN/D3QN时,如何强制单次训练迭代仅执行一次环境重置(即一个1步episode)?
解决方案
问题原因
原配置中存在两个关键参数导致多次重置:
train_batch_size=50:每次训练需要收集50个样本,每个episode仅1步,因此必须重置环境50次来凑够批次大小;num_steps_sampled_before_learning_starts=50:训练开始前会预采样50个样本,进一步增加了重置次数;- 新API栈(RLModule/EnvRunner)的采样逻辑较复杂,可能存在额外的采样行为。
正确配置示例
要实现单次训练迭代仅收集1个1步episode,需调整以下参数:
from ray.rllib.algorithms.dqn import DQNConfig config = DQNConfig() # Environment config.environment("SimpleEnv-v0", env_config={"horizon": 1}) # Runner settings config.env_runners( num_env_runners=0, rollout_fragment_length=1, batch_mode="complete_episodes" ) # Training settings config.training( dueling=True, double_q=True, train_batch_size=1, # 关键:每个训练批次仅1个样本(对应1步episode) train_batch_size_per_learner=1, minibatch_size=1, num_steps_sampled_before_learning_starts=1, # 关键:跳过预采样,直接开始训练 target_network_update_freq=1, ) # Episode termination config.soft_horizon = True config.no_done_at_end = False # 关闭新API栈,使用旧版rollout逻辑更易控制 config.api_stack( enable_rl_module_and_learner=False, enable_env_runner_and_connector_v2=False ) algo = config.build_algo() # 执行单次训练迭代 result = algo.train() print(f"训练迭代结果:{result['episode_reward_mean']}")
关键调整说明
train_batch_size=1:明确每个训练批次仅包含1个样本,对应1个1步episode,无需多次重置环境;num_steps_sampled_before_learning_starts=1:取消预采样阶段,直接进入训练流程;- 关闭新API栈:旧版的rollout逻辑更直观,符合单episode训练的预期行为;
- 保持
rollout_fragment_length=1和batch_mode="complete_episodes",确保每次rollout仅收集完整的1步episode。
内容的提问来源于stack exchange,提问作者طه الشريف
相关产品推荐
相关产品推荐

