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.
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 set PLUTO_API_KEY. If you already have WANDB_PROJECT set in your environment, dual-logging activates automatically. No code changes needed.
pip install pluto-ml
export PLUTO_API_KEY=mlpi_xxx
# Existing training script — no changes
python train.py
That’s it. Every wandb.log() call now also logs to Pluto.
Configuration
Required Environment Variables
| Variable | Description |
|---|
PLUTO_API_KEY | Master switch — without it the hook never activates, even if other wandb env vars are set. |
PLUTO_PROJECT or WANDB_PROJECT | Pluto project name. Falls back to WANDB_PROJECT so you don’t need to duplicate config. |
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.
Finish
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.