Skip to content

Web UI: prefill speeds, request timings, a context gauge, chat compaction - #177

Closed
orangeswim wants to merge 2 commits into
Niko1221:mainfrom
orangeswim:prefill-metrics
Closed

orangeswim wants to merge 2 commits into
Niko1221:mainfrom
orangeswim:prefill-metrics

Conversation

@orangeswim

@orangeswim orangeswim commented Sep 29, 2026 •

Copy link
Copy Markdown

Web UI: prefill speeds, request timings, a context gauge, chat compaction

No engine changes. This UI change exposes some metrics already tracked.

Prefill speeds. _prompt_tok_s() in server.py (the cumulative mean, not a window -
the engine reports prompt progress per 8k chunk, so a window rate swings between 0 and
the burst rate), a prompt_tok_s telemetry series, and prompt_tok_s per request in
/metrics history. In the Monitor: a Prefill card, the rate on the "Reading prompt"
line, read N @ X tok/s on the last-request line, a Read t/s column in the requests
table.

Request details in chat. A chevron on each reply opens one line:
read 25,838 @ 2,165 tok/s · 1,850 reused · TTFT 12.4 s · drafts 214 of 240 accepted.
It's the response's timings (llama.cpp names), kept in localStorage with the message.

Tokens in/out. A Monitor card from the server's running totals: everything read vs
written since the server started (1.2M / 340k, cache reuse excluded from the in side),
with the request count and reused tokens as its sub-line.

Context gauge. 2.4k/200K with a fill bar next to the sampling button. Amber at 70%
of the window, red at 90%. Updates from usage after each reply. Passive - it does not
trigger anything.

Compaction. The layers button folds the older turns into a summary; the newest turns stay verbatim up to a ~5k-token budget, the API payload becomes the summary plus everything after the cut, and the page keeps every message (older turns muted above the cut). The summary is one hidden non-streaming request (thinking off, temp 0, 1600 tokens max) with a structured prompt: intent, facts and decisions, verbatim code, all user messages, errors and fixes, open items, current thread. The fold marker lands at the end of the chat with its stats; only the newest marker carries a "put back into the context" undo (an earlier one could not restore anything - a later fold still stands over it), and unfolding peels
one layer at a time. Chained folds merge. Long user messages (>10 lines / 800 chars) clamp with a Show-all toggle - display only, the API gets the full text.

All 38 serve tests pass unchanged. Tested on a 3090 against 0.1.26 (k8v4 and int8).

AI Tools

Created and reviewed with the help of Claude-Code using GLM-5.3, Strata qwen3.8-flash-next-coder-iq1_m and Codex.

image image image

…quest history

The engine has always reported prompt timing (request_timings, /v1/status, the
done event) but the web UI showed decode only. Three additions, no engine change:

- Monitor: a Prefill card (live tok/s while a prompt is read, the last request's
  when idle, the same sparkline treatment), the reading progress line gains its
  rate, and the idle last-request line gains 'read N @ X tok/s'
- chat: the meta line is unchanged; a chevron opens one muted detail row with
  the request's timings - tokens read and their speed, cache reuse, time to
  first token, written tok/s, drafts accepted
