Guide Profiles Model Configs Container Lifecycle Using the TUI Dev Builds

Using the TUI

The TUI is llmux's default interface — a single Textual dashboard that manages vLLM and llama.cpp profiles side by side. Everything the headless CLI does is available here as keyboard-driven screens and forms.

Launching

llmux          # no arguments → launches the TUI
llmux tui      # explicit

Running llmux with no subcommand drops you straight into the unified dashboard.

Language (English / Korean)

The TUI is bilingual. It follows your system locale by default (a ko_* LANG/LC_ALL gives Korean, anything else English). Force one with LLMUX_LANG=en llmux or LLMUX_LANG=ko llmux. Table column headers and engine-flag names stay in English in both modes.

The dashboard

The dashboard is one DataTable showing every profile from both backends. Running containers float to the top so the active workload is always visible without scrolling; within the running / stopped groups, rows stay sorted by (backend, name).

┌ llmux ─ vLLM + llama.cpp ───────────────────────────────────────────────────────────────────┐
│  vLLM 1/2  ·  llama.cpp 0/1  ·  Enter = actions                   │
├─────────────────────────────────────────────────────────────────────┤
│ Status      Backend    Profile      Port   tok/s  Model        Detail  │
│ ● running   vLLM       qwen3-8b     8000   62.4   Qwen3-8B     TP=1    │
│ ○ stopped   llama.cpp  gemma-3-4b   8080   —      gemma-3-4b   —       │
│ ○ stopped   vLLM       qwen3-0-6b   8001   —      Qwen3-0.6B   —       │
└─────────────────────────────────────────────────────────────────────┘
 GPU0 ████████░░░░ 64%  12.1/24GB
 🔍  Estimate HF model memory (press m then type, Enter to run)

A status bar shows running / total counts per backend. The tok/s column shows live generation throughput for each running model, polled from its /metrics endpoint every 3 seconds (see llmux stats). A GPU bar below the table auto-refreshes every few seconds, and the table itself re-scans every 5 seconds. The memory-estimator search row is hidden by default to keep the dashboard compact — press m to reveal it (and Esc to hide it again).

Keyboard shortcuts

Move the cursor with / , then act on the selected row.

Dashboard

KeyActionNotes
EnterOpen the action menu for the selected profileContext-aware (running vs. stopped)
nNew profileOpens the backend picker, then Quick Setup
mMemory estimatorToggles the HF model search row (hidden by default); Esc hides it
CConfigsOpens the config list for the selected row's backend — new, edit, clone, rename, delete
sSystem infoFor the selected row's backend (or asks)
tTerminal monitorThe v monitor in a plain terminal (suspends the TUI); q returns
rRefreshRe-scan all profiles and container status
qQuit
uStart containerPower-user shortcut (hidden from footer)
dStop containerPower-user shortcut
lView logsWorks for stopped containers too (last-run logs)
vLive monitorbtop-style system view — GPUs always, plus every running model (throughput/KV graphs, cache-hit, latency percentiles, PCIe)
eEdit profilePower-user shortcut
cEdit configPower-user shortcut
xDelete profileStopped containers only
?HelpQuick key reference popup

The u / d / l / e / c / x keys are deliberately hidden from the footer — they do exactly the same thing as picking the matching item from the Enter action menu.

App-level

KeyAction
qQuit
F1Return to the dashboard
?Help

Log / startup viewers

KeyAction
fToggle auto-follow on/off
/ / PgUp / PgDnScroll
q / EscBack / close

The action menu

Pressing Enter on a profile opens a context menu. The options depend on whether the container is running:

StateAvailable actions
RunningStop Container · View Logs · Monitor · Benchmark · Edit Profile · Edit Config
StoppedStart Container · Edit Profile · Edit Config · Delete Profile

Benchmark fires a single /v1/chat/completions request at the running server and reports tokens/second. Delete is blocked while a container is running — stop it first. To rename a profile, edit its Name field in the profile form (also only while the container is stopped, since it's named after the profile).

Live monitor

Press v on any row (or pick 📊 Monitor from the action menu) to open a full-screen, btop-style system view. It polls nvidia-smi and each running server's /metrics once a second. Opening it does not require a running container — with nothing up you still get the GPU panel, which is usually the reason to open a monitor at all.

Always shown:

Then one panel per running model — the running list is re-scanned every tick, so a model started elsewhere appears on its own. With exactly one model up you get the full detail view; with several, each gets a compact summary row (tok/s, KV, running/waiting, TTFT, TPOT).

Both backends work — the differing Prometheus metric names are matched by family, and any metric a backend doesn't expose reads rather than a made-up value. Keys: p pause, r reset peaks, +/- poll interval, l language, Esc/q back.

Terminal monitor (plain)

Press t on any row to suspend the Textual UI and open the same monitor — the same GPU panel, braille graphs, cache-hit, and latency percentiles — as a plain-terminal page in your normal terminal, auto-refreshing every second. No Textual rendering, so it holds up over low-bandwidth SSH or on terminals that render the TUI poorly. Same keys; q (or Ctrl+C) returns.

The same monitor is available without the TUI at all: llmux top <profile>.

Quick Setup

n opens a backend picker, then a Quick Setup form that creates a matching profile + config in one step. For vLLM the form takes a Hugging Face model id, GPU id, port, GPU-memory-utilization, an Enable-LoRA toggle, and an optional "copy params from" existing config. The profile name is derived from the model id automatically.

Memory estimator

Press m (or click the search box) and type a Hugging Face model id, then Enter. llmux estimates the model's memory footprint and renders it against your detected GPUs:

This runs entirely on the dashboard — no profile or container needed.

Container start screen

Picking Start Container opens a full-screen launcher with a Version radio set. The options differ per backend:

Five startup modes:

ModeWhat it does
Local LatestHighest local vllm/vllm-openai versioned tag
Official ReleasePulls Docker Hub's latest stable version (explicit semver, never :latest)
NightlyPulls vllm/vllm-openai:nightly
Dev BuildUses / builds vllm-dev:<branch> from source — reveals Repo URL + Branch inputs
Custom TagAn arbitrary image tag you type in

Three startup modes — llama.cpp has a single official ghcr.io tag, so "Local / Official / Nightly" collapses into one:

ModeWhat it does
Default Imageghcr.io/ggml-org/llama.cpp:server-cuda
Dev BuildUses / builds llamacpp-dev:<branch> from source — reveals Repo URL + Branch inputs
Custom TagAn arbitrary <repo>:<tag> you type in

If the profile is already pinned to a llamacpp-dev: image via its image_tag, the screen shows that pin — selecting Default Image or Custom Tag overrides it for that launch only.

Selecting Dev Build reveals Repo URL and Branch inputs, pre-filled from .env.common. Pressing Start streams the startup log live, then switches to following the container's logs. See Dev Builds for the build mechanics.

Conflict gate before start

The dashboard runs a cross-backend port + GPU conflict check before opening the start screen. If something clashes, you get a confirmation dialog with the details and a Start anyway button.

Profile and config forms

Edit Profile and Edit Config open modal forms:

Both forms map straight onto profiles.yaml and the config YAML — there is no separate TUI state.

See also