Skip to content

feat(power): add query energy and TDP dashboard axes / 新增每请求能耗与 TDP 占比图表轴 - #735

Merged
edwingao28 merged 8 commits into
masterfrom
feat/power-derived-axes
Aug 19, 2026
Merged

edwingao28 merged 8 commits into
masterfrom
feat/power-derived-axes

Conversation

@edwingao28

@edwingao28 edwingao28 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

What

Three derived measured-power axes for the inference dashboard:

  • y_measuredJPerSuccessfulQuery — joules per successful query (producer emits joules_per_successful_query)
  • y_measuredWhPerSuccessfulQuery — the same energy in Wh (÷ 3600) for people who think in battery units
  • y_measuredPowerPercentTdpavg_power_w / TDP × 100, TDP from the shared hardware registry in packages/constants/src/gpu-keys.ts (all 10 SKUs carry a tdp entry)

All three: EN/ZH labels, roofline directions (lower_right on the interactivity block, lower_left on the e2e block; %TDP has no Pareto direction — it is a utilization gauge, not an efficiency frontier), scatter + historical trends + unofficial-run overlay wiring, and gap-preserving behavior when the underlying fields are absent.

Depends on

Stacked on #734 (power_valid / schema-semantics guard) — the first two commits here are that PR. Review only the last commit: feat(power): add query energy and TDP dashboard axes. Merge #734 first, then this rebases to a single commit.

Like the base PR, the J/query axes only render whole-deployment-stamped rows on disaggregated deployments; %TDP and role watts are unaffected.

Out of scope

The AI-generated chart path (ai-chart/) shares the Y_AXIS_METRICS whitelist and has pre-existing defects for every lower-is-better metric (missing-as-zero in line charts, no radar inversion, top-N picks maxima). Those predate this PR — they date from the original six measured axes — and are tracked separately rather than mixed in here. This PR only adds a validateSpec test pinning that the new keys survive spec validation.

Verification

bun run typecheck                 clean
bun run lint                      clean
packages/app vitest (full)        3381 passed / 174 files
packages/db  benchmark-mapper     98 passed

Note

Medium Risk
Touches measured-power contract semantics and chart roofline/table ordering for new lower-is-better axes; risk is mitigated by broad tests but display logic errors would mislead efficiency comparisons.

Overview
Adds three Measured Energy Y-axis options on the inference dashboard: joules per successful query, watt-hours per successful query (÷3600), and average measured power as % of hardware TDP from the GPU registry.

Data path: joules_per_successful_query is passed through benchmark transform (with the same schema-v2 / power_valid guards as other whole-deployment joules on disagg rows). Chart points derive Wh/query and %TDP via shared buildMeasuredPowerChartFields, used by scatter charts and historical trend interpolation.

Chart behavior: New keys are registered in Y_AXIS_METRICS, chart JSON (EN/ZH), and ChartControls. J/query and Wh/query use lower-is-better Pareto directions (lower_right / lower_left by chart block) with roofline marking wired in markRooflinePoints. %TDP is plottable but has no _roofline — treated as a utilization gauge, not an efficiency frontier.

Hardening: Invalid or malformed power_valid / schema normalization on unofficial-run overlays; non-power telemetry (temp, util, workers) is scrubbed when power_valid=0, alongside measured power fields.

Reviewed by Cursor Bugbot for commit 1e1999a. Bugbot is set up for automated code reviews on this repo. Configure here.

@edwingao28
edwingao28 requested a review from adibarra as a code owner August 14, 2026 01:54
@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
inferencemax-app Ready Ready Preview Aug 19, 2026 3:41am

Request Review

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 5m 19s —— View job


Review — PR #735: power-derived axes

  • Gather context (target commit 308fbdd)
  • Review derived-metric logic (benchmark-transform, chart-utils)
  • Review constants / metric-keys / types / config
  • Runtime verification (Playwright on localhost:3000)
  • Check CI status
  • Post findings

Summary

🟢 Solid, well-tested change. The three new derived axes are wired correctly end-to-end and verified at runtime.

Verified:

  • ✅ All three options appear in the Measured Energy Y-axis group and render real data (selected % TDP → chart draws with sensible values ~34–44%, e.g. B200 ≈ 40.8% of its 1000 W TDP), 0 console errors.
  • ✅ Math is correct and unit-tested: 560 W / 700 W → 80%, 1800 J / 3600 → 0.5 Wh, 1800 J/query; absent-input cases correctly omit the fields (gap-preserving).
  • tdp is present on all HW_REGISTRY entries and threaded through getGpuSpecs → both scatter (createChartDataPoint) and historical-trend (rowToLightweightPoint) paths share buildMeasuredPowerChartFields.
  • ✅ Whole-deployment gating on joules_per_successful_query matches the base PR's energy semantics.
  • ✅ Test coverage is thorough (transform, chart-utils, direction, overlay-provider, unofficial-run route, ai-chart spec, interpolation, chart-controls component). CI is green (typecheck / lint / unit / e2e all passing).

One non-blocking note (inline): the PR body says "%TDP has no Pareto direction", but the config does assign it a roofline and the test enforces it — so Optimal Only filters the %TDP axis to a frontier (confirmed at runtime). Behavior is self-consistent and defensible; just reconcile the description (or drop the roofline) so reviewers aren't misled.

No blocking issues found.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bbd7f58. Configure here.

Comment thread packages/app/src/components/inference/inference-chart-config.json Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 308fbdd3e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/app/src/lib/chart-utils.ts
Comment thread packages/app/src/components/inference/ui/ChartControls.tsx
Comment thread packages/app/src/components/inference/inference-chart-config.json Outdated
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 3m 58s —— View job


Re-review — PR #735: power-derived axes

  • Gather context (diff vs origin/master, prior review threads)
  • Review derived-metric logic (chart-utils, benchmark-transform)
  • Verify the markRooflinePoints P1 concern (Codex)
  • Check %TDP roofline direction concern (Bugbot/Codex/prior Claude)
  • Runtime verification (Playwright — 0 console errors)
  • Check CI status (all green)
  • Post findings

Summary

The three new axes are wired correctly end-to-end (config EN/ZH labels, Y_AXIS_METRICS, buildMeasuredPowerChartFields shared by scatter + trend paths, overlay + interpolation, tdp threaded through getGpuSpecs). Math checks out (per-GPU avg_power_w / tdp × 100, J÷3600 → Wh), fields are gap-preserving, and CI is green (Lint / Unit / E2E all ✅). Runtime load of #inference shows 0 console errors. The commit under review (308fbdd) is unchanged since the prior verification.

One 🟡 WARNING (inline, also Codex's P1): markRooflinePoints was never extended for the three new metrics, so transformBenchmarkRows returns their per-point roof flag as permanently false. Not a live render break — both ScatterGraph and GPUGraph recompute the frontier from the chart-definition direction rather than reading that flag (I confirmed Optimal Only works at runtime) — but it violates the AGENTS.md "Add/modify a metric" checklist and leaves the transform's roof contract inconsistent with the six existing measured axes. Worth closing before merge.

Non-blocking (already noted by Bugbot / Codex / prior review): the PR body says "%TDP has no Pareto direction", but the config assigns it lower_right/lower_left rooflines and measured-power-direction.test.ts enforces them. Behavior is internally consistent and defensible (%TDP is monotonic in avg_power_w per hardware), but reconcile the description or drop the roofline so reviewers aren't misled — same choice-point as the WARNING above.

No blocking issues found.

Comment thread packages/app/src/lib/chart-utils.ts
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 1m 55s —— View job


Re-review — PR #735: power-derived axes

  • Gather new commits since prior review
  • Verify prior WARNINGs are resolved (markRooflinePoints + %TDP direction)
  • Review new/changed code
  • Check CI status
  • Runtime verification (Playwright)
  • Post findings

Summary

Re-review of the two new commits since 308fbdd (a69cff1 mark roofline points; c6d64d6 drop %TDP direction). Both prior WARNINGs are correctly resolved:

  • markRooflinePoints extendedmeasuredJPerSuccessfulQuery / measuredWhPerSuccessfulQuery now appear in both the reset block and the onCurrentRoofline assignment chain, and calculateRoofline/computeAllRooflines unions accept their .y keys. Their per-point roof flag is now consistent with the six existing measured axes. (%TDP is intentionally excluded — see below.)
  • %TDP Pareto direction dropped_roofline keys removed from both the interactivity and e2e config blocks, the _roofline field removed from ChartDefinition, and measured-power-direction.test.ts now asserts declaredDirection(...) is undefined for %TDP while keeping the query-energy axes at lower_right/lower_left. This reconciles the earlier config-vs-description contradiction: %TDP is now genuinely a gauge (no frontier), matching the PR body. Internally consistent — with no direction, ScatterGraph/GPUGraph compute no frontier, so Optimal Only leaves all configs visible.

Runtime: #inference loads and the chart renders with 0 console errors.

🔴 BLOCKING — Lint & Format CI is failing

The Lint & Format check fails (run): oxfmt --check flags two files, both introduced by the fix commits — chart-utils.ts (inline) and measured-power-direction.test.ts:33. Fix with bun run fmt:fix before merge; branch rules gate on this check. Unit tests are green; E2E still in progress.

Once formatting is fixed, this is good to go.

Comment thread packages/app/src/lib/chart-utils.ts Outdated
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 1m 9s —— View job


Re-review — PR #735: power-derived axes

  • Gather new commits since prior review (c6d64d6)
  • Verify prior 🔴 BLOCKING lint/format failure is resolved
  • Check CI status
  • Review new/changed code
  • Runtime verification
  • Post findings

Summary

Re-review of the single new commit since the last review (c6d64d6): 1e1999a style: oxfmt.

✅ The prior 🔴 BLOCKING lint/format failure is resolved. 1e1999a is a pure-formatting commit (git show confirms — no semantic change) that reflows exactly the two lines the failing oxfmt --check flagged:

  • chart-utils.ts:832 — the measuredWhPerSuccessfulQuery reset collapsed back onto one line.
  • measured-power-direction.test.ts:30 — the QUERY_ENERGY_METRICS array wrapped across lines.

Lint & Format is now green, along with Tests (Unit), Code Quality, and PR #735. Tests (E2E) was still in progress at review time — worth a final glance before merge, but nothing in a formatting-only commit should affect it.

Both prior WARNINGs remain correctly resolved (verified unchanged in the current tree):

  • markRooflinePoints extends the reset + onCurrentRoofline assignment chain for measuredJPerSuccessfulQuery / measuredWhPerSuccessfulQuery, and calculateRoofline / computeAllRooflines unions accept their .y keys — so their per-point roof flag is now consistent with the six existing measured axes.
  • %TDP genuinely carries no Pareto direction: _roofline keys removed from both config blocks (interactivity + e2e), the _roofline field removed from ChartDefinition, and measured-power-direction.test.ts asserts declaredDirection(...) is undefined for it while pinning the query-energy axes at lower_right/lower_left. Config, types, test, and the PR body now agree.

Runtime: the only change since the last Playwright verification (commit c6d64d6, #inference loaded with 0 console errors and % TDP rendering ~34–44%) is byte-level formatting, so runtime behavior is identical — no re-run needed.

🟢 LGTM — no blocking issues found. Once Tests (E2E) reports green, this is good to merge.

@edwingao28
edwingao28 merged commit 313fcd4 into master Aug 19, 2026
24 checks passed
@edwingao28
edwingao28 deleted the feat/power-derived-axes branch August 19, 2026 03:47
functionstackx added a commit that referenced this pull request Aug 25, 2026
…ns (#850)

Two weeks of AgentX work shipped concepts the glossary did not define, and
left several existing entries describing behavior the dashboard no longer
has. Add entries for E2E Normalized Interactivity (#847, #848), tokens per
dollar (#770, #787, #793), energy per token (#734, #735), context
parallelism (#745), KV cache offload (#729, #818), KV cache manager, KV-aware
routing, and TileRT (#843).

Refresh nine entries against current behavior: agentic curves merge
speculative decoding into point-level metadata (#695) while fixed-sequence
curves still split on it; best-per-SKU views merge permitted optimizations
into one curve; cost and energy are derived from interpolated throughput
rather than splined (#726); AgentX is the deliberate exception to the
prefix-caching-disabled rule; agentic ISL/OSL is a lognormal distribution
rather than a single pair (#810, #811).

中文:新增八条 AgentX 相关术语并更新九条既有释义。新增:端到端归一化交互性、
每美元 token 数、每 token 能耗、上下文并行、KV cache offload、KV cache 管理器、
KV 感知路由和 TileRT。更新内容对齐当前行为:agentic 曲线把投机解码作为数据点级
元数据合并(定长场景仍按曲线区分);每个 SKU 最佳配置视图合并允许的优化;成本与
能耗由插值吞吐量推导而非单独样条;AgentX 是禁用前缀缓存规则的有意例外;agentic
的 ISL/OSL 是对数正态分布而非单一取值。中英文条目同步更新。
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.

1 participant