- server: a _prompt_tok_s window rate mirroring _tok_s (sampled by the telemetry
  tick from the engine's per-chunk progress), a prompt_tok_s telemetry series,
  and prompt_tok_s in the per-request history /metrics already returns

Co-Authored-By: Claude Code <noreply@anthropic.com>
@orangeswim
orangeswim force-pushed the prefill-metrics branch 2 times, most recently from 89c3dc6 to 424b56b Compare September 29, 2026 23:43
@orangeswim
orangeswim marked this pull request as ready for review September 29, 2026 23:44
@orangeswim
orangeswim marked this pull request as draft September 29, 2026 23:49
@orangeswim
orangeswim force-pushed the prefill-metrics branch 13 times, most recently from 4cbfb4c to 2c80adb Compare September 30, 2026 02:04
@hendrikp

hendrikp commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

The prefill #163 i did more compact by sharing it in speed panel. I noticed the total tokens is already at bottom of recent request table as small text.

Both of these things eliminate the need for a 3rd row.

apiMessages() folds at a compact marker (web/fold.js, tested by web/test_fold.mjs,
run through serve/test_web_fold.py): the LAST marker's summary stands in for
everything older than its recorded cut; the newest turns stay verbatim up to a
~5k-token budget, the summary carries them as an exact client-built transcript,
and the payload after any fold is [summary] + newer messages. The page keeps
every message - muted above the cut - and only the newest marker carries the
put-back undo. The summary request runs thinking on low, temp 0, capped at 5k
tokens clamped to the window's room, with a truncation warning.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@Niko1221

Copy link
Copy Markdown
Owner

Nice UI work. Please drop STRATA_CAPTURE_DIR from this PR (it writes every request body to disk; that deserves its own PR with docs), fix the duplicated comment in start_telemetry, and coordinate with #163 so we have one prefill-speed display.

@Niko1221

Copy link
Copy Markdown
Owner

Thanks @orangeswim, nice UI work. We're taking #163 for the prefill speed display. For a new PR please keep only the context gauge, the request timings and chat compaction (no prefill parts), and leave out STRATA_CAPTURE_DIR (it writes every request body to disk; that needs its own PR with docs). We're closing PRs that wait on changes so the list stays manageable; this is not a no. Please open a new PR when it's ready and link this one.

@Niko1221 Niko1221 closed this Sep 30, 2026
perronemirko pushed a commit to perronemirko/Strata that referenced this pull request Oct 15, 2026
The PCIe round-trips, not the math, capped device-resident prefill.
Packing the card's K/V rows cuts that traffic and the VRAM the windows
reserve: e4m3 = 1B/element (4x), f16 = 2B, chosen per side by -k / -v.

- k_attn is template<T_K, T_V>: history rows dequantize into registers
  (gpu::unpack_target_to_fp32), so no fp32 KV row ever exists in VRAM
- per-row power-of-two scales in kv.kinv/kv.vinv; host cache and the
  KV checkpoint stay fp32, the Model/decode/rollback read them unchanged
- pack/unpack kernels on the H2D and the commit path replace the fp32
  D2D copy; plan_bytes and init() size the packed rows
- kv_quant.hpp now holds the ONE definition of pack/unpack: the copies
  duplicated in gpu_cuda.cu shadowed it and stayed unreferenced (nvcc
  Niko1221#177-D), and the mid-file include left prefill_dev.cu unable to see
  the template (3 errors at line 132/133)

Refs: build clean with `sh build.sh --cuda` (sm_89)
perronemirko pushed a commit to perronemirko/Strata that referenced this pull request Oct 17, 2026
The PCIe round-trips, not the math, capped device-resident prefill.
Packing the card's K/V rows cuts that traffic and the VRAM the windows
reserve: e4m3 = 1B/element (4x), f16 = 2B, chosen per side by -k / -v.

- k_attn is template<T_K, T_V>: history rows dequantize into registers
  (gpu::unpack_target_to_fp32), so no fp32 KV row ever exists in VRAM
- per-row power-of-two scales in kv.kinv/kv.vinv; host cache and the
  KV checkpoint stay fp32, the Model/decode/rollback read them unchanged
- pack/unpack kernels on the H2D and the commit path replace the fp32
  D2D copy; plan_bytes and init() size the packed rows
- kv_quant.hpp now holds the ONE definition of pack/unpack: the copies
  duplicated in gpu_cuda.cu shadowed it and stayed unreferenced (nvcc
  Niko1221#177-D), and the mid-file include left prefill_dev.cu unable to see
  the template (3 errors at line 132/133)

Refs: build clean with `sh build.sh --cuda` (sm_89)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants