How to Use Soup's TUI for Interactive Training Monitoring: A Complete Guide

Soup's Textual-based terminal UI lets you watch fine-tuning runs in real time with live metrics, automatic refresh, and keyboard-driven navigation.

The Soup CLI includes an optional TUI (Terminal User Interface) for monitoring distributed training jobs without leaving your terminal. Unlike monolithic ML tools that force heavy dependencies, Soup keeps the TUI truly optional—textual is only imported when you run soup tui, ensuring the core CLI stays fast on resource-constrained machines.

Architecture and Design Philosophy

Soup's TUI follows a lazy-loading architecture to minimize overhead. The implementation in src/soup_cli/tui_app.py wraps the textual import in a try/except block; if the library is absent, the soup tui command gracefully degrades to an installation hint rather than crashing.

The UI consumes data through the ExperimentTracker class in src/soup_cli/experiment/tracker.py. This SQLite-backed tracker maintains run metadata, loss curves, step counts, and cost estimates. The TUI polls this database every refresh_secs (default 1 second) to deliver a live dashboard experience.

Installing and Launching the TUI

Step 1: Install the Optional Dependency

pip install textual

This one-time installation enables the full interactive interface.

Step 2: Start the Monitoring Dashboard

soup tui

The command entry point lives in src/soup_cli/commands/tui.py, which handles the optional dependency check before handing control to SoupTuiApp.

Once launched, SoupTuiApp (defined at line 75 of src/soup_cli/tui_app.py) renders a two-pane layout:

  • Left pane: A DataTable listing recent runs with keys, status, and timestamps
  • Right pane: A Static panel showing detailed metrics for the selected run

Keyboard Controls

Key Action
↑ / ↓ Navigate runs list
Enter Select run and display details
r Force immediate refresh (_reload re-queries the DB)
q Quit the UI

The automatic refresh runs every second by default, giving you real-time visibility into loss convergence and training progress.

Customizing Refresh Behavior

For faster or slower polling, launch the TUI programmatically:

from soup_cli.tui_app import SoupTuiApp

if __name__ == "__main__":
    # Refresh every 0.5 seconds, show last 100 runs

    SoupTuiApp(refresh_secs=0.5, run_limit=100).run()

The refresh_secs and run_limit parameters control polling frequency and table depth respectively.

Data Flow and Rendering Pipeline

The TUI's rendering pipeline involves three key functions in src/soup_cli/tui_app.py:

  1. build_runs_table_rows (line 36) – Formats SQLite rows into table-compatible tuples
  2. build_run_detail (line 54) – Renders expanded metrics, loss curves, and cost estimates for the selected run
  3. _reload – Background method that re-queries ExperimentTracker and triggers UI updates

This architecture decouples the visual layer from data persistence, letting you monitor runs even while trainings execute in separate processes or on remote nodes.

Troubleshooting Common Issues

"textual not found" on Launch

The CLI intentionally fails soft. If you see an install hint, run:

pip install textual

The check in src/soup_cli/commands/tui.py prevents import errors from breaking the base Soup installation.

Stale Data or Missing Runs

Press r to force a refresh. The _reload method pulls directly from src/soup_cli/experiment/tracker.py, so any runs committed to the SQLite database will appear immediately.

Summary

  • Lazy imports keep Soup's core CLI lightweight—textual loads only for soup tui
  • Two-pane layout in SoupTuiApp displays runs and metrics side-by-side
  • Automatic polling refreshes every second via _reload calling ExperimentTracker
  • Keyboard-driven navigation with q, r, and arrow keys
  • Programmatic control through SoupTuiApp(refresh_secs=..., run_limit=...)

Frequently Asked Questions

What happens if Textual isn't installed?

The soup tui command detects the missing dependency in src/soup_cli/commands/tui.py and prints an installation hint without crashing. The rest of the Soup CLI remains fully functional.

How does the TUI get real-time training data?

It polls the SQLite experiment database through ExperimentTracker (src/soup_cli/experiment/tracker.py) every refresh_secs. This design works across processes—training jobs write to the DB while the TUI reads.

Can I adjust the refresh rate?

Yes. Pass refresh_secs when constructing SoupTuiApp, or use the default 1-second interval for standard monitoring.

Why is the TUI implemented as a separate command?

The split between soup (core CLI) and soup tui (interactive UI) follows Python packaging best practices. Heavy terminal libraries are isolated to an optional dependency, keeping installation lean on headless servers.

Where is the run detail formatting handled?

The build_run_detail function at line 54 of src/soup_cli/tui_app.py assembles metrics, loss curves, step counts, and estimated cost into the right-hand panel view.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →