Skip to content

deepseek_v4: emit dashboard telemetry (HWINFO/TIERS/EMAP/PROF/HITS) in serve mode - #882

Open
PwrBank wants to merge 3 commits into
JustVugg:mainfrom
PwrBank:feat/v4-dashboard-telemetry
Open

deepseek_v4: emit dashboard telemetry (HWINFO/TIERS/EMAP/PROF/HITS) in serve mode#882
PwrBank wants to merge 3 commits into
JustVugg:mainfrom
PwrBank:feat/v4-dashboard-telemetry

Conversation

@PwrBank

@PwrBank PwrBank commented Aug 7, 2026

Copy link
Copy Markdown

Problem

The DeepSeek V4 target engine (deepseek_v4) never emits the serve-protocol telemetry lines that openai_server.py parses for the web dashboard. The Brain and Profiling tabs, the hardware panel, and the tier bar all stayed on "waiting for engine" — the UI was ready, the server was ready, but the engine never spoke:

  • HWINFO / TIERS / EMAP (hardware panel, tier bar, expert cortex) — absent
  • PROF (per-turn phase timings for the Profiling page) — absent
  • HITS (live cortex flash of routed experts during decode) — absent

Verified against the v1.5.0 binary: strings deepseek_v4 | grep -c "EMAP" → 0; /experts returned {"rows":0,"cols":0,"map":"","hits":"","seq":0} and /profile returned {"seq":0,"turns":[]} after real turns.

What this adds

  • c/expert_store.h: ColiStoreTelemetry struct plus two optional ops on ColiExpertStoreOps:
    • emap — per-expert tier/heat hex map (2 chars per expert: (tier << 6) | heat, tier 0=disk 1=RAM, heat = log2(usage) capped at 63)
    • hits — drain+clear a routed-expert bitmap (1 bit per expert, byte i>>3, bit i&7)
  • c/deepseek_v4.c:
    • store_emap() / store_hits() implemented inside the expert-store unit, next to the slot cache they read, under the store mutex
    • routed-expert bitmap allocated at store open, freed on destroy/fail; marked in lookup() and both lookup_hot() success paths
    • serve loop emits HWINFO (cpuinfo/meminfo), TIERS + EMAP, and per-turn PROF after the READY handshake and after each turn (mirrors colibri.c's mux_done ordering)
    • v4_serve_token drains and emits HITS after every token, so the Brain cortex flashes routed experts live during decode

Verification (real 284B checkpoint, serve mode)

  • /health now carries hwinfo (AMD EPYC 7662, 64 cores, RAM totals) and tiers (e.g. ram: 2108, disk: 8900, ram_gb: 28.18 after one turn)
  • /expertsrows: 43, cols: 256, 22,016-char map with resident tier + heat bytes set
  • /profile → real per-turn records (wall_s, token counts, forwards)
  • 40-token turn → hits_seq advanced to exactly 40 (one HITS emission per token), bitmap populated
  • No protocol regressions: chat/completions, DATA streaming, ACCEPT/DONE unchanged

Known limitation (deliberately honest)

The V4 engine has no per-phase timers yet (unlike the GLM engine's t_ewait/t_emm/t_attn accumulators), so PROF phase fields are emitted as 0 and the whole wall time lands in the UI's "other" bucket. The per-turn wall/token columns render correctly; the phase breakdown needs engine-side instrumentation, which is a separate change.

Base

Based on main (v1.5.0, 8f512fc). Happy to rebase onto dev if you'd rather have it there with the other V4 work.

root and others added 3 commits August 7, 2026 12:57
Adds the serve-protocol HWINFO / TIERS / EMAP / PROF lines the gateway
(openai_server.py) parses for the web dashboard. The V4 target engine
previously never emitted them, so the Brain/Profiling tabs and the
hardware/tier panels stayed on 'waiting for engine'.

- expert_store.h: new ColiStoreTelemetry struct + optional emap op on
  ColiExpertStoreOps (per-expert tier/heat hex map).
- deepseek_v4.c: store_emap() implemented inside the expert-store unit
  (reads the live slot cache + usage under the store mutex); serve loop
  calls ops->emap/ops->stats and emits TIERS/EMAP, per-turn PROF, and
  HWINFO (cpuinfo/meminfo) after READY+STAT and after each turn.
- Phase timings are not split out by the V4 engine yet: PROF phase fields
  are 0 and the wall time lands in the UI's 'other' bucket (honest).
The Brain cortex flash effect needs HITS lines (1 bit per expert, per
token). The V4 engine tracked nothing, so the cortex stayed dark during
decode.

- V4ExpertStoreState: routed-expert bitmap (rows*cols bits), allocated in
  the store open path, freed in destroy/fail.
- lookup() and lookup_hot() (both success paths) mark the bit for the
  routed (layer, expert) under the store mutex.
- New ColiExpertStoreOps.hits op: drains + clears the bitmap as hex.
- Serve loop: v4_serve_token drains and emits HITS after every token, so
  the gateway's hits_seq advances during decode and the Brain tab flashes
  each token's experts live.
…y scale

The cortex grid was previously just the 1px inter-cell gap, which aliases
away when the canvas bitmap is CSS-scaled to the wrapper (non-integer
scale factors drop some column/row lines). Draw a 1px black stroke at
every cell boundary so the grid is complete at any display size, and
present even when cell < 4 (gap == 0).
@acedogblast

Copy link
Copy Markdown

I tested this with the web command but it does not seem to show HW info and profiling.

@JustVugg JustVugg added the enhancement New feature or request label Aug 8, 2026
@JustVugg

JustVugg commented Aug 8, 2026

Copy link
Copy Markdown
Owner

The problem is real and your verification of it is the right shape — strings deepseek_v4 | grep -c "EMAP" → 0, and /experts returning {"rows":0,...} after real turns, is proof rather than assertion. The Brain and Profiling tabs have been dead for DeepSeek V4 since it shipped, and the UI was ready the whole time.

Three CI checks are failing, so I cannot take it yet. Would you look at those first? I have not dug in, because the fix is yours and guessing at it from here would waste your time as much as mine.

Two review notes for when you push again, neither blocking:

emap and hits as optional ops on ColiExpertStoreOps is the right seam. That header is shared, so a store that does not implement them stays valid — worth stating explicitly in the struct comment that both are optional and NULL is a legal value, otherwise the next implementer has to infer it from the call sites.

HITS after every token is the part I would want a number on. Draining and emitting a bitmap per token on a 284B model with 256 experts × 43 layers is 1,376 bytes of hex per token plus a printf and fflush on the serve pipe. At the token rates this engine runs at that is almost certainly free, but "almost certainly" is how the last three regressions got in. If you have a before/after tok/s on the same prompt with and without the emission, put it in the PR and the question is closed.

One thing I want to flag because it is genuinely in your favour: this touches c/deepseek_v4.c (+197), which is the engine the maintainer works on locally. That is not a reason to hold it — it is a reason to keep the diff exactly as scoped as it already is. Please resist the urge to tidy anything else in that file while you are in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants