Skip to main content

Jaxnasium: A Lightweight Utility Library for JAX-based RL Projects

PyPI version Python 3.11+ Ruff Documentation Status

Jaxnasium is not an environment suite, and not a framework that locks you in. Rather, it is your one-stop shop for your JAX RL code: a single environment API that existing suites are wrapped into, a set of general algorithms you can either import or copy into your project, and the tooling to train, evaluate and sweep them.

  1. 🕹️ One environment API. Import environments from Gymnax, Jumanji, Brax, Pgx, JaxMARL, xMinigrid, Navix, PopJym or Craftax through jym.make(...), automatically wrapped to a common standard.
  2. 🤖 Readable cross-suite algorithms. Various algorithms that can operate on any of those environments in near-single-file philosophy, built in Equinox with a familiar Stable-Baselines-like API and end-to-end JIT training in the spirit of PureJaxRL.
  3. 👥 Multi-agent for free. Single-agent algorithm code transparently upgrades to multi-agent environments through PyTrees and function transformations.
  4. 📊 Sweeps and evaluation. Grid, random, Sobol and one-at-a-time searches over many seeds, locally or across a Slurm job array.
  5. 🚀 Project scaffolding. Bootstrap a complete codebase with a single CLI command.

For more details, see the 📖 Documentation.

Installation

pip install "jaxnasium[algs]"   # [algs] pulls in optax + distrax, needed for jaxnasium.algorithms

Third-party environment suites are not dependencies; install the ones you want to use (e.g. pip install gymnax). For a brand-new project, let the CLI set everything up for you:

uvx jaxnasium init <projectname>   # or: pipx run jaxnasium init <projectname>
cd <projectname> && uv run train.py

Quickstart

import jax
import jaxnasium as jym
from jaxnasium.algorithms import PPO

env = jym.make("CartPole-v1")
key = jax.random.PRNGKey(0)

algorithm = PPO(total_timesteps=500_000, learning_rate_start=2.5e-3)
agent, metrics = algorithm.train(key, env)
returns = agent.evaluate(key, env, num_eval_episodes=10)

train returns the trained agent alongside its training metrics: by default the mean return of the episodes that finished in each training iteration, one scalar per iteration (iterations without a finished episode yield NaN).

🏠 Environments

Jaxnasium does not aim to deliver a full environment suite. Instead, jym.make(...) imports environments from existing suites (provided they are installed) and wraps them to the Jaxnasium API standard:

env = jym.make("Breakout-MinAtar")  # from Gymnax
env = jym.FlattenObservationWrapper(env)

algorithm = PPO(**some_good_hyperparameters)
agent, metrics = algorithm.train(jax.random.PRNGKey(0), env)

# > Using an environment from Gymnax via gymnax.make(Breakout-MinAtar).
# > Wrapping Gymnax environment with GymnaxWrapper
# >  Control this behavior by passing wrappers=[...] to jym.make
# > Wrapping environment in VecEnvWrapper
# > ... training results

By default make applies the adapter wrapper for the environment's library and a LogWrapper for episode statistics; the algorithms add a VecEnvWrapper themselves when training.

For convenience, Jaxnasium bundles the 5 classic-control environments, which need no external dependencies.

See Available Environments for a complete list of available environments.

Environment API

The Jaxnasium API stays close to the somewhat established Gymnax API for the reset() and step() functions, but allows for truncated episodes in a manner closer to Gymnasium.

obs, env_state = env.reset(key)  # <-- Mirroring Gymnax

# env.step(): Gymnasium Timestep tuple with state information
(obs, reward, terminated, truncated, info), env_state = env.step(key, env_state, action)

Writing your own environment means subclassing jym.Environment and implementing step_env, reset_env, observation_space and action_space.

🤖 Algorithms

Algorithms in jaxnasium.algorithms follow a near-single-file implementation philosophy. In contrast to implementations in CleanRL or PureJaxRL, Jaxnasium algorithms are built in Equinox and follow a class-based design with a familiar Stable-Baselines API.

Each algorithm is split into an algorithm, which holds the hyperparameters and the training logic, and the agent, holding the trainable state along with the trainer that produced it.

agent, metrics = PPO(**some_good_hyperparameters).train(key, env)

agent.get_action(key, obs)                          # act
agent, more_metrics = agent.train(key, env)         # keep training
agent.save("ppo_agent.eqx")                         # checkpoint, trainer included

Networks are configurable without touching the algorithm, observation and action spaces may be arbitrary PyTrees of spaces, and observation/reward normalization is built in and checkpointed with the agent. See Algorithms for the details.

Algorithm Multi-Agent1 Observation Spaces Action Spaces Composite (nested) Spaces2
PPO ✅ Box, Discrete, MultiDiscrete Box, Discrete, MultiDiscrete ✅
DQN ✅ Box, Discrete, MultiDiscrete Discrete, MultiDiscrete3 ✅
PQN ✅ Box, Discrete, MultiDiscrete Discrete, MultiDiscrete3 ✅
SAC ✅ Box, Discrete, MultiDiscrete Box, Discrete, MultiDiscrete ✅

1 All algorithms support automatic multi-agent transformation through the auto_upgrade_multi_agent parameter. See Multi-Agent for more information.

2 Algorithms support composite (nested) spaces. See Spaces for more information.

3 MultiDiscrete action spaces in PQN and DQN are only supported when flattening to a Discrete action space. E.g. via the FlattenActionSpaceWrapper.

👥 Multi-agent

Multi-agent support is a core pillar of Jaxnasium's design rather than a separate API. Multi-agent Environments simply expose a PyTree of spaces whose first level is the agent dimension, and algorithms build one agent per entry automatically:

env = jym.make("MPE_simple_spread_v3")  # a JaxMARL environment
agent, metrics = PPO().train(key, env)  # one PPO agent per agent in the environment

agent.get_action(key, obs)  # {"agent_0": ..., "agent_1": ..., ...}

Hyperparameters may even differ per agent, e.g. PPO(gamma={"agent_0": 0.9, "agent_1": 0.99}). See Multi-Agent.

📊 Sweeps and evaluation

jaxnasium.eval turns any function into a parameter sweep, and provides a standard train-and-evaluate trial for Jaxnasium algorithms. Jobs are addressed by index, so the same script runs locally in a loop or as a Slurm job array:

from jaxnasium.eval import AlgorithmEvaluation, GridSearch, SobolSearch, Sweep

sweep = Sweep(
    AlgorithmEvaluation(jax.random.split(key, 10), batch_size=5, save_path="results/"),
    GridSearch({"env": ["CartPole-v1", "Acrobot-v1"], "algorithm": ["PPO", "DQN"]}),
    SobolSearch({"learning_rate_start": (1e-4, 1e-2, "log")}, num_samples=32, seed=key),
)

len(sweep)          # 2 envs * 2 algorithms * 32 learning rates
result = sweep[0]()  # run one job

See Sweeps and Searches.

Where to go next

Environment · Spaces · Wrappers Build or adapt an environment
Algorithms · Multi-Agent Train agents
Networks · Architectures Swap in your own model
Sweeps · Searches Run experiments at scale
Compilation Ahead-of-time compilation and caching
Checkpointing · Tree utilities · CLI Everything else

Metadata

Release files for jaxnasium 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jaxnasium 0.1.0
File Size Uploaded Provenance
jaxnasium-0.1.0.tar.gz 108.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for jaxnasium 0.1.0
File Interpreter ABI Platform
jaxnasium-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 255.6 kB

Release files / jaxnasium-0.1.0.tar.gz

Download URL jaxnasium-0.1.0.tar.gz
Size 108.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2f98aab4a61e5162dea2ec9149d0bcca20e991b0e0fbb9b41788aa8bef7c8343
BLAKE2b-256 checksum
How to use checksums
b289bbf35b7c7417b8ee2a64db729bbcc2cad4b85bad9a514fd2107a81583b54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / jaxnasium-0.1.0-py3-none-any.whl

Download URL jaxnasium-0.1.0-py3-none-any.whl
Size 147.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
11bc5cbc5c8cb2fff626d8650b9543987975551d7435446e5b8caec133fd4805
BLAKE2b-256 checksum
How to use checksums
9032c467d2c028f7aec04803df4112a1062a214ac0d6e144462caf65956f4ab0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Security for jaxnasium 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page