Summary
The live terminal chart rendering is duplicated between commands/live_chart.py (perf-specific) and session/monitor/live_display.py (generic HW monitor). Refactor into a layered architecture.
Current State
commands/live_chart.py::LiveMonitorDisplay — perf-specific, caller-driven (update per iteration), ~250 lines
session/monitor/live_display.py::HWLiveDisplay — generic, self-driving (background thread), ~200 lines
- ~50 lines of plotext chart rendering code duplicated between both
Proposed Architecture
Layer 1: LiveChart (pure rendering component)
- Location:
modelkit/utils/live_chart.py
- Responsibility: plotext chart rendering + Rich Live terminal display
- API:
render_chart(time_series: dict[str, list[float]], width, height) -> Renderable
- No HW awareness — just plots named time series with colors
- Pure function, no state, no threading
Layer 2: HWLiveDisplay (HW monitor + chart)
- Location:
modelkit/sysinfo/live_display.py (or session/monitor/)
- Builds on:
LiveChart + HWMonitor
- Self-driving: background thread polls HWMonitor, renders via LiveChart
- API: context manager —
with HWLiveDisplay(title="eval"): ...
- Used by: examples, user scripts, any non-perf context
Layer 3: PerfLiveDisplay (perf benchmark display)
- Location:
modelkit/commands/live_chart.py (replaces current LiveMonitorDisplay)
- Builds on:
LiveChart + HWMonitor (or inherits HWLiveDisplay)
- Caller-driven: perf loop calls
update(iteration, latency_ms) per iteration
- Adds: iteration progress bar, warmup/benchmark phase, latency/throughput status
- Used by:
wmk perf --monitor
Benefits
- Eliminates ~50 lines of duplicated plotext chart code
- Clear separation: rendering vs monitoring vs benchmarking
LiveChart reusable for future visualizations (e.g., training loss, memory over time)
- Each layer has a single responsibility
Files to Modify
| File |
Action |
modelkit/utils/live_chart.py |
Create — pure chart renderer |
modelkit/sysinfo/live_display.py |
Create — HWLiveDisplay (move from session/monitor/) |
modelkit/commands/live_chart.py |
Rewrite — PerfLiveDisplay using LiveChart |
modelkit/session/monitor/live_display.py |
Delete — replaced by sysinfo/ |
Acceptance Criteria
Summary
The live terminal chart rendering is duplicated between
commands/live_chart.py(perf-specific) andsession/monitor/live_display.py(generic HW monitor). Refactor into a layered architecture.Current State
commands/live_chart.py::LiveMonitorDisplay— perf-specific, caller-driven (update per iteration), ~250 linessession/monitor/live_display.py::HWLiveDisplay— generic, self-driving (background thread), ~200 linesProposed Architecture
Layer 1:
LiveChart(pure rendering component)modelkit/utils/live_chart.pyrender_chart(time_series: dict[str, list[float]], width, height) -> RenderableLayer 2:
HWLiveDisplay(HW monitor + chart)modelkit/sysinfo/live_display.py(orsession/monitor/)LiveChart+HWMonitorwith HWLiveDisplay(title="eval"): ...Layer 3:
PerfLiveDisplay(perf benchmark display)modelkit/commands/live_chart.py(replaces currentLiveMonitorDisplay)LiveChart+HWMonitor(or inheritsHWLiveDisplay)update(iteration, latency_ms)per iterationwmk perf --monitorBenefits
LiveChartreusable for future visualizations (e.g., training loss, memory over time)Files to Modify
modelkit/utils/live_chart.pymodelkit/sysinfo/live_display.pymodelkit/commands/live_chart.pymodelkit/session/monitor/live_display.pyAcceptance Criteria
LiveChartrenders arbitrary time series without HW knowledgeHWLiveDisplayworks as a standalone context manager (current behavior preserved)PerfLiveDisplayrenders iteration progress + HW chart (currentwmk perf --monitorbehavior preserved)examples/imgcls_eval.pycontinues to work with--monitorwmk perf --monitorcontinues to work