6 Commits

Author SHA1 Message Date
noonghunna
f6613c869a v7.69 + #35975 + Codex P103 gate fix — Cliff 2 closure recipes
Six rounds of cross-rig bisect with Codex/ChatGPT diagnosis closes
Cliff 2 at 60K on TP=1 + 24GB. Two shippable variants:

Balanced MTP (long-text.yml updated):
- Genesis v7.69 dev tip (commit 2db18df)
- Codex r1 P103 gate fix applied to nested Genesis tree (cu_seqlens=[0,T]
  treated as dense single-seq, not multi-seq varlen). Sent to Sander as
  v7.70 proposal — diff in /tmp/cliff2_v770_cu_seqlens_response.md.
- vllm#35975 backport sidecar (patch_inputs_embeds_optional.py)
- mem-util 0.93 (down from 0.95)
- max_model_len 180000 (admission ceiling at this mem-util)
- MTP K=3 retained
- 60K probe: HTTP 200 in 623s, recall correct, MTP AL=4.00

Max-context safety (long-text-no-mtp.yml — NEW):
- Same patches, but MTP off + mem-util 0.95
- max_model_len 200000 (admission unlocked by removing MTP residency)
- 60K probe: HTTP 200 in 537s, recall correct
- 90K probe: indeterminate within 25-min curl budget
- For long single-shot RAG / codebase analysis

Diagnostic chain:
1. Codex r1 identified P103 gate as too broad (cu_seqlens != None
   bypasses chunking even for single-seq [0,T] case). Applied fix.
2. T=4128 distribution showed chunked path never engages on real
   serving (vLLM's outer chunked-prefill caps T well below MAX_T).
3. Codex r2: real Cliff 2 source is residency, not gate logic.
4. PR #35975 backport (skip inputs_embeds for text-only) frees
   444 MiB at boot — necessary but not sufficient at 0.95 mem-util.
5. mem-util sweep at 0.92/0.93 with MTP+#35975 closed Cliff 2 at 60K.
6. MTP-off + 0.95 + 200K admission validated max-context variant.

Codex's P103 gate fix is semantically correct and worth shipping in
Genesis v7.70 even though it's not what closes 60K Cliff 2 on this
config (the FLA call sees T=4128 already, well below MAX_T).

Full diagnostic trail: results/v0.20-migration/v769-codex-r1-test.summary

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 15:24:49 +00:00
noonghunna
7a7efbea0d bump Genesis pin 753344b → fc89395 (v7.66 dev tip)
v7.66 ships 3 new patches relevant to our config:
- PN33 (default ON): spec-decode warmup K-aware sizing, vllm#37521 backport
  EXTENDED beyond EAGLE to cover MTP/ngram. Sander claimed it closes both
  ampersandru's mid-stream OOM AND our workspace_lock AssertionError.
- PN25 v7.66: refactored from `@torch.library.custom_op` to
  `direct_register_custom_op` + `Library("genesis", "FRAGMENT")` at module
  level. Schema introspection at import time eliminates the
  `infer_schema skipped frame` Dynamo crash class.
- PN32 (default OFF): GDN chunked-prefill for Cliff 2 single-24GB-GPU OOM.

Cross-rig validation findings on 1×3090 TP=1
--------------------------------------------

**PN33 partial — narrows but does not close workspace_lock on TP=1.**

Sander's claim was that PN33 closes both ampersandru's mid-stream OOM
AND our workspace_lock AssertionError. Tested both:

| Test                                       | PN33 result      |
|--------------------------------------------|------------------|
| Engine boot (profile_run workspace lock)   |  closed       |
| Runtime decode (`turboquant_attn.py:1350`) |  still fires  |

Engine boots cleanly without `patch_workspace_lock_disable.py` sidecar
when PN33 is on, BUT the first decode request crashes with the same
`AssertionError: Workspace is locked but allocation from
turboquant_attn.py:1350:_decode_attention requires 0.76 MB`.

Net: keep `patch_workspace_lock_disable.py` sidecar mounted. PN33
narrows the bug surface but doesn't close it for our config.

**PN25 v7.66 still doesn't work on TP=1.**

Sander's `direct_register_custom_op` + `Library("genesis", "FRAGMENT")`
approach replaces v7.65's `@torch.library.custom_op`, eliminating the
`infer_schema` skipped-frame issue. But on TP=1 the new failure mode is
`Library("genesis", "FRAGMENT")` itself failing inside dynamo trace at
`instantiate_user_defined_class_object` (different mechanism, same root
cause: Library construction inside trace context disallowed on TP=1).

Net: keep `patch_pn25_genesis_register_fix.py` v3 (import-time approach).
Our patch text-patches activation.py to register the op at module-import
time as a cached global, BEFORE any trace context exists. Survives both
the v7.65 `@custom_op` and v7.66 `Library` failure modes because we
register outside the trace entirely.

**PN30 dst-shaped temp fix carries forward cleanly.**

Our `patch_pn30_dst_shaped_temp_fix.py` anchor still matches v7.66's
PN30 wiring file. All 4 TQ3 composes still pass probes 4 + 5 (multi-turn
agent, LCB-coding) which would otherwise crash with Sander's upstream
PN30 a9977d8 (compact `.contiguous()` row-stride corruption — see
genesis-vllm-patches#17 reply for the diagnosis).

**PN31 still doesn't fit on 24 GB.** Same memory pressure as v7.65 round.

Validation matrix on v7.66
--------------------------

| Compose            | Probes (verify-stress.sh)                |
|--------------------|-------------------------------------------|
| long-text          | 6/7  (Cliff 2 only fail)               |
| long-vision        | 6/7  (Cliff 2 only fail)               |
| bounded-thinking   | 6/7  (Cliff 2 only fail)               |
| dual-turbo (TP=2)  | 6/7  (Cliff 2 only fail)               |

Same coverage as v7.65 + our patches. No new regressions on v7.66.

Net effect of pin bump
----------------------

- Get Sander's v7.66 + PN33 (validated improvement, even if partial)
- Get PN32 available for opt-in (Cliff 2 mitigation, untested by us)
- Same 3 local sidecars retained (PN25 v3, PN30 fix, workspace_lock)
- No simplification possible yet

Per-config + cross-rig summary in
results/v0.20-migration/v766-pin-results.summary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 03:40:06 +00:00
noonghunna
b875624f2d extend PN25 v3 + PN30 dst-shaped temp fix to all 4 TQ3 composes
PR #23 + PR a62ad78 + PR 9af1a52 shipped PN25 v3 + PN30 dst-shaped temp
fix on long-text only. This commit extends the same patch stack to the
remaining 3 TQ3 composes (long-vision, bounded-thinking, dual-turbo) and
validates each independently.

What changed
------------

- **long-vision.yml**: 198K + 0.98 → **145K + 0.95** + DS layout +
  PN25 v3 + PN30. Vision tower residence forces deeper backoff than
  long-text (engine pre-check returned `estimated max 148608` at 175K +
  0.95, settled at 145K with safety margin).
- **bounded-thinking.yml**: 214K + 0.985 → **180K + 0.95** + DS layout +
  PN25 v3 + PN30. Parity with long-text — same patch stack, same backoff,
  structured-CoT grammar still works on top.
- **dual-turbo.yml**: 262K context preserved + DS layout + PN25 v3 + PN30.
  TP=2 splits state across both cards, fits the patch stack at 0.85
  mem-util cleanly.

Validation per compose (verify-stress.sh, 7 probes)
---------------------------------------------------

| Variant            | Pass count | Failure              |
|--------------------|------------|----------------------|
| long-text          | 6 / 7      | Cliff 2 architectural |
| long-vision        | 6 / 7      | Cliff 2 architectural |
| bounded-thinking   | 6 / 7      | Cliff 2 architectural |
| dual-turbo (TP=2)  | 6 / 7      | Cliff 2 architectural |

All non-architectural probes pass — IDE-agent one-shot, multi-turn agent,
LCB-coding, reasoning-heavy, 25K tool RETURN, small-rung longctx. Cliff 2
(60K+ single prompt DeltaNet GDN forward state OOM) fails on every
variant including TP=2 because GDN state is per-rank not split — that's
fundamental, not addressable on this config class.

Per-config summaries written to:
- results/v0.20-migration/long-vision-pn30.summary
- results/v0.20-migration/bounded-thinking-pn30.summary
- results/v0.20-migration/dual-turbo-pn30.summary

Docs partial update (SINGLE_CARD.md): updated TL;DR table with new ctx
ceilings and removed the Cliff 1 mech B "limitation to know" since both
mechanisms (PN12 eager + PN25 v3 compile) now close it. Kept Cliff 2 as
the one remaining limitation. More doc updates in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 02:22:21 +00:00
noonghunna
0bdcb69fa3 results: re-bench dual.yml + dual-dflash + dual-dflash-noviz on v0.20
Closes the "dual variants not yet re-benched on v0.20" caveat from PR #23.
Confirms no v0.20 regression on fp8 / FP16 paths — code TPS within bench
variance of chart values across all 3.

n=5 measured + 3 warmup per prompt:

| Variant            | Chart (prior) narr / code | v0.20 measured narr / code | Δ                       |
|--------------------|----------------------------|------------------------------|-------------------------|
| dual.yml           | 69.05 / 88.58              | 68.61 / 90.71  (CV 1.8% both) | narr -0.6% / code +2.4% |
| dual-dflash.yml    | 81.94 / 124.93             | 77.12 / 125.97 (CV 2-4%)      | narr -5.9% / code +0.8% |
| dual-dflash-noviz  | 78.19 / 126.99             | 78.94 / 123.18 (CV 2-3%)      | narr +1.0% / code -3.0% |

dual-dflash narrative is the only delta outside CV (-5.9%); could be
substrate (different driver / power state at chart capture) or a minor
DFlash N=5 spec-decode regression on v0.20. Chart value stays — within
±5pp of measured, within bench noise band.

Both dual.yml and dual-dflash* are "Genesis-less by design" (zero Genesis
env vars). The migration only bumped the image SHA on these — no env-var
changes — which is consistent with the flat result. The +50% TPS jump
on TQ k8v4 we reported to Sander in discussion #19 came from enabling
his full PROD env-var stack on the TQ KV path; fp8 / FP16 dual paths
don't share the same patches and don't exhibit a similar bump.

Updated `docs/DUAL_CARD.md` performance summary table with the new
measured numbers + a per-variant Δ column. Per-config summaries written
to `results/v0.20-migration/dual-{yml,dflash,dflash-noviz}.summary`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:34:28 +00:00
noonghunna
077228e81b results: dual-turbo re-bench with corrected env vars (PN22 / PN26 naming fix)
Post-merge follow-up to PR #23. Captures the dual-turbo TP=2 bench after the
env-var naming fixes (PN22 / PN26 sub-config) actually fire, vs the prior
bench where they were silently no-op.

Honest finding: PN22's advertised "+9-30% TPS on TP>=2" (per PR author of
vllm#39419) doesn't materialize at our small bench sample sizes (n=2 runs/
stream, n=4 streams = 8 total runs at high CV).

| Metric | Prior (PN22 silently OFF) | Fixed (PN22 firing) | Δ |
|---|---|---|---|
| n=1 code wall_TPS    | 76.01 | 76.71 | +0.9% (within CV 4-5%) |
| n=4 aggregate        | 269.03 | 242.94 | -9.7% (within bench-size variance) |
| PN22 boot status     | "PN22=1" matches no env_flag — silent OFF | APPLY (vllm#39419 backport) |
| PN26 sparse-V status | BLOCK_KV / NUM_WARPS / THRESHOLD silently using defaults | 27B-tuned values applied |

The naming corrections are real bugs regardless of TPS impact — PN22 / PN26
sub-config are now actually firing on master. Effect may be more visible at
sustained high batch sizes (Sandermage's PROD bench at 100t × 50-req sustained)
where local-argmax dominates the draft-path latency budget more than at our
single-shot 800-token bench.

Headline numbers from PR #23 (76.01 code / 269 aggregate at n=4) remain the
right reference for docs and charts — re-bench is within noise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:56:35 +00:00
noonghunna
5aa97a25d9 v0.20 migration + Genesis v7.65 dev tip + cold-start cache + env-var alignment
This branch migrates the entire vLLM stack from `dev205+g07351e088` + Genesis
v7.64 to `0.20.1rc1.dev16+g7a1eb8ac2` + Genesis v7.65 dev tip (commit
`d89a089`). v7.65 is on Sandermage's `dev` branch — explicitly the cross-rig
testing surface he requested in discussion #19; he'll merge dev→main once we
both confirm stable. Pin gates restated when that lands.

What changes
------------

Pin migration:
- vLLM image: nightly-07351e08... → nightly-7a1eb8ac2... (dev205 → v0.20.1rc1.dev16)
- Genesis: 64dd18b (v7.64) → d89a089 (v7.65 dev tip)

Sidecar churn:
- DROPPED: patch_pn12_ffn_pool_anchor.py (PN12 native on v0.20)
- DROPPED: patch_pn12_compile_safe_custom_op.py (Genesis P38B in-source hook)
- DROPPED: patch_fa_max_seqlen_clamp.py (Genesis PN17 + P15B)
- ADDED: patch_workspace_lock_disable.py (relaxes vllm#39226 strict assertion;
  P98 covers same surface but auto-skips on v0.20 due to drift-marker false
  positive — pending Sandermage marker fix)

Env-var alignment to Sandermage's PROD set (start_27b_int4_TQ_k8v4.sh@dev):
- FIXED naming bugs that silently no-op'd patches:
  - PN9_INDEPENDENT_DRAFTER_ATT → _ATTN (was silently OFF)
  - PN22 → PN22_LOCAL_ARGMAX_TP (was silently OFF)
  - PN26_BLOCK_KV → PN26_SPARSE_V_BLOCK_KV (fell back to default 4, not 8)
  - PN26_NUM_WARPS → PN26_SPARSE_V_NUM_WARPS
  - PN26_THRESHOLD → PN26_SPARSE_V_THRESHOLD (fell back to default 0.001, not 0.01)
- ADDED explicit-OFFs to match Sander's PROD verbatim:
  - P78_TOLIST_CAPTURE_GUARD=0 (we use our own patch_tolist_cudagraph.py)
  - P81_FP8_BLOCK_SCALED_M_LE_8=0 (FP8-specific, no-op on TQ3)
  - P82=0, P82_THRESHOLD_SINGLE=0.3
- Cap divergence (justified): PROFILE_RUN_CAP_M=4128 + PREALLOC_TOKEN_BUDGET=4128
  (Sander uses 4096 — vLLM `interface.py:639` forces our config's Mamba
  block_size to 4128 due to TQ3 + TP=1 page-size math; lower values
  AssertionError at boot)
- Carry-forward (intentional): P4 (hybrid TQ required), P65 (TQ spec-CG
  downgrade — pending v0.20 verification that #40880 closure makes it
  redundant)

Cold-start cache mounts (closes #22):
- All 10 composes now mount torch_compile_cache + Triton cache from
  `models/qwen3.6-27b/vllm/cache/`. First boot warms (~6 min); warm boot
  drops to ~3.2 min (47% faster). Per-stage savings on long-text:
  - Dynamo bytecode transform: 18s → 5s (-73%)
  - torch.compile: 57s → 9s (-85%)
  - Initial profiling/warmup: 51s → 7s (-87%)

Mamba block_size cap fix:
- v0.20 enforces `long_prefill_token_threshold >= block_size`; on hybrid
  Mamba+TQ3, vLLM forces block_size=4128. Bumped GENESIS_PROFILE_RUN_CAP_M
  and PREALLOC_TOKEN_BUDGET 4096→4128 across all 5 main composes.

Default 48K compose:
- Required workspace_lock_disable sidecar after initial v0.20 boot hit
  vllm#39226 strict assertion. Caught during validation, fixed.

Context restored vs dev205 backoffs (validated 33K + 50K stress on v0.20):
- long-text:        185K → 214K (+16%)
- long-vision:      140K → 198K (+41%)
- bounded-thinking: 185K → 214K (+16%)

Bench results (n=5, results/v0.20-migration/):
- long-text 214K        narr 49.74 / code 67.39 (CV 2.6/2.7%)
- long-vision 198K      narr 50.32 / code 66.12 (CV 2.3/4.1%)
- bounded-thinking 214K narr 49.77 / code 65.80 (CV 1.4/2.3%)
- tools-text 75K (fp8)  narr 53.32 / code 69.66 (CV 2.3/1.4%)
- dual-turbo 262K (TP=2) narr 58.33 / code 76.01 per-stream
                         269 TPS aggregate at n=4 streams (3.63x speedup)
- default 48K           narr 48.82 / code 65.98 (n=3)

Validation: verify-full 8/8 on every variant. verify-stress 33K AND 50K
tool-prefill PASS on every variant — the cliff that fired on EVERY dev205
config no longer reproduces.

Docs + charts:
- README + SINGLE_CARD + DUAL_CARD + CLIFFS + EXAMPLES + STRUCTURED_COT
  + FAQ + UPSTREAM + 3 engine docs + model README + INTERNALS + CHANGELOG
  all updated with new pin, ctx, TPS numbers, and "v0.20 unblock" section
- performance.{png,svg} + variants regenerated with measured TPS
- vram-budget.{png,svg} + variants regenerated with measured VRAM
- UPSTREAM tracker: 5 issues moved  closed (PR #12, #13, #14, #15, P104
  superseded by PN17 + P15B)

Issues addressed:
- #16 (Cliff 1 mech B leaks past PN12 on inductor-compiled FFN) — partial:
  v0.20's revised TQ FA paths close the synthetic stress; PN25 (Sander's
  proper compile-path opaque-op fix) is on dev but explicitly opt-in pending
  worker-fork registration fix. Workarounds documented (tools-text fp8 path
  / --enforce-eager) until Sander ships PN25 default-on.
- #20 (launch.sh port + container-name mismatch) — already closed by
  77ca576 (post-issue-filing).
- #22 (cold-start caching) — closed by cache mounts above.

Remaining caveats:
- Cliff 2 (DeltaNet GDN forward, single prompt ≥50-60K) unchanged —
  architectural, applies to all single-card vLLM TQ3 paths. Mitigation:
  dual-turbo TP=2 (state splits across cards) or llama.cpp 262K.
- Default 48K narr_TPS (48.82) slightly under chart's 55 reference —
  bench variance + sample size n=3; not regression.
- Dual.yml / dual-dflash* not re-benched on v0.20; numbers carry forward
  from dev205 (fp8 paths were not TPS-changed by the migration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:33:01 +00:00