docs: steady-state metrics reporting design proposal - #447
Conversation
|
MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅ |
| a run killed by `SIGKILL`/OOM before the log is flushed yields a truncated log; | ||
| the step must degrade to a best-effort result with a status flag rather than | ||
| fail (§5.6). |
There was a problem hiding this comment.
Maybe I am not reading it in the right way - but I thought it should fail if the original run fails?
There was a problem hiding this comment.
What does "failing" mean here — a request timeout or a process crash? My intent is that a timeout should still yield a best-effort (partial) result over whatever was logged, while a hard crash of the post-process can just fail. Could you clarify which case you had in mind so I word the edge-case handling to match?
There was a problem hiding this comment.
Two run-failure modes, handled differently. A timeout / interrupt (SIGTERM, drain-timeout) still flushes a partial event log, so the step computes a best-effort steady result over what was logged and marks status = partial — the same way the report already flags interrupted runs. A hard crash before the log is flushed (SIGKILL/OOM) yields a truncated log; the step still degrades to best-effort + partial rather than erroring. The post-process itself never hard-fails a run. Separately, a run that completes but never reaches steady state is reported with the offending metrics flagged unstable (§5.6), not failed — whether that should count as an invalid submission is the open TF question in §6. Does that cover the case you had in mind?
This reply was drafted by Claude (Claude Code) and posted on my behalf.
| - **Relative active concurrency.** In-flight count as a percentage of the | ||
| max-concurrency budget (100% at saturation). | ||
| - **Issue-time window.** A contiguous range of super-passes `[start, end)`. Its | ||
| measured set is every request _issued_ in that range. Throughput uses the |
There was a problem hiding this comment.
This might requires some clarification - as far as i understand from below a sample issued but whose response is not received has no logged TTFT and is naturally excluded. So either it is issue only or issue with at least one event to be included in a window.
There was a problem hiding this comment.
Membership is issued within the window; a sample then contributes to a given metric only if that metric was logged inside the window (e.g. a first-token event for TTFT). So an issued-but-no-response sample is a member of the issue set (it counts toward the offered / issue-time denominator) but contributes no TTFT/TPOT — hence "naturally excluded" from the latency families, not from issuance. I'll reword §5.1 to separate membership from per-metric contribution so it's unambiguous.
This reply was drafted by Claude (Claude Code) and posted on my behalf.
| (everything issued at `t=0`), so there is no client-side issue-time window and no | ||
| client-side drain boundary. The step detects the mode and finds the steady region |
There was a problem hiding this comment.
for TPOT calculations, we could potentially use the completion-first_token time, but that would require the server to not evict requests in decode phase.
There was a problem hiding this comment.
Agreed — that's exactly the §5.6 caveat: the timestamp-derived TPOT (complete − first_token) assumes the request stays resident through decode; if the server evicts/pages it mid-decode, the span includes non-decode queue time and inflates TPOT, so a server-reported per-token count is preferred where eviction is possible. This is also why the design now adds staircase / level-shift detection (Pettitt + multi-plateau): KV-cache-eviction-driven degradation toward the end of long runs shows up as a step in TPOT, which we flag as an anomaly rather than fold into the steady number.
This reply was drafted by Claude (Claude Code) and posted on my behalf.
| - **ISL / OSL** are reported for analytics, not as validation numbers: once the | ||
| window is allowed to drop samples (not enforcing full dataset-pass boundaries), | ||
| the input/output-length distribution is skewed relative to the constructed | ||
| dataset and is no longer a meaningful validation quantity, though it remains | ||
| useful for analysis. |
There was a problem hiding this comment.
If the window is allowed to drop samples, should the ISL/OSL statistics be computed for the samples included in the measurement?
There was a problem hiding this comment.
Yes — ISL/OSL are computed over the included (windowed) samples today, which skews them relative to the constructed dataset once the window is allowed to drop samples. §5.8 flags them as analytics-only, not validation numbers. Whether the official artifact should report them over the full issued set instead (or carry both) is deferred to the benchmark TF (§6, "ISL/OSL reporting basis").
This reply was drafted by Claude (Claude Code) and posted on my behalf.
|
|
||
| # 6 Open questions {#6-open-questions} | ||
|
|
||
| - **Default parameters.** The warmup band, trailing-window length, per-percentile |
There was a problem hiding this comment.
Can we ignore the first pass/super-pass over the dataset as a warmup pass and the other parameters can be benchmark specific decided by TF?
There was a problem hiding this comment.
Agreed, and captured as the §6 open question "First pass as warmup (task force)." The current design infers the warmup band adaptively from the data, but treating the first full pass as warmup-by-construction is a reasonable TF-set default; the accompanying band / window / bound defaults would be the TF's to fix.
This reply was drafted by Claude (Claude Code) and posted on my behalf.
| - **Guard distance measure.** The exact two-sample statistic and acceptance bound | ||
| for the per-token-invariance guard (§5.4) need to be fixed. | ||
| - **No-steady-state runs.** When no steady state is found (a tracked metric is | ||
| Drifting Up), should the run be reported _invalid_ — analogous to legacy |
There was a problem hiding this comment.
We should declare the gates for each benchmark and also define whether a submission should be invalid if it fails a certain gate. It should be a benchmark TF decision on what gates to include.
There was a problem hiding this comment.
Agreed — captured in §6 ("Per-benchmark gates and invalidation"): the CoV bounds and trend thresholds are tunable per benchmark, and whether failing a gate invalidates a submission versus reports-with-flags is explicitly a benchmark-TF decision, not fixed by this proposal.
This reply was drafted by Claude (Claude Code) and posted on my behalf.
5e936f6 to
bad5e83
Compare
| client. The window measures the sustained behavior of a healthy server; a | ||
| genuinely unhealthy server produces bad-but-real numbers, which the drift | ||
| detector (§5.5) distinguishes from transient pollution. | ||
| - **Super-pass.** The atomic unit of the analysis: a contiguous block of requests |
There was a problem hiding this comment.
Is there an assumption here that we need more than one super-pass? How many would be needed to get a good estimate?
There was a problem hiding this comment.
Yes. The coverage-status table (§5.6) requires ≥ warmup + 1 full super-passes to window normally; below that it's best-effort / low-confidence. For a trustworthy estimate the trend test needs ≥ 4 super-passes (its minimum), so in practice you want ~5–6+ post-warmup super-passes. Fewer still yields a number, but flagged insufficient_passes.
This reply was drafted by Claude (Claude Code) and posted on my behalf.
| [ ingest -> per-super-pass series ] issue-order bucketing | ||
| | | ||
| v | ||
| [ adaptive warmup crop ] remove the ramp |
There was a problem hiding this comment.
Band-adaptive warmup crop (§5.4): estimate the steady level from the median of the series' back half for a driver metric (e.g. TTFT p99), then drop leading super-passes whose value exceeds steady × (1 + band). Band-based (not slope-based) so a single settling outlier can't collapse the crop, and only high leading values are dropped so a later upward drift is still measurable. (The reference script currently exposes a fixed --warmup; the adaptive crop is specced but not yet ported to it.)
This reply was drafted by Claude (Claude Code) and posted on my behalf.
| **Ensemble and window selection.** CoV alone is insufficient — a window is only | ||
| meaningful if the metric is in Plateau. In practice, over a large set of runs, no | ||
| single `(window, bound)` fits all metrics and workloads, so the rule is run as an | ||
| **ensemble** of preset `(window, bound)` settings. Among the settings that report |
There was a problem hiding this comment.
Can you explain what does "ensemble of (window, bound)" mean exactly? How are the values of window and bound decided?
There was a problem hiding this comment.
It means the CoV rule is evaluated at several preset (trailing-window, bound) settings rather than one; a window passes CoV if at least one setting certifies every gated metric. No single setting fits all metrics/workloads, so the ensemble adds robustness (concordance across settings is a corroborating guardrail). The values come from sweeps over recorded runs (defaults: bounds 0.03 / 0.05 / 0.08 loosening toward the tail, trailing windows 4–5); §6 flags that these defaults should be reviewed on a wider set before being locked.
This reply was drafted by Claude (Claude Code) and posted on my behalf.
Post-processing step (and ad-hoc CLI over events.jsonl) that reports steady-state metrics — super-pass windowing, guarded drain-tail cut, CoV ensemble + trend gate (drift up/down), hairball, edge-case handling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bad5e83 to
158d294
Compare
…aly gates) + tests Implement the steady-window selection in scripts/steady_state_diagnostics.py: grow-from-left plateau segmentation (admissible = trend-steady + within a CoV bound on TTFT/TPOT p50+p95), first-plateau selection per the MSER maximize-precision principle, pooled TTFT/TPOT histograms + per-user/system TPS with batch-means CIs, Pettitt + multi-plateau staircase (level-shift) detection, and a whole-tail Drifting-Up gate that flags a locally-flat window sitting inside a globally-drifting metric. Adds tests (47) and a README alongside the script. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Lower the tokenizer-flush buffer for long reasoning outputs (e.g. DeepSeek-R1) to avoid OOM on large event logs; threaded through run()/build_super_pass_series. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The steady-window system TPS divided total output tokens by the completion span (first issue -> last event), so the decode drain inflated the denominator and deflated TPS -- ~12x too low on high-tail workloads (DeepSeek-R1 c28k: 63.7k -> 746.9k tok/s). Use the offered-load issue span (first issue -> last issue) per design section 5.1; track last_issue_ns, add window_issue_span_ns, and export a raw per_super_pass series for plotting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the fixed --warmup with 'auto': estimate the steady level from the driver metric's back-half median (default tpot_p50 -- smooth per super-pass, unlike the volatile TTFT) and crop leading super-passes >band off it (symmetric, since TPOT ramps up to steady). Configurable via --warmup/--warmup-band/--warmup-driver. On the DeepSeek-R1 c28k run this crops 24 ramp super-passes and moves the window from the ramp shoulder (SP13, TPOT p50 40.4ms, spurious tpot_p95 drift warning) onto the true plateau (SP24-27, TPOT p50 46.1ms, no warning). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| ## Run | ||
|
|
||
| ```bash | ||
| uv run scripts/steady_state_diagnostics.py <run>/events.jsonl \ |
There was a problem hiding this comment.
Is the expectation here that we will "fix" this command for a particular benchmark (across all systems)?
The ramp crop is data-driven off TPOT p50 (smooth per super-pass; TTFT too volatile under closed-loop admission), symmetric band around the back-half median, capped at half the run. Matches the shipped scripts/steady_state_diagnostics.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Post-processing step (and ad-hoc CLI over events.jsonl) that reports steady-state metrics — super-pass windowing, guarded drain-tail cut, CoV ensemble + trend gate (drift up/down), hairball, edge-case handling.
What does this PR do?
Adds a design doc for a new steady-state window detection and metrics reporting feature
Type of change
Related issues
cc @arekay-nv to tag any related issues
Testing
Checklist