🐛 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__)
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
🐛 Bug
When
replay_buffer_classis passed explicitly to an off-policy algorithm,n_steps > 1is silently ignored and the algorithm trains with 1-step returns.
In
OffPolicyAlgorithm._setup_model(), both the n-step buffer selection and its validationlive inside the
if self.replay_buffer_class is None:branch. When the user supplies theclass, neither runs:
self.n_stepskeeps its value, but the buffer is not anNStepReplayBuffer, sosample()returnsdiscounts=Noneandtrain()falls back todiscounts = self.gamma. No exception and no warning are raised.To Reproduce
1.
n_stepsis accepted but never applied when the buffer class is given explicitlyn_steps=3is stored on the model, but the buffer built cannot compute n-step returns.sample()therefore returnsdiscounts=None, andtrain()falls back todiscounts = 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
Relevant log output / Error message
System Info
No response
Checklist