Skip to content

Feature/flashsac integration - #227

Open
psurchit wants to merge 6 commits into
leggedrobotics:mainfrom
psurchit:feature/flashsac-integration
Open

Feature/flashsac integration#227
psurchit wants to merge 6 commits into
leggedrobotics:mainfrom
psurchit:feature/flashsac-integration

Conversation

@psurchit

Copy link
Copy Markdown

Integrated FlashSAC (paper, code) - published at RSS 2026. I will also be raising a PR on MJLab to integrate the MJLab wrapper corresponding to this.

Port FlashSAC's weight-normalized layers, squashed-Gaussian policy, and
ensembled categorical (distributional) double-critic into rsl_rl as
modules/flashsac_layers.py, and wrap them as RSL-RL models
(FlashSACActorModel, FlashSACCriticModel) following the MLPModel surface
(obs-group resolution, EmpiricalNormalization, JIT/ONNX export). Actor
exports a deterministic tanh(mean) head; ONNX export verified. Dual
BSD-3 / MIT (FlashSAC) attribution. Passes ruff check + format.
Cover actor/critic shapes and action bounds, distributional prob-sum,
weight-normalization unit rows, tanh log-det-Jacobian parity, temperature
init, obs-group fail-loud (KeyError/ValueError), and ONNX export validity
+ eager parity. 16 tests, mirroring the existing tests/ layout.
Fixed-capacity uniform replay buffer storing TensorDict observation groups,
with n-step return accumulation ported from FlashSAC's TorchUniformBuffer.
Provides add/can_sample/sample (Batch with terminated/truncated/next_obs)
and save/load. 9 unit tests cover n-step discounting, done-truncation,
wrap-around, sampling shapes, fail-loud construction, and persistence.
Passes ruff + pyright; full suite 200 passed.
Add the FlashSAC algorithm implementing the RSL-RL algorithm contract
(act/process_env_step/compute_returns no-op/update/save/load/get_policy/
compile/construct_algorithm): squashed-Gaussian actor, ensembled categorical
double critic with EMA target, auto-tuned entropy temperature, n-step
categorical TD targets, delayed actor updates, and zeta noise-repetition
exploration. Eager-only + single-GPU for v1 (rejects use_amp/compile/multi-GPU
loudly). Reconstructs terminated/truncated from dones + time_outs, requiring
time_outs for infinite-horizon envs (fail loud).

Adds utils: warmup_cosine_decay scheduler, RewardNormalizer, and fail-loud
_require + resolve_sac_obs_groups helpers. 17 tests cover construction,
rollout/exploration, one update step, delayed actor, EMA drift, save/load,
and fail-loud config paths. ruff + pyright clean; full suite 217 passed.
Add OffPolicyRunner (subclass of OnPolicyRunner) that overrides learn() with
an off-policy loop: collect num_steps_per_env interactions into the replay
buffer, then run num_steps_per_env * updates_per_step gradient updates. Reuses
the base construction, logging, checkpointing, and ONNX/JIT export. Rejects
multi-GPU (WORLD_SIZE > 1) at construction.

Also make the shared Logger robust to algorithms without RND: read
cfg['algorithm'].get('rnd_cfg') instead of requiring the key (no behavior
change for PPO). 10 runner tests cover construction, multi-GPU rejection,
learn loop, param updates, save/load (incl. actor-only), inference bounds,
and ONNX export. ruff + pyright clean; full suite 227 passed.
Average each metric over the iteration's gradient updates instead of
keeping only the last update's dict. With delayed actor updates
(actor_update_period > 1) and updates_per_step making the last update a
critic-only step, actor/entropy/temperature metrics were silently dropped
from logging even though the actor was training. Now all reported metrics
surface.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant