Skip to main content

A visual, Unreal-Blueprints-style node-graph editor for building and launching ML training runs.

Project description

ModuLearn

A visual, Unreal-Blueprints-style node-graph editor for building and launching machine-learning training runs. Drop Dataset → Model → Train nodes on a canvas, wire hyperparameters, loss and feature transforms into them, hit ▶ Train, and watch the learning curve live on the graph. No forms, no drift between the UI and the code it runs.

ModuLearn is a working name — you assemble training runs from modular nodes and learn from the live curve. Rename the package/repo freely; nothing depends on the name.

Why

Most training UIs are flat forms that slowly rot out of sync with the code behind them. ModuLearn inverts that: your Python is the single source of truth. You declare what you can train once, in a Registry, and the entire editor — palette, typed wiring rules, live validation, launch — is generated from it. Wire something the backend can't accept and it simply won't connect.

Install

pip install -e .          # fastapi + uvicorn + pydantic
modulearn demo            # serve the bundled editor at http://localhost:8000

modulearn demo is a complete, dependency-free editor (its "trainer" is a toy loss curve) so you can click around immediately. Once you've built your own app, serve it the same way:

modulearn run myproject.py        # serves the `app` you built with create_app
modulearn run myproject.py:editor # ...or a differently-named app / factory
modulearn --help

Swap on_train for your real training loop and nothing else changes. (The equivalent source file lives at examples/quickstart.py if you'd rather run it directly with python.)

The whole integration is two things

from modulearn import Registry, Param, create_app

reg = Registry()

reg.add_dataset("iris", title="Iris", kind="tabular",
                features=[...], targets=["species"])
reg.add_model("mlp", title="MLP", requires_kind="tabular",
              params=[Param("hidden", "hidden layers", "int_list", [64, 32])])
reg.add_hyperparameter("lr", label="learning rate", default=1e-3, min=1e-6, max=1)
reg.add_loss([Param("loss", "kind", "enum", "mse", choices=["mse", "cross_entropy"])])

def on_train(compiled, reporter):
    # compiled.dataset, .model, .model_params, .hyperparameters, .loss_params, .transforms
    # compiled.check_shape(X, y)   # optional: fail early if a loaded array's shape drifts
    reporter.state(epochs=100)
    for e in range(100):
        reporter.metric(epoch=e, train=..., val=...)   # drives the live chart
        reporter.state(epoch=e, best_val=...)
    reporter.state(phase="done", test_score=...)

app = create_app(reg, on_train, title="My Project")
  1. A Registry — declare datasets, models, hyperparameters, a loss, and optional feature transforms. Each hyperparameter you add automatically grows a matching, type-checked input on the Train sink.
  2. on_train(compiled, reporter) — your training loop. compiled is a fully-validated CompiledGraph; reporter publishes progress the editor polls (see the state contract below).

How it fits together

 registry.py   ── you declare nodes ──►  catalog (GET /api/nodes)
      │                                        │
      ▼                                        ▼
 compiler.py   ◄── canvas JSON ────────  static/ (custom canvas engine)
      │  type-checks every wire, runs semantic checks
      ▼
 CompiledGraph ──►  your on_train(compiled, reporter)  ──►  runs/<id>/{state,metrics}.json
                                                                   │
                                                    editor polls ◄─┘  (live panel + chart)
  • Typed ports. Links carry a family (dataset, model, loss, run) or a field-specific scalar subtype (scalar/lr), so a learning-rate value fits the lr input and never epochs — enforced both client-side and in the compiler.
  • All-or-nothing compile. compile_graph collects every structural, type and semantic error and raises them together, so the UI flags all bad wires at once.
  • Composable transforms. Chain Dataset → Transform → … → Model; the compiler walks the chain into compiled.transforms. Mark a transform live=False to show it in the palette but have the compiler refuse it until your backend is ready.
  • Guarded at the boundary. Hyperparameters are range-checked at compile against the min/max you declared, so on_train never sees a value the UI called impossible (epochs=0, a negative lr). And compiled.check_shape(X, y) fails early — naming the dataset — when a loaded array doesn't match its declared features/targets, instead of dying cryptically deep inside your model.
  • Stateless live window. Training runs in a background thread and persists to runs/<id>/. Closing the browser never stops a run; reopening shows true state.

The state contract

Your on_train reports through reporter, and the editor reads these keys:

call keys the UI understands
reporter.state(**kw) phase (running/done/error), epoch, epochs, best_val, test_score, error
reporter.metric(**row) epoch, train, val → the live learning curve

Anything else you write is stored and returned by the API, just not charted.

If your on_train raises, ModuLearn catches it and records phase="error" with a one-line error summary (led by the exception type) and the full traceback — both render right in the editor panel, so a crashing loader or training loop is visible on the canvas instead of hanging or failing silently. The traceback also prints to the server log.

Editor niceties

  • Searchable palette with collapsible category dropdowns; ⌘K / / to focus, Enter to drop the first match.
  • Wires colored by type, with flowing pulses that speed up on the edges feeding a running Train node; ports glow while you drag a compatible connection.
  • Canvas persists to localStorage; reload/fork any past run's blueprint.
  • All motion respects prefers-reduced-motion.

Layout

modulearn/
  registry.py    the declarative surface your app fills in
  compiler.py    graph JSON -> validated CompiledGraph (pure, unit-testable)
  server.py      create_app(): FastAPI factory + background job runner
  cli.py         the `modulearn` command (demo / run)
  demo.py        the app `modulearn demo` serves
  static/        graph.html, graph.js (app), graph-engine.js (canvas engine)
examples/
  quickstart.py  a complete, dependency-free editor

License

MIT (see LICENSE). The canvas node-graph engine (static/graph-engine.js) is our own, built from scratch — no third-party graph library.

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

modulearn-0.2.0.tar.gz (66.1 kB view details)

Uploaded Source

Built Distribution

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

modulearn-0.2.0-py3-none-any.whl (46.5 kB view details)

Uploaded Python 3

File details

Details for the file modulearn-0.2.0.tar.gz.

File metadata

  • Download URL: modulearn-0.2.0.tar.gz
  • Upload date:
  • Size: 66.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for modulearn-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0950ef691f36e24b088c91177131618440432c3bf38b8870ab040c5f424db18b
MD5 b149e1c8fff4f1118450b2bfeb40994a
BLAKE2b-256 c9017156c1c77f4d190c7c02db65c830191c4c53c1b38b4339a8d5319e5ecffb

See more details on using hashes here.

File details

Details for the file modulearn-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: modulearn-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 46.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for modulearn-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0409f52b2979cc83ca52e1a2ef7230330740d7b57e197c722e4ac66efdb0370a
MD5 4e0c4054b99922352a958f03b030f5d6
BLAKE2b-256 142daca2c07f7a153c81867785469ae3c739b8eddc8ba1766b5cbbd9acb3f7b4

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