Skip to content

feat(yoco): add --kv-sharing-fast-prefill server arg + validators (PR-A/3) - #11

Draft
pyc96 wants to merge 1 commit into
pyc/sota-gemma4-31b-mm-disabledfrom
pyc/yoco-fast-prefill-config
Draft

feat(yoco): add --kv-sharing-fast-prefill server arg + validators (PR-A/3)#11
pyc96 wants to merge 1 commit into
pyc/sota-gemma4-31b-mm-disabledfrom
pyc/yoco-fast-prefill-config

Conversation

@pyc96

@pyc96 pyc96 commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

Stack of 3 PRs that port vLLM's YOCO fast-prefill optimization for Gemma-4 to SGLang. This is PR-A/3: flag plumbing + validators only, no model behavior change.

Background

vLLM's Gemma-4 implementation (vllm/model_executor/models/gemma4.py:759-952, 1190-1273) splits the decoder into two halves: the first K = N - num_kv_shared_layers layers run on the full extend-token batch (the "self-decoder"), and the last num_kv_shared_layers layers (the "cross-decoder") run only on the per-request last-extend-token rows. Because those last layers reuse K/V from earlier layers and never write KV themselves, their compute is only needed at the positions that feed the LM head.

For Gemma-4 31B-IT on H100+TP=2+triton+MTP, the current SGLang summ 8000/1000 throughput is 331 tok/s vs vLLM 868 tok/s (gap -62%). The vLLM-vs-SGLang audit at `agent-pod/runs/20260523_gemma4_31b_it_h100_sota_humanize/yoco/{draft,plan}.md` shows YOCO is the structural source of vLLM's prefill advantage; this stack ports it to SGLang.

What's in PR-A

Flag plumbing + cross-cutting validators. No model behavior change — the YOCO branch lands in PR-B and the benchmarks in PR-C.

File Change
`python/sglang/srt/server_args.py` New `kv_sharing_fast_prefill: bool = False` dataclass field; argparse `--kv-sharing-fast-prefill` (store_true); Gemma-4 branch validators (triton-backend pin, `num_kv_shared_layers > 0`); new `_validate_kv_sharing_fast_prefill_combos` helper called from `check_server_args` (rejects EAGLE/EAGLE3).
`python/sglang/srt/configs/model_config.py` New `kv_sharing_fast_prefill` kwarg on `ModelConfig.init`; `from_server_args` plumbs the flag through.
`test/registered/unit/server_args/test_kv_sharing_fast_prefill.py` 8 unit tests: dataclass default, CLI parse, argparse registration, ModelConfig plumbing, EAGLE rejection, EAGLE3 rejection, NEXTN accepted, flag-off no-op.

Behavior

  • Default: `--kv-sharing-fast-prefill` is off. No effect on any existing deployment.
  • When set on a Gemma-4 server with `--attention-backend triton` and a model that has `num_kv_shared_layers > 0`: logs `"KV-sharing fast prefill enabled for (num_kv_shared_layers=N)"` at startup. No runtime behavior change yet (PR-B wires it).
  • When set on a non-Gemma-4 model, or with a non-triton backend, or with `num_kv_shared_layers == 0`: clear `ValueError` at startup.
  • When set with `--speculative-algorithm EAGLE` or `EAGLE3`: clear `ValueError` (these spec algos need per-token logits, which YOCO can't provide).
  • When set with `--speculative-algorithm NEXTN` (which Gemma-4 promotes to FROZEN_KV_MTP for the assistant draft): accepted.

Tests

```
python test/registered/unit/server_args/test_kv_sharing_fast_prefill.py
...
Ran 8 tests in 0.860s
OK
```

Benchmark / MMLU

No runtime change — these will appear in PR-C. For reference, the current SGLang best on the campaign workload (`google/gemma-4-31B-it`, H100+TP=2+triton+MTP, 80 prompts, warmup 2, seed 1) on the parent branch `pyc/sota-gemma4-31b-mm-disabled` is:

Scenario SGLang vLLM Gap
chat 1k/1k tok/s 1499 2827 -47.0%
chat 1k/1k median TTFT 2777 ms 4689 ms -40.8% (SGLang wins)
summ 8k/1k tok/s 331 868 -61.9%
summ 8k/1k median TPOT 23.4 ms 31.8 ms -26.4% (SGLang wins)
MMLU N=500 0.780 0.778 +0.2 pp

This stack targets the summ tok/s and TTFT gap. PR-C will report new numbers.

Diff noise note

`python/sglang/srt/server_args.py` shows 401 lines changed (255 inserts / 146 deletes) but only ~50 of those are my real changes. The rest is an auto-format reflow (`assert (cond), "msg"` → `assert cond, ("msg")`) triggered by a recent ruff format rule on every edit-and-save in this repo. The real changes are the four blocks at lines ~684 (field), ~6213 (argparse), ~2240 (Gemma-4 branch validators), and ~7109 (helper + call). Easy to audit by greping for `kv_sharing`.

Stack

  • PR-A (this PR): flag plumbing + validators
  • PR-B: model-side YOCO branch in `Gemma4TextModel.forward` (gather → cross-decoder → scatter, + triton attention metadata builder for the back-half phase, + 4 unit tests, + per-prompt parity test)
  • PR-C: benchmark + tuning results table + campaign checkpoint update

Stack base: `pyc/sota-gemma4-31b-mm-disabled` @ `3a3195b30`

Plan: `.humanize/yoco-gemma4/refined-plan.md` (also at `runs/20260523_gemma4_31b_it_h100_sota_humanize/yoco/plan.md`)


CI States

Latest PR Test (Base): ❌ Missing run-ci label -- add it to run CI tests.
Latest PR Test (Extra): ❌ Blocked -- run-ci is required first.

…-A/3)

Introduce an opt-in server flag for the YOCO-style fast-prefill optimization
that vLLM ships for Gemma-4 (Gemma4SelfDecoderLayers / Gemma4CrossDecoderLayers
in vllm/model_executor/models/gemma4.py). When enabled, the last
num_kv_shared_layers decoder layers will eventually run only on the
per-request last-extend-token rows during EXTEND-mode forwards (model-side
implementation lands in the follow-up PR).

This first PR in a stack of three contains only the flag plumbing and the
cross-cutting validators that don't depend on the live model.

Changes:
* ServerArgs.kv_sharing_fast_prefill: bool dataclass field (default False)
* argparse --kv-sharing-fast-prefill (store_true)
* ModelConfig.__init__ accepts kv_sharing_fast_prefill keyword
* ModelConfig.from_server_args propagates the flag
* Gemma-4 branch of _handle_model_specific_adjustments validates:
  - triton backend (prefill + decode) when the flag is on
  - num_kv_shared_layers > 0 on the served model's text config
  - logs 'KV-sharing fast prefill enabled for <arch>' on success
* ServerArgs._validate_kv_sharing_fast_prefill_combos (new helper)
  rejects --speculative-algorithm EAGLE / EAGLE3 with the flag on.
  Called from check_server_args(); factored out so it's unit-testable
  without a live HF config.
* test/registered/unit/server_args/test_kv_sharing_fast_prefill.py:
  8 unit tests covering the dataclass default, CLI parsing, argparse
  registration, ModelConfig plumbing, and all four validator branches
  (EAGLE rejected, EAGLE3 rejected, NEXTN accepted, flag-off skipped).

Default-off, opt-in only; no behavior change for existing deployments.

The diff in server_args.py contains some auto-format noise (assert (cond),
'msg' -> assert cond, ('msg')) from a ruff format rule that triggers on
save. The real changes are the four blocks cited above.

Stack base: pyc/sota-gemma4-31b-mm-disabled @ 3a3195b
Next: PR-B (model-side YOCO branch in Gemma4TextModel.forward) and
      PR-C (benchmark + tuning).

Plan: .humanize/yoco-gemma4/refined-plan.md
Co-authored-by: Claude
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