Skip to content

Latest commit

 

History

275 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LiteRunner

Tests codecov PyPI version PyPI platforms Total downloads
Made Using tsvikas/python-template GitHub Discussion PRs Welcome

Overview

Runner for generative models with local and W&B tracking.

Write a small Python script per model that declares params, outputs, and metrics. lite-runner handles the rest: CLI parsing, interactive prompts for missing values, subprocess execution, stdout/stderr capture, metric extraction, file uploads to W&B, and code snapshots for reproducibility.

Quick start

Create a run.py for your model:

#!/usr/bin/env -S uv run
# /// script
# dependencies = ["lite-runner"]
# ///
from lite_runner import Runner, Param, Metric

runner = Runner(
    command="python generate.py",
    params=[
        Param("prompt", help="Text prompt"),
        Param("seed", type="int", default=42),
        Param("output-path", value="$output/video.mp4", type="path-video"),
    ],
    metrics=[
        Metric("loss", pattern=r"loss=([\d.]+)"),
    ],
)

if __name__ == "__main__":
    runner.run()

Then run it (requires uv):

chmod +x run.py
./run.py --prompt "a cat walking"           # interactive TUI fills missing params
./run.py --prompt "a cat" --no-interactive  # non-interactive, fail if missing
./run.py --prompt "a cat" --dry-run         # print command, don't run
./run.py --seed=-                           # unset a param (omit from command)
./run.py --image - - -                      # unset a multi-value param

What it does

Each runner.run() call:

  1. Parses CLI args (all params are optional in argparse; missing ones trigger TUI prompts)
  2. Creates an output directory at ~/lite_runs/<project>/<timestamp>_<run_name>/
  3. Inits a W&B run and logs all params, git info, and host metadata
  4. Saves a code snapshot (git archive + dirty diff) as a W&B artifact
  5. Builds and runs the subprocess, streaming stdout/stderr to terminal and log files
  6. Extracts metrics from stdout via regex
  7. Uploads output files (videos, images, artifacts) to W&B
  8. Logs duration, exit code, and status to W&B summary

Param

Param("name")                               # basic string param
Param("seed", type="int", default=42)       # typed with default
Param("mode", choices=["fast", "quality"])  # select from choices
Param("verbose", type="bool")               # --verbose flag (store_true, always defaults to False)
Param("image", type="path-image")           # file input, uploaded to W&B before run
Param(
    "output-path",
    value="$output/video.mp4",              # fixed value, $output interpolated
    type="path-video",
)                                           # after the run, uploaded to W&B as a video
Param(
    "input-image",
    type=["path-image", "float", "float"],  # multi-value flag
    labels=["img", "start", "strength"],
)                                           # each part prompted separately in TUI

Type — controls parsing, casting, and file upload intent. All param values are logged to run.config. The path-* variants additionally upload the file at that path to W&B:

Type Parsed as File upload
"str" (default) str
"int" int
"float" float
"bool" flag
"path" str
"path-image" str as image
"path-video" str as video
"path-artifact" str as artifact
"path-text" str as text

"bool" params are special: they generate a --flag (no value), always default to False (any other default= is ignored), and cannot appear in multi-value type lists.

Other fields:

  • value= makes a param fixed (never prompted, not in CLI). Can be a callable (called at resolve time).
  • default= can be a callable (called at resolve time to compute the default)
  • flag= overrides the CLI flag name (default: --<name with hyphens>)
  • prompt=False skips interactive prompting (falls through to default). Requires a default=. The param still accepts CLI flags and is logged normally.
  • $output in value is replaced with the run's output directory
  • log_when= auto-inferred: "before" for inputs, "after" for $output paths
  • type=[...] gives per-element types for multi-value flags (nargs inferred from length)
  • Pass - on CLI to unset a param (omit it from the subprocess command). For single-value: --seed=-. For multi-value: --image - - - (one - per element). This mirrors typing - at the interactive TUI prompt.

Output

For files the model writes to uncontrolled locations:

Output("model_metadata.json", log_as="artifact", copy_to="$output/model_metadata.json")

Supports glob patterns and directory zipping:

Output("debug/**/*.png", log_as="image")                # upload each matched png
Output("debug/", log_as="image")                        # upload each file in directory
Output("debug/", log_as="zip")                          # zip entire directory, upload as artifact
Output("$output/frames/*.jpg", log_as="zip")            # zip glob matches into archive
Output("weights/", log_as="zip", name="model-weights")  # name= sets the W&B key (disambiguates zips)

Metric

Extract values from stdout:

Metric("loss", pattern=r"loss=([\d.]+)")
Metric("status", pattern=r"status: (\w+)", type="str")
Metric("steps_per_sec", pattern=r"steps/s=([\d.]+)", type="int")
Metric(
    "elapsed", pattern=r"elapsed: ([\d:.]+)", type="timedelta"
)  # [[HH:]MM:]SS[.ddd] → seconds

Last match wins. Patterns are matched against both stdout and stderr. Stored in wandb.run.summary.

Supported types: "float" (default), "int", "str", "timedelta".

Sweeps

Loop with override(). Runs are grouped in W&B for easy comparison:

runner = Runner(
    command="python gen.py",
    params=[...],
    run_group="lr-sweep",  # groups all runs together in W&B UI
)
for lr in [1e-3, 1e-4, 1e-5]:
    runner.override(learning_rate=lr).run(no_interactive=True)

Each call creates a separate W&B run, all grouped under the same group.

You can also update metadata per-run:

runner.override(seed=42).with_metadata(tags=["baseline"]).run()

Runner options

Runner(
    command="python gen.py",  # str or list[str] (list avoids shell splitting)
    params=[...],
    outputs=[...],
    metrics=[...],
    tags=["experiment-1"],    # W&B run tags
    env={
        "CUDA_VISIBLE_DEVICES": "0",
        "NOISY_VAR": None,
    },                        # set or unset env vars
    secret_env={
        "HF_TOKEN": "hf_xxx",
    },                        # like env, but redacted in logs / recorded config
    project="my-project",     # default: git repo name
    run_group="my-sweep",     # W&B run group for sweeps (None = no grouping)
)

Pipeline API

Each method returns a new Runner (immutable copies), so you can branch:

base = runner.parse_cli()    # parse sys.argv
r1 = base.override(seed=42)  # override params by name
r2 = base.override(seed=99)
r1.run()                     # auto-resolves defaults & prompts
r2.run()

Methods:

Method Description
parse_cli(argv) Parse CLI args (default: sys.argv[1:])
override(**kwargs) Set param values by name
with_metadata(project=, run_group=, tags=) Update W&B metadata
resolve_defaults() Apply defaults and fixed values
ask_user(no_interactive=) Prompt for missing values
run(...) Auto-calls any unapplied steps, then executes

run() accepts kwargs dry_run, min_free_space_gib, no_interactive, no_wandb, project, run_name as alternatives to CLI flags. It returns a RunResult with fields: output_dir, exit_code, duration, run_name, project, config, param_values, param_sources.

Built-in CLI flags

Flag Description
--dry-run Print command and exit
--min-free-space-gib N Minimum free disk space in GiB (default: 1.0)
--no-interactive Fail if required params missing
--no-wandb Skip W&B logging (still logs to JSON)
--run-name NAME Override W&B run name
--project NAME Override project name

What gets logged to W&B

Location Content
run.config["param/*"] All param values
run.config["param_source/*"] Where each param value came from (cli, default, fixed, override, prompt)
run.config["git/*"] commit, branch, repo, dirty
run.config["meta/*"] hostname, user, cwd, datetime, command, full_command, output_dir, env (secrets as ***)
run.summary exit_code, duration_seconds, status, metrics
Artifacts Log files, code snapshot, artifact-type outputs
Media Videos and images from path-* type params/outputs

Using with Claude Code

This repo is also a Claude Code plugin marketplace. Install the lite-runner skill so Claude Code writes idiomatic run.py scripts and drives sweeps correctly:

/plugin marketplace add moonmath-ai/LiteRunner
/plugin install lite-runner@lite-runner-marketplace

See plugins/lite-runner/ for the plugin source.

Contributing

Interested in contributing? See CONTRIBUTING.md for development setup and guidelines.

About

MLOps-style tracking without touching the code.

Resources

Contributing

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages