PufferLib v2
Use this skill for codebases pinned to PufferLib 2.x (pufferlib>=2.0,<3.0). PufferLib 2.0 was released on PyPI on December 8, 2024 and introduced the Ocean/native-environment generation described by PufferAI as the 1M SPS release.
[!IMPORTANT]
This is not the v1 API. Do not write from pufferlib import PuffeRL; import the training module with from pufferlib import pufferl or use the puffer CLI. If the repository already uses trainer.evaluate(), trainer.train(), or trainer.mean_and_log(), inspect imports and pinning before editing because that pattern may be v1 or early-v2 code.
Version Selection
- Prefer
pufferlib-v2 only for projects pinned to pufferlib>=2.0,<3.0, reproducing 2024/early-2025 experiments, or maintaining PufferLib 2.x environments.
- Prefer
pufferlib-v3 for pufferlib>=3.0,<4.0 projects or when the code uses newer pufferlib.pufferl config helpers.
- Prefer the legacy
pufferlib skill only for pufferlib==1.0.0 code.
Installation
python -m venv .venv
source .venv/bin/activate
pip install "pufferlib>=2.0,<3.0"
For environments with native graphics, Atari, NetHack, Procgen, Neural MMO, or CUDA-sensitive dependencies, prefer the upstream PufferTank container or the repository's pinned environment. Keep Python, PyTorch, CUDA, Gymnasium, and PettingZoo versions synchronized with the project lockfile.
Primary Workflow
- Confirm the version:
python - <<'PY'
import pufferlib, importlib.metadata
print(importlib.metadata.version('pufferlib'))
print(pufferlib.__file__)
PY
- Prefer CLI training for supported Ocean/built-in environments:
puffer train ENV_NAME --help
puffer train ENV_NAME
puffer eval ENV_NAME --help
- For Python training, prefer the module-level
pufferl API and local examples in the target repository over the old top-level PuffeRL import.
- Keep vectorized environment settings explicit: number of workers, environments per worker / environment count, batch size, backend, and async/sync mode.
- Validate with a tiny run before launching a long experiment.
Native Environment and Vectorization Guidance
PufferLib 2.x centers on high-throughput simulation:
- Use native PufferEnv/Ocean environments when performance matters. Native envs can write observations directly into buffers used by vectorization/training.
- Keep Gymnasium/PettingZoo support as a compatibility layer. Wrap existing environments rather than rewriting them first.
- Use a VecEnv-style interface by default. Async operation extends the synchronous step/reset workflow, so implement synchronous logic first, then add send/recv-style async only if needed.
- Start with a conservative worker count. Increase workers/envs per worker only after profiling CPU utilization and policy-forward time.
Training Pattern
Use this shape for v2 maintenance work; adapt names from the installed package and repository examples rather than assuming v1 signatures:
from pufferlib import pufferl
# Prefer repository-provided config/env/policy helpers when available.
config = load_or_create_config()
vecenv = make_vectorized_env(config)
policy = make_policy(vecenv, config)
trainer = pufferl.PuffeRL(config, vecenv, policy)
while not done_training(trainer, config):
trainer.evaluate()
logs = trainer.train()
if logs:
handle_logs(logs)
checkpoint = trainer.close()
When migrating old v1 code:
- Replace
from pufferlib import PuffeRL with from pufferlib import pufferl.
- Replace
pufferlib.make(...) calls with the v2 vectorization/environment construction used by the project.
- Ensure policies accept the state argument expected by the trainer when recurrent state or async environment metadata is enabled.
- Treat
mean_and_log() as trainer-internal unless local examples call it directly.
Environment Development Checklist
- Define observation/action spaces before reset/step data are consumed.
- Return consistent Gymnasium-style
obs, reward, terminated, truncated, info data in wrappers, or the native PufferEnv equivalent in native envs.
- For multi-agent envs, keep agent ordering stable and document how dead/missing agents are padded or masked.
- Avoid per-step allocation in performance-critical environments. Allocate buffers at initialization and write in place.
- Add a smoke test that resets, steps random actions for at least 100 transitions, and checks shapes/dtypes.
Performance Checklist
- Profile environment step time separately from policy forward/backward time.
- Use async vectorization when policy inference and environment stepping can overlap.
- Keep observation copies to a minimum; prefer native buffers for Ocean/C environments.
- Tune
num_workers, env count, rollout horizon, batch size, and minibatch size together.
- Compare SPS after warmup, not during first-epoch compilation/build overhead.
Common Failure Modes
- ImportError for
PuffeRL: old v1 import; use from pufferlib import pufferl.
- Shape mismatch on first batch: wrapper spaces do not match reset/step output; print
single_observation_space, single_action_space, and first observation dtype/shape.
- Hanging multiprocessing run: test the same env with a serial backend, then reduce workers to one and re-enable multiprocessing.
- Low SPS with fast native env: check policy forward time, Python callbacks/logging, info payload size, and whether async mode is enabled.
Sources to Check When Updating
- PyPI release history for exact 2.x versions.
- PufferAI blog post “PufferLib 2.0: Reinforcement Learning at 1,000,000 Steps/Second”.
- The target repository's lockfile and training examples; v2 projects often carried local helper wrappers.
1---2name: pufferlib-v23description: PufferLib 2.x reinforcement learning workflows for the Dec 2024 API generation. Use when working with pufferlib>=2.0,<3.0, Puffer Ocean C environments, native PufferEnv/VecEnv-style vectorization, Gymnasium/PettingZoo compatibility wrappers, asynchronous sampling, or v2 training/evaluation migration from the deprecated v1 PuffeRL top-level API.4---56# PufferLib v278Use this skill for codebases pinned to **PufferLib 2.x** (`pufferlib>=2.0,<3.0`). PufferLib 2.0 was released on PyPI on **December 8, 2024** and introduced the Ocean/native-environment generation described by PufferAI as the 1M SPS release.910> [!IMPORTANT]11> This is not the v1 API. Do **not** write `from pufferlib import PuffeRL`; import the training module with `from pufferlib import pufferl` or use the `puffer` CLI. If the repository already uses `trainer.evaluate()`, `trainer.train()`, or `trainer.mean_and_log()`, inspect imports and pinning before editing because that pattern may be v1 or early-v2 code.1213## Version Selection1415- Prefer `pufferlib-v2` only for projects pinned to `pufferlib>=2.0,<3.0`, reproducing 2024/early-2025 experiments, or maintaining PufferLib 2.x environments.16- Prefer `pufferlib-v3` for `pufferlib>=3.0,<4.0` projects or when the code uses newer `pufferlib.pufferl` config helpers.17- Prefer the legacy `pufferlib` skill only for `pufferlib==1.0.0` code.1819## Installation2021```bash22python -m venv .venv23source .venv/bin/activate24pip install "pufferlib>=2.0,<3.0"25```2627For environments with native graphics, Atari, NetHack, Procgen, Neural MMO, or CUDA-sensitive dependencies, prefer the upstream PufferTank container or the repository's pinned environment. Keep Python, PyTorch, CUDA, Gymnasium, and PettingZoo versions synchronized with the project lockfile.2829## Primary Workflow30311. Confirm the version:32 ```bash33 python - <<'PY'34 import pufferlib, importlib.metadata35 print(importlib.metadata.version('pufferlib'))36 print(pufferlib.__file__)37 PY38 ```392. Prefer CLI training for supported Ocean/built-in environments:40 ```bash41 puffer train ENV_NAME --help42 puffer train ENV_NAME43 puffer eval ENV_NAME --help44 ```453. For Python training, prefer the module-level `pufferl` API and local examples in the target repository over the old top-level `PuffeRL` import.464. Keep vectorized environment settings explicit: number of workers, environments per worker / environment count, batch size, backend, and async/sync mode.475. Validate with a tiny run before launching a long experiment.4849## Native Environment and Vectorization Guidance5051PufferLib 2.x centers on high-throughput simulation:5253- Use native PufferEnv/Ocean environments when performance matters. Native envs can write observations directly into buffers used by vectorization/training.54- Keep Gymnasium/PettingZoo support as a compatibility layer. Wrap existing environments rather than rewriting them first.55- Use a VecEnv-style interface by default. Async operation extends the synchronous step/reset workflow, so implement synchronous logic first, then add send/recv-style async only if needed.56- Start with a conservative worker count. Increase workers/envs per worker only after profiling CPU utilization and policy-forward time.5758## Training Pattern5960Use this shape for v2 maintenance work; adapt names from the installed package and repository examples rather than assuming v1 signatures:6162```python63from pufferlib import pufferl6465# Prefer repository-provided config/env/policy helpers when available.66config = load_or_create_config()67vecenv = make_vectorized_env(config)68policy = make_policy(vecenv, config)6970trainer = pufferl.PuffeRL(config, vecenv, policy)71while not done_training(trainer, config):72 trainer.evaluate()73 logs = trainer.train()74 if logs:75 handle_logs(logs)7677checkpoint = trainer.close()78```7980When migrating old v1 code:8182- Replace `from pufferlib import PuffeRL` with `from pufferlib import pufferl`.83- Replace `pufferlib.make(...)` calls with the v2 vectorization/environment construction used by the project.84- Ensure policies accept the state argument expected by the trainer when recurrent state or async environment metadata is enabled.85- Treat `mean_and_log()` as trainer-internal unless local examples call it directly.8687## Environment Development Checklist8889- Define observation/action spaces before reset/step data are consumed.90- Return consistent Gymnasium-style `obs, reward, terminated, truncated, info` data in wrappers, or the native PufferEnv equivalent in native envs.91- For multi-agent envs, keep agent ordering stable and document how dead/missing agents are padded or masked.92- Avoid per-step allocation in performance-critical environments. Allocate buffers at initialization and write in place.93- Add a smoke test that resets, steps random actions for at least 100 transitions, and checks shapes/dtypes.9495## Performance Checklist9697- Profile environment step time separately from policy forward/backward time.98- Use async vectorization when policy inference and environment stepping can overlap.99- Keep observation copies to a minimum; prefer native buffers for Ocean/C environments.100- Tune `num_workers`, env count, rollout horizon, batch size, and minibatch size together.101- Compare SPS after warmup, not during first-epoch compilation/build overhead.102103## Common Failure Modes104105- **ImportError for `PuffeRL`**: old v1 import; use `from pufferlib import pufferl`.106- **Shape mismatch on first batch**: wrapper spaces do not match reset/step output; print `single_observation_space`, `single_action_space`, and first observation dtype/shape.107- **Hanging multiprocessing run**: test the same env with a serial backend, then reduce workers to one and re-enable multiprocessing.108- **Low SPS with fast native env**: check policy forward time, Python callbacks/logging, info payload size, and whether async mode is enabled.109110## Sources to Check When Updating111112- PyPI release history for exact 2.x versions.113- PufferAI blog post “PufferLib 2.0: Reinforcement Learning at 1,000,000 Steps/Second”.114- The target repository's lockfile and training examples; v2 projects often carried local helper wrappers.