Skip to main content

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

VariableDescription
PLUTO_API_KEYMaster switch — without it the hook never activates, even if other wandb env vars are set.
PLUTO_PROJECT or WANDB_PROJECTPluto project name. Falls back to WANDB_PROJECT so you don’t need to duplicate config.

Optional Environment Variables

VariableDescription
PLUTO_URL_APPApp endpoint for self-hosted instances
PLUTO_URL_APIAPI endpoint for self-hosted instances
PLUTO_URL_INGESTIngest endpoint for self-hosted instances
DISABLE_WANDB_LOGGINGSet 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

wandbpluto
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

wandbpluto
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.

Media Logging

wandbpluto 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

wandbpluto 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 featureReason
run.config.update() post-initCompat 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 registryNo Pluto equivalent.
wandb.log_code()No Pluto equivalent.
define_metric(), mark_preempting(), sweepsNo 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.