Skip to main content

Zero-setup ML experiment tracker with live dashboard, anomaly detection, and hyperparameter suggestions

Project description

trainlog

Track ML experiments in 2 lines of code. No server. No account. No config.

CI PyPI Python License: MIT Stars

You're running a training loop. You want to know which hyperparameters worked best. You don't want to:

  • Set up a tracking server
  • Create an account on any service
  • Write to a cloud API
  • Configure environment variables
  • Install 47 dependencies

trainlog is the answer. Install it, wrap your loop, open a beautiful local dashboard. Done.


Quickstart (5 steps)

1. Install

pip install mltrackr

This installs the trainlog command and import trainlog Python package.

2. Generate a ready-to-run example

python -m trainlog.cli init --framework plain -o demo.py

On most systems trainlog init works directly. If not, use python -m trainlog.cli instead.

3. Run the demo (creates 6 fake training runs)

python demo.py

4. Inspect results in the terminal

python -m trainlog.cli list
python -m trainlog.cli best accuracy
python -m trainlog.cli suggest accuracy

5. Open the visual dashboard

python -m trainlog.cli ui

Then open http://localhost:7000 in your browser. Press Ctrl+C to stop.


Your first real experiment

import trainlog

with trainlog.run("resnet-baseline", tags=["cv", "baseline"]):
    trainlog.log(lr=1e-3, batch_size=64, optimizer="adam")

    for epoch in range(50):
        loss, acc = train_one_epoch(model, dataloader)
        trainlog.log(loss=loss, accuracy=acc, epoch=epoch)

    trainlog.note("Solid baseline - try lr=5e-4 next")
# If 'trainlog' works directly on your system:
trainlog ui
trainlog list
trainlog best accuracy
trainlog suggest accuracy
trainlog report

# If not (e.g. Windows), use:
python -m trainlog.cli ui
python -m trainlog.cli list
python -m trainlog.cli best accuracy

Everything is saved locally in ~/.trainlog/experiments.db. A single SQLite file. Copy it, back it up, open it in any SQLite browser.


Why trainlog?

The real problem: you're hacking on a model, you want to log some metrics, but setting up MLflow takes 15 minutes and W&B wants you to create an account and send your data to the cloud. So you end up writing metrics to a text file or just... not tracking anything. Then you forget which hyperparameters worked. Then you run the same failed experiment again.

trainlog is the experiment tracker that's actually available when you need it.

trainlog MLflow Weights & Biases
Setup time 5 seconds ~15 minutes ~5 minutes
Requires account ❌ No ❌ No ✅ Yes
Requires running server ❌ No ✅ Yes ❌ No (cloud)
Works offline ✅ Always ⚠️ Partial ❌ No
Data stays local ✅ Always ✅ Yes ❌ No
Live anomaly detection ✅ Built-in ❌ No ⚠️ Paid
Hyperparameter suggestions ✅ Built-in ❌ No ⚠️ Paid
Auto-generated reports ✅ Built-in ❌ No ❌ No
Free forever ✅ MIT ✅ Apache ⚠️ Usage limits

Features you'll actually use

✅ Zero-friction tracking

Wrap any loop. Log any value. Works with every framework.

import trainlog

with trainlog.run("gpt-finetune", tags=["nlp", "v3"]):
    trainlog.log(lr=2e-5, epochs=3, model="gpt2")
    for step, batch in enumerate(dataloader):
        loss = model.train_step(batch)
        trainlog.log(loss=loss.item(), step=step)

✅ Beautiful live dashboard

trainlog ui

Opens at http://localhost:7000 — a fast, dark-mode single-page app with:

  • Searchable run list with inline sparkline charts in the sidebar
  • Trend indicators (↑ ↓) showing whether each metric is improving
  • Side-by-side comparison of any runs you select (best value highlighted)
  • Auto-generated time-series charts with gradient fills
  • Metric progress bars showing where the latest value sits in its historical range
  • Global statistics view — success rate, most-logged metrics, run timeline
  • Auto-refresh every 5 seconds — open while training, watch it update

✅ Live anomaly detection — catch bad runs early

trainlog.configure_watch(nan_check=True, divergence_window=5, plateau_window=15)

with trainlog.run("training"):
    for epoch in range(100):
        trainlog.log(loss=compute_loss())
        # Automatically warns if: loss → NaN, loss diverges for 5 epochs,
        # loss plateaus for 15 epochs (and suggests adjusting LR)

Stop wasting GPU hours on runs that are already failing.

✅ Hyperparameter suggestions

trainlog suggest accuracy

Analyzes your run history and tells you which hyperparameter values are statistically correlated with better results. No black box — plain English insights like:

Best config: lr=0.001 → avg accuracy 0.943 (vs 0.871 for other values, +8.2%)
Next experiment: try batch_size=128 — larger batches correlated with +5.1% accuracy

✅ Auto-generated experiment reports

trainlog report --output results.md

Generates a thesis-ready markdown report with:

  • Summary statistics (total runs, completion rate, best configurations)
  • Chronological experiment timeline
  • Key findings (computed automatically)
  • Notes from all your runs
  • Optional AI narrative: trainlog report --ai (uses local Ollama, no API keys)

✅ Generate a ready-to-run example

trainlog init                           # plain Python example
trainlog init --framework pytorch       # PyTorch training loop
trainlog init --framework sklearn       # scikit-learn grid search
trainlog init --framework keras         # Keras callback

Generates a complete working script you can run immediately.

✅ Works with every framework

Framework How
PyTorch trainlog.log(loss=loss.item(), acc=acc) inside the training loop
scikit-learn trainlog.log(**params, cv_score=score) in your hyperparam loop
Keras / TF One-file TrainlogCallback for model.fit()
HuggingFace Custom TrainerCallback — see examples/huggingface_example.py
XGBoost / LightGBM Log in the eval callback
JAX / Flax Log at end of each training step
Plain Python Anything that produces a number

Full API reference

Python API

import trainlog

# ── Tracking ──────────────────────────────────────────────────────────────────
with trainlog.run("name", tags=["tag1", "tag2"]) as run_id:
    trainlog.log(accuracy=0.95, loss=0.05)          # log any key-value pairs
    trainlog.note("Cosine LR schedule helped a lot") # attach plain-text notes

trainlog.tag(run_id, "production")       # add tags after the fact
trainlog.tag("experiment-name", "best")  # also works by name

# ── Querying ──────────────────────────────────────────────────────────────────
runs = trainlog.get_runs()                           # all runs, newest first
best = trainlog.get_best_run("accuracy")             # highest final value
best_low = trainlog.get_best_run("loss", mode="min") # lowest final value
cmp = trainlog.compare_runs(1, 2, 3)                 # list of run dicts

# ── Anomaly detection ─────────────────────────────────────────────────────────
trainlog.configure_watch(
    nan_check=True,           # warn on NaN/Inf values
    divergence_window=5,      # warn if metric diverges for N steps
    plateau_window=15,        # warn if metric plateaus for N steps
    enabled=True,
)

# Or temporarily with a context manager:
with trainlog.watch(divergence_window=3):
    # stricter watch for this block
    trainlog.log(loss=0.5)

# ── Export & analysis ─────────────────────────────────────────────────────────
trainlog.export_csv("results.csv")
trainlog.export_json("results.json")
trainlog.generate_report("report.md", use_ollama=False)
suggestions = trainlog.suggest("accuracy", mode="max", top_n=3)
trainlog.clear_all()  # deletes everything (irreversible)

CLI reference

# Dashboard
trainlog ui                             # open at localhost:7000
trainlog ui --port 8080 --no-browser    # custom port, no auto-open

# Inspect runs
trainlog list                           # rich table, newest first
trainlog list --limit 50
trainlog compare 1 2 3                  # side-by-side metric comparison
trainlog best accuracy                  # best run for a metric
trainlog best loss --mode min

# Annotate
trainlog tag 42 production tuned        # add tags to run #42
trainlog note 42 "Try cosine annealing" # add note to run #42

# Analyse
trainlog stats                          # aggregate statistics
trainlog suggest accuracy               # hyperparameter recommendations
trainlog suggest loss --mode min --top 5

# Generate
trainlog report                         # write report.md
trainlog report -o results.md --ai      # with Ollama AI narrative
trainlog init --framework pytorch       # generate example script

# Export / clean
trainlog export --format csv -o data.csv
trainlog export --format json -o data.json
trainlog clear                          # delete all (asks confirmation)

How it works

  • SQLite~/.trainlog/experiments.db. One file. No server. Inspect it with any SQLite browser. Back it up with cp.
  • Flask — the dashboard is a local Flask server. Vanilla JS, Chart.js, zero npm, zero build step.
  • Thread-local state — each training job in its own thread gets an isolated run context. Concurrent experiments just work.
  • Git-aware — captures the current commit hash via git rev-parse HEAD. Silently skipped outside a git repo.
  • Watch hooks — anomaly detection runs inside every log() call. Zero external services, works offline.

Quickstart with examples

trainlog init --framework pytorch -o train.py
python train.py
trainlog ui

That's the whole flow. Five commands. Zero config.


Roadmap

Done ✅

  • Live anomaly detection (configure_watch)
  • Auto-generated experiment reports (trainlog report, Ollama support)
  • Hyperparameter suggestions (trainlog suggest)
  • Quick-start example generator (trainlog init)
  • Sparkline charts in sidebar with trend indicators
  • Metric progress bars and trend arrows in detail view
  • Framework examples: PyTorch, scikit-learn, Keras, HuggingFace

Coming up

  • trainlog.log_artifact("model.pt") — save file paths alongside metrics
  • Native PyTorch TrainlogCallback (pip-installable plugin)
  • VS Code extension — inline run summary on hover
  • trainlog serve — shareable read-only dashboard URL (ngrok/localtunnel)
  • Team sync via shared git-tracked SQLite
  • Slack / Discord webhook on run completion

Have an idea? Open a feature request — or submit a PR.


Contributing

See CONTRIBUTING.md. TL;DR: pip install -e ., make your change, open a PR.

All contributions welcome — typos, docs, features, bug fixes.


License

MIT — use it however you want, forever.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mltrackr-0.3.0.tar.gz (35.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mltrackr-0.3.0-py3-none-any.whl (37.4 kB view details)

Uploaded Python 3

File details

Details for the file mltrackr-0.3.0.tar.gz.

File metadata

  • Download URL: mltrackr-0.3.0.tar.gz
  • Upload date:
  • Size: 35.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for mltrackr-0.3.0.tar.gz
Algorithm Hash digest
SHA256 2e061f92ef954c3423c715e1dfdade29bb9fdba8284139b5921aec82c63faad3
MD5 1338f80f5eecd5cfffd6fcf3d2324ff3
BLAKE2b-256 fe11c44cc2dfaf0be8108e5633168b8ce266db035e713f91bf081d1adcfb33cf

See more details on using hashes here.

File details

Details for the file mltrackr-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mltrackr-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 37.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for mltrackr-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e92867744e1ecc6493c30a01805b7c4b0cb45838ac8e2cab18a6e538cd6a455
MD5 1218f13fe6c833f2b62f4773ed82e251
BLAKE2b-256 9d9ddba56eeb38558f7b695415b6947891999d9aa75319212691571450bfb7d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page