Documentation Index
Fetch the complete documentation index at: https://docs.trainy.ai/llms.txt
Use this file to discover all available pages before exploring further.
The wandb compatibility shim is in public preview. Its interface and behavior may change as we iterate. Expect sharp edges.
We’ve created a Weights & Biases compatibility layer that enables dual-logging to both wandb and Pluto simultaneously. This allows you to gradually migrate your experiment tracking without touching existing training scripts.
Quick Start
Install Pluto and authenticate. Use either pluto login (stores a token in your system keyring — recommended for interactive workstations) or export PLUTO_API_KEY (recommended for CI / containers / non-interactive jobs):
pip install pluto-ml
# Pick one:
pluto login # interactive — stores token in keyring
# export PLUTO_API_KEY=mlpi_xxx # or set the env var
Then run any existing wandb script — dual-logging activates automatically:
import wandb
# Project that the run is recorded to
project = "my-awesome-project"
# Dictionary with hyperparameters
config = {
'epochs': 10,
'lr': 0.01,
}
with wandb.init(project=project, config=config) as run:
# Training code here
# Log values to W&B with run.log()
run.log({"accuracy": 0.9, "loss": 0.1})
That’s it. Every wandb.log() call now also logs to Pluto. No PLUTO_PROJECT env var needed — the shim picks up the project= kwarg from wandb.init().
Configuration
Authentication
Either of the following is sufficient — the hook checks both:
| Source | When to use |
|---|
pluto login | Interactive workstations. Stores a token in your system keyring; persists across shells. |
PLUTO_API_KEY env var | CI, containers, or any non-interactive context. In DISABLE_WANDB_LOGGING=true mode, WANDB_API_KEY may be reused as a Pluto token. |
If neither is present, the shim logs a one-time warning pointing at pluto login / PLUTO_API_KEY and wandb runs unmodified.
Project Name
Resolved in this order (first match wins):
| Source | Notes |
|---|
PLUTO_PROJECT env var | Highest precedence. |
project= kwarg to wandb.init(...) | Picked up automatically — no extra config needed. |
WANDB_PROJECT env var | Falls back to wandb’s own project env so you don’t need to duplicate config. |
run.project attribute on the wandb run | Last-resort fallback. |
Optional Environment Variables
| Variable | Description |
|---|
PLUTO_URL_APP | App endpoint for self-hosted instances |
PLUTO_URL_API | API endpoint for self-hosted instances |
PLUTO_URL_INGEST | Ingest endpoint for self-hosted instances |
DISABLE_WANDB_LOGGING | Set to true to skip wandb entirely and only log to Pluto (post-sunset mode, see below). |
Supported Operations
The compatibility layer monkey-patches wandb.init() so the returned Run object dual-logs every supported call. Unsupported methods still work normally on wandb via attribute fallthrough — they just don’t dual-log to Pluto.
Initialization
| wandb | pluto |
|---|
wandb.init(project="my-project", config=cfg) | pluto.init(project="my-project", config=cfg) |
wandb.init(fork_from=...) | pluto.init(fork_run_id=..., fork_step=...) |
run.tags = ["experiment-v1"] | run.add_tags(["experiment-v1"]) |
wandb.init() completes fully before any Pluto code runs. pluto.init() runs in a thread with a 10s timeout — if the Pluto server is unreachable, the run silently falls back to wandb-only. Tag assignments on the wandb run sync to Pluto on every assignment.
Metric Logging
| wandb | pluto |
|---|
wandb.log({"train/loss": 0.5}) | run.log({"train/loss": 0.5}) |
wandb.log({"train/loss": 0.5}, step=100) | run.log({"train/loss": 0.5}, step=100) |
Numeric values, lists of numbers, and the wandb media types below are forwarded to Pluto. The data dict you pass into wandb.log() is never mutated.
| wandb | pluto equivalent |
|---|
wandb.Image(...) | pluto.Image(...) |
wandb.Histogram(...) | pluto.Histogram(...) |
wandb.Audio(...) | pluto.Audio(...) |
wandb.Video(...) | pluto.Video(...) |
wandb.Table(...) | Pluto table file |
Lists of media at the same step (wandb.log({"gens": [wandb.Image(a), wandb.Image(b)]})) are forwarded as a multi-sample group. The Pluto UI renders these with a per-card ◀ i / N ▶ nav — see Images: Multi-Sample Logging.
Artifacts and Saved Files
| wandb | pluto equivalent |
|---|
wandb.log_artifact(art) | Each local file in the artifact → pluto.Artifact under artifacts/{art_name}/{entry_path} |
wandb.save(path_or_glob) | Each matched file → pluto.Artifact under save/{basename} |
Reference entries (S3 URLs, etc.) inside wandb.Artifact are skipped — Pluto stores files directly. Artifact versions and aliases are not translated; Pluto has no equivalent.
wandb.finish() triggers pluto.finish() as well. Pluto’s teardown has a 5s timeout so it never blocks wandb’s cleanup. If pluto.init() failed earlier, the run stays wandb-only and finish() is a no-op on the Pluto side.
Not Supported
These wandb features run normally on wandb but do not dual-log to Pluto:
| wandb feature | Reason |
|---|
run.config.update() post-init | Compat layer captures config only at wandb.init(). Call run.update_config() directly on the Pluto run for in-run updates. |
run.watch() (gradient tracking) | No Pluto equivalent. |
wandb.log_model() / model registry | No Pluto equivalent. |
wandb.log_code() | No Pluto equivalent. |
define_metric(), mark_preempting(), sweeps | No Pluto equivalent. |
Post-Sunset Mode
When you’re ready to stop sending data to wandb, set the kill switch:
export DISABLE_WANDB_LOGGING=true
In disabled mode, WANDB_API_KEY can also hold a Pluto API token, so a user fully migrating from wandb can swap a single env var value:
export WANDB_API_KEY=mlpi_xxx # Pluto token in the existing var
export WANDB_PROJECT=my-project
export DISABLE_WANDB_LOGGING=true
python train.py
All wandb.* calls are intercepted and redirected to Pluto without any code changes.