skills/pufferlib/references/training.md
Research snapshot: 2026-07-23.
PyPI's latest stable pufferlib release is 3.0.0, published
2025-06-23. It declares Python >=3.9 and is distributed only as a
60.7 MB source archive:
pufferlib-3.0.0.tar.gz
sha256: 7df3a3e3f5f894d78d2a1f5374097890aec01473183e748abefe4f3faa10eaa9
The uploaded metadata depends on NumPy <2.0, Gym <=0.23, Gymnasium
<=0.29.1, PettingZoo <=1.24.1, Shimmy, Torch, Neptune, W&B, and other
packages without a complete transitive lock. It does not declare a CUDA
version or a minimum Torch version. Do not invent compatibility guarantees.
The upstream default branch is 4.0; its pyproject.toml says version 4.0.0,
Python >=3.10, and Torch >=2.9. As of the research date, this source line
is not the latest stable PyPI artifact.
The current PufferTank Dockerfile uses:
13.0.2 cuDNN development image2025.6.3The Dockerfile does not pin an exact Torch wheel, uv version, PufferLib commit, or every apt package. It is an upstream convenience environment, not a complete reproducibility lock.
Do not use an unpinned uv pip install pufferlib. Work in a disposable,
project-specific environment and commit pyproject.toml plus uv.lock.
For the published profile, after reviewing the source archive and build:
uv venv --python 3.11
uv add --exact --no-sync "pufferlib==3.0.0"
uv lock
uv sync --frozen
Confirm the lock records the published SHA-256 above and review every resolved dependency. The 3.0.0 source build can compile native code and may fetch build assets. Resolve and build in a sandbox with no credentials or sensitive mounts. Do not treat a successful resolver run as a security review.
For 4.0 source work, pin an immutable revision rather than branch 4.0:
uv add --no-sync \
"pufferlib @ git+https://github.com/PufferAI/PufferLib.git@25647630e1b15330bb3153a5a0d3ff8d234c3acf"
uv lock
The commit above is the reviewed 4.0 branch head on 2026-07-23. Re-review before updating it. Native training still requires an audited build of a specific environment; uv locking does not lock compilers, CUDA, NCCL, cuDNN, Raylib, or system libraries.
Never run remote install scripts directly from a pipe. Download, inspect, pin, verify, and execute only in an appropriate sandbox.
The 3.0 console entry point is puffer = pufferlib.pufferl:main:
puffer train ENV_NAME [OPTIONS]
puffer eval ENV_NAME [OPTIONS]
puffer sweep ENV_NAME [OPTIONS]
puffer autotune ENV_NAME [OPTIONS]
puffer profile ENV_NAME [OPTIONS]
puffer export ENV_NAME [OPTIONS]
Environment, vector, policy, recurrent, training, and sweep values come from INI sections. Overrides use section-qualified flags:
puffer train puffer_breakout \
--train.device cpu \
--train.total-timesteps 100000 \
--vec.backend Serial \
--vec.num-envs 2
Run puffer train ENV_NAME --help against the exact locked environment because
available options are generated from merged INI files.
The stable trainer is pufferlib.pufferl.PuffeRL, not a top-level
pufferlib.PuffeRL:
from pufferlib import pufferl
args = pufferl.load_config("puffer_breakout")
vecenv = pufferl.load_env("puffer_breakout", args)
policy = pufferl.load_policy(args, vecenv, "puffer_breakout")
trainer = pufferl.PuffeRL(args["train"], vecenv, policy)
try:
while trainer.epoch < trainer.total_epochs:
trainer.evaluate()
trainer.train()
trainer.mean_and_log()
finally:
trainer.close()
The exact public methods include evaluate, train, mean_and_log,
save_checkpoint, print_dashboard, and close. Use the CLI when possible;
the Python trainer is a relatively low-level implementation surface.
auto in a
published experiment.seed in both [vec] and [train], then run multiple independent seeds.torch_deterministic, precision, compile settings, optimizer, horizon,
minibatch, and total timesteps.Build one audited environment, then use:
puffer train breakout
puffer eval breakout --load-model-path checkpoints/.../weights.bin
puffer sweep breakout
puffer match breakout \
--load-model-path trusted-a.bin \
--load-enemy-model-path trusted-b.bin
Current modes are train, eval, sweep, paretosweep, and match.
Native training is the default. --slowly selects the Torch fallback.
Configuration uses sections such as:
[vec]
total_agents = 4096
num_buffers = 2
num_threads = 16
[train]
total_timesteps = 10_000_000
minibatch_size = 8192
horizon = 64
[torch]
network = MinGRU
encoder = DefaultEncoder
decoder = DefaultDecoder
Current source validates that minibatch_size is divisible by horizon and
does not exceed horizon * total_agents. Multi-GPU launch uses spawn. Do a
small CPU/local build and contract test before CUDA training.
Training rollouts are not evaluation. For every reported result:
Generate a starting plan:
python3 scripts/repro_plan.py --environment synthetic
PufferLib 3.0 saves a policy state_dict with torch.save and a separate
trainer state containing optimizer state, global step, epoch, and run ID. Its
loading paths call torch.load. The 4.0 native backend writes .bin weight
files; the 4.0 Torch fallback also uses torch.save/torch.load.
Rules:
latest in a reproducible run; resolve and record the exact path
and digest.Safe metadata inspection:
python3 scripts/inspect_checkpoint.py trusted/model.pt \
--expected-sha256 EXPECTED_DIGEST
The helper hashes and classifies bytes only. It never imports Torch, invokes pickle, opens archive members, or extracts files.
Local logging is the default. W&B and Neptune are optional network services that may transmit configuration, metrics, source metadata, hardware telemetry, stdout/stderr, and explicitly uploaded checkpoints/artifacts. They can create storage, seat, compute, or retention costs and are subject to vendor privacy, access, and retention policies.
Credential rules:
WANDB_API_KEY or an approved secret
manager.NEPTUNE_API_TOKEN or an approved secret manager..env files. If policy permits a local secret
file, read only the explicitly named key from the explicitly named file.PufferLib 3.0 supports both --wandb and --neptune; its sweep mode requires
one. Current 4.0 source exposes W&B but no Neptune CLI integration. In either
profile, require explicit logging opt-in and disclosure acknowledgment. The
bundled training planner enforces this without reading credential values:
python3 scripts/train_template.py \
--logger wandb \
--enable-external-logging \
--acknowledge-external-disclosure