Skip to content

feat(gemma4): the sliding family serves an opt in fp8 KV pool - #1012

Open
FeathBow wants to merge 6 commits into
pegainfer-project:mainfrom
FeathBow:feat/gemma4-fp8-kv
Open

feat(gemma4): the sliding family serves an opt in fp8 KV pool#1012
FeathBow wants to merge 6 commits into
pegainfer-project:mainfrom
FeathBow:feat/gemma4-fp8-kv

Conversation

@FeathBow

Copy link
Copy Markdown
Collaborator

Description

Closes #1010

PEGAINFER_KV_FP8=local stores the sliding family's K/V as e4m3 at scale 1.0, halving the decode step's dominant KV read; unset serves byte-identically to before. The reference engine defaults to exactly this scheme for the checkpoint, so the two engines finally read the same bytes per step.

The pool layout carries an element width, the geometry gate converts the backing length by it, and the shared launch header takes the KV element type as a template parameter: a gemma4 translation unit instantiates the two hd256 windowed reads over e4m3 while the bf16 instantiations and bindings stay where they are, and the hd256 prep kernel takes a store type the same way. Wrappers without an fp8 twin refuse a one-byte layout at the operator boundary, and the prefix-cache combination is refused at startup because its page copies index bf16 elements.

Test Env

Single GPU (sm_89, 48 GiB, x86_64).

Verification

Results from the box run on the carve; the accuracy legs decide whether this opens.

  • cargo fmt --all -- --check and git diff --check against main pass; the Gemma 4 release server builds; the qwen3 default build (no gemma4 feature) builds; all-target kernels/Gemma/core Clippy passes with -D warnings; release lib tests pass; the kernel GPU suites pass 21/21.
  • Unset: the 26B checkpoint answers four greedy public /v1/completions requests (31-, 35-, 33- and 1421-token prompts, 64 forced tokens) with bytes identical to main's binary, md5 219de1e3c09c.
  • Startup refusals: PEGAINFER_KV_FP8=local with PEGAINFER_PREFIX_CACHE set exits with "the prefix cache copies pool pages in bf16 element units"; PEGAINFER_KV_FP8=global exits with "supports only "local"".
  • fp8, gates under PEGAINFER_KV_FP8=local: the greedy HF generation gate passes token for token; the ragged-batch row-order gate and the eviction gate pass; the 16K waypoint gate fails at the window-edge waypoint (w1023: top-1 5/9 below backend bar 6/9; every other waypoint within tolerance); the mixed-step-against-serial gate, bit-exact under bf16, diverges under fp8 on the window-crossing partner; the shared-lane lifecycle gate configures the prefix cache and is refused at startup by design.
  • fp8, determinism and composition: the four prompts from two fresh fp8 starts carry one md5; the same prompt at c1 and as four identical concurrent requests differs on both the bf16 and the fp8 pool alike (the engine's known composition dependence, not the pool's); the fp8 texts first diverge from the bf16 texts at the 31st, 24th, 10th and 20th word and stay coherent.
  • Serving A/B on the one binary, bf16 pool against fp8 pool, vllm bench serve random 1024 in / 128 out at 8 / 24 / 64 prompts, two cooled alternating rounds, output tok/s as mean [range]: c1 106.3 [106.0–106.5] → 105.1 [105.0–105.2]; c4 279.8 [279.1–280.4] → 285.0 [284.2–285.7]; c16 595.0 [591.4–598.5] → 629.1 [627.5–630.6]; median TPOT at c16 23.92 → 22.10 ms.

Signed-off-by: Feathbow <feathbow@gmail.com>

@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: fe393f7564

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread pegainfer-gemma4/src/serve.rs Outdated
Err(std::env::VarError::NotPresent) => Ok(2),
Ok(value) if value == "local" => {
anyhow::ensure!(
std::env::var_os("PEGAINFER_PREFIX_CACHE").is_none(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat disabled prefix-cache values as disabled

When FP8 is enabled in an environment that explicitly disables caching with PEGAINFER_PREFIX_CACHE=0, off, or an empty string, this raw presence check rejects startup even though parse_prefix_cache_cap in engine.rs normalizes all three spellings to None. This breaks an otherwise supported deployment configuration; base the incompatibility check on the parsed cache capacity rather than whether the variable exists.

Useful? React with 👍 / 👎.

Comment thread pegainfer-gemma4/src/serve.rs Outdated
Comment on lines +658 to +659
fn local_kv_elem_bytes() -> Result<usize> {
match std::env::var("PEGAINFER_KV_FP8") {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Document the FP8 serving contract

This introduces a production environment variable, a prefix-cache incompatibility, changed pool memory consumption, and approximate-output behavior without updating docs/models/gemma4/serving.md or the repository's key-env-var list. Operators therefore cannot discover or safely configure the feature from the repository documentation; document the knob, supported value, incompatibilities, memory envelope, and accuracy tradeoff alongside the existing Gemma serving controls.

AGENTS.md reference: AGENTS.md:L176-L178

Useful? React with 👍 / 👎.

…riable

Signed-off-by: Feathbow <feathbow@gmail.com>
Signed-off-by: Feathbow <feathbow@gmail.com>
PagedKvLayout and KvLayout carry KvStorage::{Bf16, E4m3} instead of a
public byte count, so an illegal width is unrepresentable and the
geometry gate dispatches on the enum rather than defaulting everything
that is not exactly one byte to bf16. The three fp8 dispatch sites name
the entry point that actually ran when they fail. PEGAINFER_KV_FP8
parses once in the engine beside the other knobs, before the checkpoint
loads, and GemmaServe receives the storage as a parameter; the second
raw-env interpretation in serve.rs is gone, and the enabled-prefix-cache
refusal keeps its message.

Signed-off-by: Feathbow <feathbow@gmail.com>
…inned

Signed-off-by: Feathbow <feathbow@gmail.com>
…gine's own floor

Signed-off-by: Feathbow <feathbow@gmail.com>
@FeathBow
FeathBow force-pushed the feat/gemma4-fp8-kv branch from a40bef6 to 552de78 Compare August 30, 2026 20:49
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.

gemma4: the sliding family stores KV at twice the width its window needs

1 participant