env-ssl-wrapper 0.5.7__tar.gz → 0.5.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/PKG-INFO +8 -8
  2. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/README.md +7 -7
  3. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/sgs.py +30 -12
  4. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/pyproject.toml +1 -1
  5. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/.gitignore +0 -0
  6. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/LICENSE +0 -0
  7. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/__init__.py +0 -0
  8. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/action_chunk.py +0 -0
  9. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/evaluate.py +0 -0
  10. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/memory_trace.py +0 -0
  11. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/__init__.py +0 -0
  12. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/action_transform_wrapper.py +0 -0
  13. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/adapters.py +0 -0
  14. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/auto_batched_wrapper.py +0 -0
  15. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/done_tracker_wrapper.py +0 -0
  16. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/episode_padding_wrapper.py +0 -0
  17. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/flatten_obs_wrapper.py +0 -0
  18. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/helpers.py +0 -0
  19. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/image_wrapper.py +0 -0
  20. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/mocks.py +0 -0
  21. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/spaces.py +0 -0
  22. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/standardize_env_wrapper.py +0 -0
  23. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/standardize_wrapper.py +0 -0
  24. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/tensor_wrapper.py +0 -0
  25. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/time_limit_wrapper.py +0 -0
  26. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/utils.py +0 -0
  27. {env_ssl_wrapper-0.5.7 → env_ssl_wrapper-0.5.8}/env_ssl_wrapper/standardize/vector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: env-ssl-wrapper
3
- Version: 0.5.7
3
+ Version: 0.5.8
4
4
  Summary: One torch-native interface for any MDP environment
5
5
  Project-URL: Homepage, https://pypi.org/project/env-ssl-wrapper/
6
6
  Project-URL: Repository, https://codeberg.org/lucidrains/env-ssl-wrapper
@@ -182,7 +182,7 @@ uv run test_action_chunk.py --verify=True --sweep=True # chunked rollouts matc
182
182
 
183
183
  ### Success-Guided Sampling
184
184
 
185
- Adaptive curriculum over a bank of reset states, keeping episodes near the policy's frontier of competence — the configurations it currently solves about `target` of the time ([Octi Zhang et al., 2026](https://arxiv.org/abs/2603.15999))
185
+ Adaptive curriculum over a bank of reset states, keeping episodes near the policy's frontier of competence — the configurations it currently solves about `target` of the time ([Octi Zhang et al., 2026](https://arxiv.org/abs/2610.12465))
186
186
 
187
187
  ```python
188
188
  import gymnasium as gym
@@ -202,9 +202,9 @@ obs, info = env.reset()
202
202
 
203
203
  The score equation is swappable: the default beta shaped kernel around `target` (`sgs_score_fn`) is simply one rule of the bank's state. Whatever you pass as `score_fn` is handed, by name, the arguments it declares — `p` (per state success rates), `counts`, `history` (the raw episode outcomes), `step`, `window`, and the hparams `target`, `kappa`, `eps`, `unvisited_weight`.
204
204
 
205
- The sampling distribution is swappable too: the default (`sgs_sample_fn`) draws from the beta shape the score produces, while a custom `sample_fn` is handed, by name, whatever it declares — `p`, `counts`, `history`, `configs`, `weights`, `probs`, `rng`, `size`, `step`, and the hparams — so any distribution of the bank can be plugged in.
205
+ The sampling distribution is swappable too: the default follows the paper's Eq. (2) — the beta shape the score produces is floored at `eps`, logits are formed and softmaxed at `temperature` (floored at 1; the paper uses 2.) — and `sgs_sample_fn` draws i.i.d. from those `probs`. A custom `sample_fn` is handed, by name, whatever it declares — `p`, `counts`, `history`, `configs`, `weights` (the raw kernel), `probs` (floored and tempered), `rng`, `size`, `step`, `temperature`, and the hparams — so any distribution of the bank can be plugged in.
206
206
 
207
- The rest of the loop is hookable as well: target schedule, uniform floor (`uniform_prob`), env-native fallback (`default_prob`), success signal (`success_fn`).
207
+ The rest of the loop is hookable as well: target and temperature schedules, uniform floor (`uniform_prob`), env-native fallback (`default_prob`), success signal (`success_fn`).
208
208
 
209
209
  Track the curriculum as it runs — one snapshot of the bank per credited episode, kept in memory and appended to a csv when `log_path` is set:
210
210
 
@@ -360,10 +360,10 @@ uv run pytest
360
360
  ```
361
361
 
362
362
  ```bibtex
363
- @article{zhang2026omnireset,
364
- title = {OmniReset: Solving Dexterous Manipulation from Sparse Rewards via Reset States},
365
- author = {Octi Zhang and others},
366
- journal = {arXiv preprint arXiv:2603.15999},
363
+ @article{zhang2026balanced,
364
+ title = {A Balanced Data Diet: Addressing the Exploration Bottleneck in Mega-Scale RL for Robot Control},
365
+ author = {Octi Zhang and Mateo Guaman Castro and Patrick Yin and Ignacio Dagnino and Abhishek Gupta and Rosario Scalise and Byron Boots},
366
+ journal = {arXiv preprint arXiv:2610.12465},
367
367
  year = {2026}
368
368
  }
369
369
  ```
@@ -122,7 +122,7 @@ uv run test_action_chunk.py --verify=True --sweep=True # chunked rollouts matc
122
122
 
123
123
  ### Success-Guided Sampling
124
124
 
125
- Adaptive curriculum over a bank of reset states, keeping episodes near the policy's frontier of competence — the configurations it currently solves about `target` of the time ([Octi Zhang et al., 2026](https://arxiv.org/abs/2603.15999))
125
+ Adaptive curriculum over a bank of reset states, keeping episodes near the policy's frontier of competence — the configurations it currently solves about `target` of the time ([Octi Zhang et al., 2026](https://arxiv.org/abs/2610.12465))
126
126
 
127
127
  ```python
128
128
  import gymnasium as gym
@@ -142,9 +142,9 @@ obs, info = env.reset()
142
142
 
143
143
  The score equation is swappable: the default beta shaped kernel around `target` (`sgs_score_fn`) is simply one rule of the bank's state. Whatever you pass as `score_fn` is handed, by name, the arguments it declares — `p` (per state success rates), `counts`, `history` (the raw episode outcomes), `step`, `window`, and the hparams `target`, `kappa`, `eps`, `unvisited_weight`.
144
144
 
145
- The sampling distribution is swappable too: the default (`sgs_sample_fn`) draws from the beta shape the score produces, while a custom `sample_fn` is handed, by name, whatever it declares — `p`, `counts`, `history`, `configs`, `weights`, `probs`, `rng`, `size`, `step`, and the hparams — so any distribution of the bank can be plugged in.
145
+ The sampling distribution is swappable too: the default follows the paper's Eq. (2) — the beta shape the score produces is floored at `eps`, logits are formed and softmaxed at `temperature` (floored at 1; the paper uses 2.) — and `sgs_sample_fn` draws i.i.d. from those `probs`. A custom `sample_fn` is handed, by name, whatever it declares — `p`, `counts`, `history`, `configs`, `weights` (the raw kernel), `probs` (floored and tempered), `rng`, `size`, `step`, `temperature`, and the hparams — so any distribution of the bank can be plugged in.
146
146
 
147
- The rest of the loop is hookable as well: target schedule, uniform floor (`uniform_prob`), env-native fallback (`default_prob`), success signal (`success_fn`).
147
+ The rest of the loop is hookable as well: target and temperature schedules, uniform floor (`uniform_prob`), env-native fallback (`default_prob`), success signal (`success_fn`).
148
148
 
149
149
  Track the curriculum as it runs — one snapshot of the bank per credited episode, kept in memory and appended to a csv when `log_path` is set:
150
150
 
@@ -300,10 +300,10 @@ uv run pytest
300
300
  ```
