Skip to content

plugrl-bridges: gymnasium and SB3 adapters beside RLinf's, and a per-episode log - #2

Merged
tactino merged 2 commits into
initfrom
bridges
Oct 2, 2026
Merged

tactino merged 2 commits into
initfrom
bridges

Conversation

@tactino

@tactino tactino commented Oct 2, 2026

Copy link
Copy Markdown
Member

Stacked on #1, which E48 runs at fca69db; that branch is left as it is.

What changes

The RLinf bridge becomes plugrl-bridges: one lockstep BridgeServer, and three adapters on it.

adapter trainer interface
plugrl_bridges.rlinf.PlugRLEnv RLinf its env contract, env_type: plugrl (was plugrl_rlinf.env)
plugrl_bridges.gym.PlugRLVectorEnv CleanRL, your own loop gymnasium.vector.VectorEnv, SAME_STEP autoreset
plugrl_bridges.sb3.PlugRLVecEnv Stable-Baselines3 SB3's VecEnv
  • Episode statistics. The adapters count them from the raw rewards, so no gymnasium wrapper is needed. As of 1.3, gymnasium's vector RecordEpisodeStatistics drops each episode's first reward under SAME_STEP (plugrl-server E51), and its vector observation wrappers refuse SAME_STEP. plugrl_bridges.gym.NormalizeObservation is provided instead.
  • Episode log. BridgeServer(episode_log=PATH) writes step,slot,episode,return,length for every episode. So does PLUGRL_BRIDGES_EPISODE_LOG, and RLinf's env.train.episode_log. It is the same record whichever trainer steps the bridge, and E49 judges every trainer on it.
  • Examples.
    • CleanRL's ppo_continuous_action.py, with only its env creation and episode logging changed (MIT, LICENSE-CLEANRL).
    • SB3's PPO, with rl-zoo's Pendulum settings as a preset.
    • RLinf configs for the C++ Pendulum client.
    • run_bridged.sh TRAINER ENV OUT SEED for one run of any of them with 16 clients.
  • cross_clients.py refuses a --run-dir that Git Bash has rewritten. That rewrite left E48's clients reconnecting after their run (E48 AMENDMENT.md).
  • CI: ruff 0.12.12 (check and format) and pytest, with torch from the CPU index.

Tested

  • Unit tests: 16 pass, on Windows and on guangzhao (bridges-venv: torch 2.14.1+cpu, gymnasium 1.3.0, SB3 2.9.0). Two of them are new, for the episode log.
  • SB3 on 16 C++ Pendulum clients (E49 pilot, seed 9): return from -1,254 to -204 over 102,400 steps. Three separate counts agree on all 512 episodes: the episode log, SB3's monitor.csv, and each C++ client's own count.
  • SB3 with its 16 environments in-process, and the same 16 behind PlugRLVecEnv (E50): byte-identical final weights, on Pendulum and on HalfCheetah, on every seed.
  • Episode counts against a known episode (E51): both adapters and the episode log count right.

The repository is renamed to plugrl-bridges once E48 has finished.

…, and a per-episode log

The lockstep BridgeServer moves out of the RLinf adapter into
plugrl_bridges.server, and three adapters sit on it:
- plugrl_bridges.rlinf.PlugRLEnv: RLinf's env contract (was plugrl_rlinf.env);
- plugrl_bridges.gym.PlugRLVectorEnv: a gymnasium VectorEnv under SAME_STEP
  autoreset, with episode statistics counted by the bridge, and a
  NormalizeObservation that also normalizes final_obs (gymnasium 1.3's vector
  observation wrappers refuse SAME_STEP);
- plugrl_bridges.sb3.PlugRLVecEnv: an SB3 VecEnv with terminal_observation,
  TimeLimit.truncated and episode.

BridgeServer(episode_log=PATH), or PLUGRL_BRIDGES_EPISODE_LOG, writes one CSV
line per episode (step, slot, episode, return, length), summed from the
rewards the clients sent, whichever trainer steps the bridge.

Examples: CleanRL's ppo_continuous_action.py with only its env creation and
episode logging changed (MIT, LICENSE-CLEANRL), SB3's PPO with rl-zoo's
Pendulum settings as a preset, RLinf PPO-MLP configs for the C++ Pendulum
client, and run_bridged.sh for one run of any trainer with 16 clients.
cross_clients.py now refuses a --run-dir that Git Bash has rewritten.

CI: ruff 0.12.12 (check, format) and pytest; torch from the CPU index.
…ort check finds RLinf

E49's pilot found the Pendulum config claiming rl-zoo's PPO settings while
keeping the global_batch_size 1,024 it inherited from RLinf's CartPole
template: 40 updates per 4,096-frame rollout against rl-zoo's 640 (rl-zoo
leaves batch_size at SB3's default, 64). Now 64.

install_guangzhao.sh checked the env class without RLinf on PYTHONPATH (RLinf
is not installed as a package), so the check failed after the install had
worked.
@tactino
tactino merged commit 0ff9c79 into init Oct 2, 2026
2 checks passed
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