Skip to main content

GoodSeed

ML experiment tracker. Logs metrics and configs to local SQLite files, serves them via a built-in HTTP server, and visualizes them in the browser.

Full documentation at docs.goodseed.ai.

Install

pip install goodseed

Python 3.9+ required.

For development:

uv sync --extra dev

Quick Start

Log metrics and configs from a training script:

import goodseed

run = goodseed.Run(name="my-experiment", tags=["bert"])

# Log configs (single values)
run["learning_rate"] = 0.001
run["batch_size"] = 32

# Log metrics (series of values)
for epoch in range(100):
    loss = train_step()
    run["train/loss"].log(loss, step=epoch)

run.close()

Custom step values:

run["metric"].log(value=acc, step=i)

step is required for series logging via run["path"].log(...).

Batch logging methods are also available:

run.log_configs({"learning_rate": 0.001, "batch_size": 32})
run.log_metrics({"loss": loss, "acc": acc}, step=step)

Your data is saved to a local SQLite file. You can also use with goodseed.Run(...) as run: to close the run automatically. Goodseed also registers best-effort per-run atexit cleanup, but calling run.close() (or using with) is still the recommended way to guarantee upload completion.

Storage Modes

The storage parameter controls where data is stored:

  • "cloud" (default) — local SQLite plus background sync to the remote API.
  • "local" — local SQLite only, no remote sync.
  • "disabled" — no storage; all writes are silent no-ops.

Cloud storage syncs data in a background thread while your training runs. Set the GOODSEED_API_KEY environment variable and use workspace/project format for the project name:

import goodseed

run = goodseed.Run(project="my-workspace/my-project", name="experiment-1")
run["train/loss"].log(0.5, step=0)
run.close()  # blocks until all data is uploaded

For local-only storage (no remote sync):

run = goodseed.Run(storage="local")

You can also set the mode via the GOODSEED_STORAGE environment variable.

Read Data from Server

run = goodseed.Run(project="my-workspace/my-project", run_id="bold-falcon", read_only=True)
data = run.get_metric_data("train/loss")
configs = run.get_configs()

Resume a run

run = goodseed.Run(resume_run_id="bold-falcon")
run["train/loss"].log(0.3, step=123)
run["eval/f1"] = 0.85
run.close()

Monitoring

By default, goodseed automatically captures:

  • stdout / stderr — every print() and warning is logged
  • Tracebacks — captured on unhandled exceptions (status set to failed)
  • CPU & memory — via psutil (installed with goodseed)
  • GPU — NVIDIA (via nvidia-smi) and AMD (via rocm-smi), no pip dependency

Disable any of these with:

run = goodseed.Run(
    capture_stdout=False,
    capture_stderr=False,
    capture_hardware_metrics=False,
    capture_traceback=False,
)

Then view your runs:

goodseed serve

Open the printed link in your browser to see your runs, metrics, and configs.

Configuration

Variable Description
GOODSEED_HOME Data directory (default: ~/.goodseed)
GOODSEED_PROJECT Default project name (default: default)
GOODSEED_RUN_ID Default run ID (overridden by run_id argument)
GOODSEED_API_KEY API key for cloud storage
GOODSEED_STORAGE Storage mode: disabled, local, or cloud (default: cloud)

Git Tracking

By default, Run() auto-tracks Git metadata from the current repository:

  • dirty state
  • source_code/diff (index vs HEAD)
  • last commit message, ID, author, and date
  • current branch
  • remotes
  • source_code/diff_upstream_<sha> when HEAD differs from the remote tracking branch

Specify a custom repository path:

import goodseed

run = goodseed.Run(git_ref=goodseed.GitRef(repository_path="/path/to/repo"))

Disable Git tracking:

import goodseed

run = goodseed.Run(git_ref=False)
# or: run = goodseed.Run(git_ref=goodseed.GitRef.DISABLED)

CLI

goodseed                   # Start the server (default command)
goodseed serve [dir]       # Start the server, optionally from a specific directory
goodseed serve --port 9000 # Use a custom port
goodseed list              # List projects
goodseed list -p default   # List runs in a project
goodseed upload -p <workspace/project> --run-id <run_id>  # Upload one run
goodseed upload -p <workspace/project>                    # Upload all runs

Tests

uv sync --extra dev
uv run pytest tests/ -v

See DOCS.md for architecture details and API reference.

Beta Notice

GoodSeed is currently in beta. We may introduce breaking changes as we iterate on the product.

In particular, the local SQLite schema and parts of the Python/CLI interface may change in future releases. Depending on the change, upgrading could require migrating or recreating existing local GoodSeed data files (stored under ~/.goodseed by default).

Feedback is very welcome while we stabilize the API. Please open issues with bug reports or feature requests.

Release files for goodseed 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for goodseed 0.4.0
File Size Uploaded
goodseed-0.4.0.tar.gz 49.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for goodseed 0.4.0
File Interpreter ABI Platform
goodseed-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.8 kB

Release files / goodseed-0.4.0.tar.gz

Download URL goodseed-0.4.0.tar.gz
Size 49.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a72a3654afc3b479d5868bb80c194e8402899a057823446840f481ad8d302ef6
BLAKE2b-256 checksum
How to use checksums
b70bd96fa08f4930cc563c0fc8e57af47c706f543035e24621ed3451b9d2b9eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / goodseed-0.4.0-py3-none-any.whl

Download URL goodseed-0.4.0-py3-none-any.whl
Size 52.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ccac06be0d3b251828fab69e32b82e4e649573e37fe3f17c842ec21e3f1ac15c
BLAKE2b-256 checksum
How to use checksums
41f843160792c584e7d29da61c000b10a70550097bcf7f3e80882531b613e207
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page