301
301
 
302
302
  ```bibtex
303
- @article{zhang2026omnireset,
304
- title = {OmniReset: Solving Dexterous Manipulation from Sparse Rewards via Reset States},
305
- author = {Octi Zhang and others},
306
- journal = {arXiv preprint arXiv:2603.15999},
303
+ @article{zhang2026balanced,
304
+ title = {A Balanced Data Diet: Addressing the Exploration Bottleneck in Mega-Scale RL for Robot Control},
305
+ author = {Octi Zhang and Mateo Guaman Castro and Patrick Yin and Ignacio Dagnino and Abhishek Gupta and Rosario Scalise and Byron Boots},
306
+ journal = {arXiv preprint arXiv:2610.12465},
307
307
  year = {2026}
308
308
  }
309
309
  ```
@@ -107,8 +107,8 @@ def try_reset_slot(env, idx: int, options: dict):
107
107
  return None
108
108
 
109
109
  # curriculum score functions
110
- # Success-Guided Sampling (SGS) / OmniReset - Octi Zhang et al.
111
- # https://arxiv.org/abs/2603.15999
110
+ # Success-Guided Sampling (SGS) - Octi Zhang et al.
111
+ # https://arxiv.org/abs/2610.12465
112
112
 
113
113
  def sgs_score_fn(
114
114
  p: torch.Tensor,
@@ -167,7 +167,7 @@ def sgs_sample_fn(
167
167
  rng: np.random.Generator,
168
168
  size: int = 1
169
169
  ) -> np.ndarray:
170
- # the paper's default - categorical draw over the beta shaped probs (see `sgs_score_fn`)
170
+ # categorical draw over the handed probs - the eps floor and temperature are applied upstream
171
171
 
172
172
  probs_np = to_numpy(probs).astype(np.float64)
173
173
 
@@ -178,13 +178,14 @@ def sgs_sample_fn(
178
178
  class SGSSampler:
179
179
  """
180
180
  Success-Guided Sampling (SGS) curriculum sampler over a bank of reset configurations.
181
- Proposed by Octi Zhang et al. in OmniReset (https://arxiv.org/abs/2603.15999).
181
+ Proposed by Octi Zhang et al. (https://arxiv.org/abs/2610.12465).
182
182
 
183
- The default sampling distribution is the beta kernel around `target` evaluated at the
184
- success rates (`sgs_score_fn`), drawn by `sgs_sample_fn`. Swap either hook - `score_fn`
185
- reshapes the scores, `sample_fn` picks the distribution - each is handed, by name,
186
- whatever it declares of `p`, `counts`, `history`, `configs`, `weights`, `probs`, `rng`,
187
- `size`, `step`, `window` and the hparams.
183
+ The default sampling distribution is the paper's Eq. (2): the beta kernel around `target`
184
+ evaluated at the success rates (`sgs_score_fn`), floored at `eps`, logits formed, and
185
+ softmaxed at `temperature` (floored at 1, the paper uses 2.), drawn by `sgs_sample_fn`.
186
+ Swap either hook - `score_fn` reshapes the scores, `sample_fn` picks the distribution -
187
+ each is handed, by name, whatever it declares of `p`, `counts`, `history`, `configs`,
188
+ `weights`, `probs`, `rng`, `size`, `step`, `window` and the hparams.
188
189
 
189
190
  Set `log_every` to keep snapshots of the bank in `self.trace` as episodes are credited,
190
191
  and `log_path` to also append them to a csv (step, success rates, sampling probs).
@@ -198,6 +199,7 @@ class SGSSampler:
198
199
  eps: float = 0.05,
199
200
  window: int = 20,
200
201
  unvisited_weight: float = 1.,
202
+ temperature: float | Callable[[int], float] = 1.,
201
203
  uniform_prob: float | Callable[[int], float] = 0.,
202
204
  default_prob: float | Callable[[int], float] = 0.,
203
205
  score_fn: Callable | None = None,
@@ -218,6 +220,7 @@ class SGSSampler:
218
220
  self.eps = float(eps)
219
221
  self.window = int(window)
220
222
  self.unvisited_weight = float(unvisited_weight)
223
+ self.temperature = temperature
221
224
  self.uniform_prob = uniform_prob
222
225
  self.default_prob = default_prob
223
226
 
@@ -272,7 +275,19 @@ class SGSSampler:
272
275
 
273
276
  @property
274
277
  def probs(self) -> torch.Tensor:
275
- return self._mixed_probs(self.weights)
278
+ return self._mixed_probs(self._sampling_weights(self.weights))
279
+
280
+ def _effective_temperature(self) -> float:
281
+ # the paper floors the temperature at one: T_eff = max(T, 1)
282
+
283
+ return max(resolve_schedule(self.temperature, self.step_count), 1.)
284
+
285
+ def _sampling_weights(self, weights: torch.Tensor) -> torch.Tensor:
286
+ # paper's Eq. (2) - floor the kernel at eps, form logits, softmax at T_eff
287
+
288
+ eps = self.eps
289
+
290
+ return (weights.clamp(min = eps) + eps) ** (1. / self._effective_temperature())
276
291
 
277
292
  def _mixed_probs(self, weights: torch.Tensor) -> torch.Tensor:
278
293
  # normalize, then mix in the uniform floor - what the default sampler draws from
@@ -313,10 +328,11 @@ class SGSSampler:
313
328
  **self._bank_args(step),
314
329
  configs = self.configs,
315
330
  weights = weights,
316
- probs = self._mixed_probs(weights),
331
+ probs = self._mixed_probs(self._sampling_weights(weights)),
317
332
  rng = self.rng,
318
333
  size = size,
319
334
  uniform_prob = resolve_schedule(self.uniform_prob, step),
335
+ temperature = self._effective_temperature(),
320
336
  )
321
337
 
322
338
  indices = to_numpy(sample_fn(**inject_args(sample_fn, available))).astype(int).reshape(-1)
@@ -388,7 +404,7 @@ class SGSSampler:
388
404
 
389
405
  class SuccessGuidedSamplingWrapper(EnvWrapper):
390
406
  """
391
- Success-Guided Sampling (SGS) environment wrapper (Octi Zhang et al., https://arxiv.org/abs/2603.15999).
407
+ Success-Guided Sampling (SGS) environment wrapper (Octi Zhang et al., https://arxiv.org/abs/2610.12465).
392
408
  Wraps on top of StandardizeEnvWrapper (or any single / vectorized environment) to adaptively sample
393
409
  initial reset states at the policy's frontier of competence and track per-config success rates.
394
410
  Pass `log_every` / `log_path` to record the progression of the bank (see `SGSSampler`).
@@ -405,6 +421,7 @@ class SuccessGuidedSamplingWrapper(EnvWrapper):
405
421
  eps: float = 0.05,
406
422
  window: int = 20,
407
423
  unvisited_weight: float = 1.,
424
+ temperature: float | Callable[[int], float] = 1.,
408
425
  uniform_prob: float | Callable[[int], float] = 0.,
409
426
  default_prob: float | Callable[[int], float] = 0.,
410
427
  score_fn: Callable | None = None,
@@ -432,6 +449,7 @@ class SuccessGuidedSamplingWrapper(EnvWrapper):
432
449
  eps = eps,
433
450
  window = window,
434
451
  unvisited_weight = unvisited_weight,
452
+ temperature = temperature,
435
453
  uniform_prob = uniform_prob,
436
454
  default_prob = default_prob,
437
455
  score_fn = score_fn,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "env-ssl-wrapper"
3
- version = "0.5.7"
3
+ version = "0.5.8"
4
4
  description = "One torch-native interface for any MDP environment"
5
5
  authors = [
6
6
  { name = "Phil Wang", email = "lucidrains@gmail.com" }
File without changes