Skip to content

[Bug]: n_steps > 1 is silently ignored when replay_buffer_class is passed explicitly #2274

Description

@Koustav-github

🐛 Bug

When replay_buffer_class is passed explicitly to an off-policy algorithm, n_steps > 1
is silently ignored and the algorithm trains with 1-step returns.

In OffPolicyAlgorithm._setup_model(), both the n-step buffer selection and its validation
live inside the if self.replay_buffer_class is None: branch. When the user supplies the
class, neither runs: self.n_steps keeps its value, but the buffer is not an
NStepReplayBuffer, so sample() returns discounts=None and train() falls back to
discounts = self.gamma. No exception and no warning are raised.

To Reproduce

1. n_steps is accepted but never applied when the buffer class is given explicitly

from stable_baselines3 import SAC
from stable_baselines3.common.buffers import ReplayBuffer

model = SAC("MlpPolicy", "Pendulum-v1", n_steps=3, buffer_size=200,
            replay_buffer_class=ReplayBuffer)
print(model.n_steps, type(model.replay_buffer).__name__)
3 ReplayBuffer

n_steps=3 is stored on the model, but the buffer built cannot compute n-step returns.
sample() therefore returns discounts=None, and train() falls back to
discounts = self.gamma, i.e. 1-step returns. Nothing is raised or warned.

2. The same configuration is rejected or accepted depending only on whether the class is named

from stable_baselines3 import SAC
from stable_baselines3.common.envs import BitFlippingEnv
from stable_baselines3.her import HerReplayBuffer

env_kwargs = dict(n_bits=4, continuous=True)

try:
    SAC("MultiInputPolicy", BitFlippingEnv(**env_kwargs), n_steps=3, buffer_size=200)
except AssertionError as e:
    print("no explicit class ->", type(e).__name__ + ":", e)

m = SAC("MultiInputPolicy", BitFlippingEnv(**env_kwargs), n_steps=3, buffer_size=200,
        replay_buffer_class=HerReplayBuffer, learning_starts=10)
print("explicit HerReplayBuffer -> no error;", type(m.replay_buffer).__name__, "n_steps =", m.n_steps)
no explicit class -> AssertionError: N-step returns are not supported for Dict observation spaces yet.
explicit HerReplayBuffer -> no error; HerReplayBuffer n_steps = 3

Relevant log output / Error message

No error and no warning are raised in the silent cases -- that is the bug.

The only exception produced anywhere in the repro is:

    AssertionError: N-step returns are not supported for Dict observation spaces yet.

It comes from the case that already behaves CORRECTLY: a Dict observation space with
n_steps=3 and no explicit replay_buffer_class. It is shown to highlight the inconsistency,
not because it is the problem being reported.

System Info

No response

Checklist

  • My issue does not relate to a custom gym environment. (Use the custom gym env template instead)
  • I have checked that there is no similar issue in the repo
  • I have read the documentation
  • I have provided a minimal and working example to reproduce the bug
  • I've used the markdown code blocks for both code and stack traces.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions