Skip to content

Align every GEAK benchmark on the Hyperloom warm-server protocol - #437

Draft
yueliu14 wants to merge 2 commits into
mainfrom
feat/warm-server-bench-align
Draft

Align every GEAK benchmark on the Hyperloom warm-server protocol#437
yueliu14 wants to merge 2 commits into
mainfrom
feat/warm-server-bench-align

Conversation

@yueliu14

@yueliu14 yueliu14 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

GEAK's validation measured throughput as the median of 3 isolated-server replicas, while the Hyperloom orchestrator that rebenches the very same kernel measures one warm round: boot the server, run a full untimed round, report the second pass. Two different statistics over the same kernel is how the two sides ended up disagreeing about whether a win was real.

Why

This is not hypothetical. From GEAK's own KB (e2e_workflow/knowledge/learned/moe-fp8-blockscale-tune-gfx950.md), Qwen3.5-122B-A10B-FP8, TP=2, gfx950/MI355, fp8 block[128,128] MoE at 21.4% of GPU time:

measurement verdict
milestone interleaved A/B +1.36%, ranges non-overlapping, byte-exact parity 12/12
Director same-session A/B +0.16% (1.0016x), ranges overlapping -> validated_no_win

The difference was the baseline moving underneath the comparison: base median rose from 2405.9 (warm-start) to 2451.5 (same-session), so most of the apparent gain was drift, not the kernel. Note that the wrong answer was the more convincing-looking one — non-overlapping ranges plus byte-exact parity. It also shows byte-exact parity is not evidence of a throughput win.

One lifecycle for every throughput number is the fix.

What changes

  • warm_server becomes the default lifecycle in bench_e2e.sh, and the default for the search, parity and validation purposes in e2e_workflow.js / run_e2e.py. REPEATS defaults to 1: one timed round is the protocol, not a truncation of it. Carve-outs for REPEATS=0 (shape capture) and PROFILE=1, which produce no throughput number and so have no lifecycle to align.
  • isolated_server stays available for boot-to-boot dispersion, opt-in only, with its own validation_measurement_mode / validation_replicas knobs so an operator can make the final arbitration stricter than the search that fed it.
  • Delete E2E_REPEATS. It was prompt-only — no role doc or script ever read it.
  • Extract the two summary emitters out of bench_e2e.sh into scripts/bench_summarize.py (from-runs / from-replicas). They were duplicated heredocs with no test, and every acceptance decision in the product reads their output; a contract field added to one and not the other produced two bench_summary.json shapes with nothing to catch it. bench_e2e.sh 1053 -> 851 lines.
  • Docs and role prompts updated to describe the protocol the code actually runs, instead of the old ">=3 repeats, median + spread".

Verified

Unit: 1171 tests under e2e_workflow/scripts/tests, 168 in interface/test_run_e2e_dispatch. The new emitter is byte-identical to the old heredocs over 12 replayed input shapes.

On hardware — a direct protocol A/B. Same box, model, serving invariant and tuning bundle; adapters/ and bench_replica.sh byte-identical between the two runs, so the lifecycle is the only variable. DeepSeek-V4-Pro, vLLM, TP=8, ISL 8192 / OSL 1024 / conc 64, 192 prompts:

lifecycle base final delta wall-clock cold boots
isolated_server x3 (before) 833.298 879.030 +5.488% ~68 min 6
warm_server x1 (this PR's default) 826.936 886.571 +7.212% 30.8 min 2

Same verdict, 2.2x faster, 6 cold boots down to 2. Server boot alone was 466 s and 381 s of the two legs — that is what the extra replicas were re-paying.

The tradeoff, stated up front

The two deltas are 1.72 pp apart, and that gap is the honest cost of the change, so it should not be discovered in review.

One sample per leg means spread = 0.0% by construction — an absence of dispersion evidence, not a quiet box — and the final_min > base_max non-overlap test carries no information at all. The isolated legs measured 2.61% and 2.81% spread, so a low base draw and a high final draw compound to ~1.6 pp on their own, which accounts for the observed 1.72 pp. Read it as sampling, not as a bias between the protocols.

roles/director.md handles this explicitly rather than hiding it: under warm_server the samples share one boot, so spread is narrower than true run-to-run spread; when delta% is within 2x the noise band and only non-overlap carries the win, the Director must say so in notes and prefer validated_no_win. At one sample it must record that the dispersion test was unavailable. bench_summary.json carries measurement_mode and dispersion_basis so any consumer can tell which lifecycle produced a number.

Numbers are comparable only within one lifecycle. The header warning originally claimed warm_server "reads systematically HIGHER"; the hardware run above is a counterexample (warm 826.9 vs isolated median 833.3 — the other way, because RANDOM_RANGE_RATIO=1.0 at ISL 8192 leaves almost no shared prefix to cache). The rule is unchanged; the stated reason is now that the sign and size are not predictable from the config alone.

Out of scope

An earlier revision of this branch also loosened the gsm8k accuracy gate (tol 0.01 -> 0.03, plus an absolute 0.5 floor). That has been reverted here. The argument stands on its own, but it is a gate-policy change rather than a measurement-protocol one, and bundling it would force this PR to be accepted or rejected as a unit. It will come back as its own PR with its own evidence.

🤖 Generated with Claude Code

yueliu14 and others added 2 commits August 27, 2026 15:40
GEAK's validation measured throughput as the median of 3 rounds while the
Hyperloom orchestrator that rebenches the same kernel measures one warm round:
boot the server, run a full untimed round, report the second pass. Two different
statistics over the same kernel is how the two sides disagreed on whether a win
was real.

* warm_server is now the default lifecycle in bench_e2e.sh, and the default for
  the search, parity and validation purposes in e2e_workflow.js / run_e2e.py.
  REPEATS defaults to 1: one timed round IS the protocol, not a truncation of it.
  Carve-out for REPEATS=0 (shape capture) and PROFILE=1, which produce no
  throughput number and so have no lifecycle to align.
* isolated_server stays available for boot-to-boot dispersion, opt-in only.
* Delete E2E_REPEATS. It was prompt-only -- no role doc or script ever read it.

Accuracy gate: tol 0.01 -> 0.03 and a new absolute floor of 0.5 on both legs.
Both legs answer the same seed-pinned subset at temp=0, so the noise scale is
the discordant pairs, sd(delta)=sqrt(d)/n ~= 1.6pt at n=200. The old 0.01 sat at
0.6 sd and rejected ~1 in 4 kernels whose quality had not moved. The floor
catches the case a purely relative gate is blind to: a broken baseline that an
equally broken candidate matches.

Extract the two summary emitters out of bench_e2e.sh into scripts/bench_summarize.py
(from-runs / from-replicas). They were duplicated heredocs with no test, and
every acceptance decision in the product reads their output; a contract field
added to one and not the other produced two bench_summary.json shapes with
nothing to catch it. bench_e2e.sh 1053 -> 851 lines.

Verified: 1171 tests under e2e_workflow/scripts/tests, 168 in
interface/test_run_e2e_dispatch. The new emitter is byte-identical to the old
heredocs over 12 replayed input shapes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…-hardware check

Follow-up to a2cbefd, which shipped the lifecycle change with its prose and its
role docs still describing the old ">=3 repeats, median + spread" protocol.

* Docs/roles now say what the code does: one discarded warmup round then one
  timed round, extra samples only when a dispersion estimate is actually needed
  (PLAN.md, README.md, roles/director.md, roles/e2e_integrator.md,
  knowledge/e2e_optimization.md, knowledge/sglang_internals.md).
  preflight.md's "baseline spread > ~5% => re-measure" rung now says it applies
  only with more than one timed sample: at the default, spread is 0.0% by
  construction and there is nothing to gate on.

* REVERT the accuracy-gate knobs from a2cbefd (ACCURACY_TOL 0.03 -> back to
  0.01, drop ACCURACY_FLOOR). The tolerance argument stands on its own, but it
  is a gate-policy change, not a measurement-protocol change, and bundling it
  here makes one PR that has to be accepted or rejected as a unit. It belongs in
  its own PR with its own evidence.

* bench_e2e.sh: fold the two staged-sibling lookups (bench_summarize.py,
  server_teardown.sh) into one _stage_lookup helper -- they were the same six
  lines twice, including the same "" -> /scripts/... guard.

* Correct the comparability warning in bench_e2e.sh and api-reference.md. It
  claimed warm_server "reads systematically HIGHER" than isolated_server. That
  is only true where prefix-cache reuse is available; measured on DeepSeek-V4-Pro
  TP8 with RANDOM_RANGE_RATIO=1.0 / ISL 8192 (random prompts, ~no shared prefix)
  warm read 826.9 vs an isolated median of 833.3 tok/s -- the other way. The rule
  is unchanged (never ratio across lifecycles); the reason is now "sign and size
  are not predictable from the config alone", which the counterexample supports
  and the old wording did not.

* test_bench_e2e_teardown_lookup: set SERVING_GPU_LOCK_DISABLE=1. The two cases
  that pass the staging gate walk into the serving-GPU mutex, a real /tmp lock
  shared with any live benchmark on the box, so the suite could block for
  SERVING_LOCK_WAIT behind an unrelated run and read as a hang.

Verified on hardware (the branch had only ever been unit-tested). Same box,
model, serving invariant and tuning bundle as an isolated_server x3 validation
run earlier the same day, so the lifecycle is the only variable:

  isolated_server x3   base 833.298  final 879.030  +5.488%   ~68 min
  warm_server x1       base 826.936  final 886.571  +7.212%   30.8 min

Same verdict, 2.2x faster, 6 cold boots down to 2. The 1.72pp gap between the
two deltas is what one sample per leg buys: the isolated legs measured 2.61% and
2.81% spread, so a low base draw and a high final draw compound to ~1.6pp on
their own. Read that as the cost of the default -- comparability and wall-clock
in exchange for the dispersion test -- not as a bias between the protocols.
Unit suite unchanged at 1171 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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