Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
230 commits
Select commit Hold shift + click to select a range
fcdabd5
start: Add staged page-level prefix reuse
Apr 26, 2026
49e5130
Implement page-level prefix cache reuse
lausannel Apr 26, 2026
dabe7b2
Fix prefix reuse exact duplicate prefill drift
lausannel Apr 26, 2026
968f4fa
Merge staged page-level prefix reuse branch
lausannel Apr 26, 2026
b2b6965
Add safe prefix reuse scheduling guards
lausannel Apr 27, 2026
de62491
Restore batch-level prefill offload drain
lausannel Apr 27, 2026
28ac33d
Backport deterministic batch sampling sync
lausannel Apr 27, 2026
a17cc3f
Merge remote-tracking branch 'origin/main' into tmp-prefix-main-merge…
lausannel Apr 27, 2026
0a51c0e
Use legacy host KV release without shared prefix
lausannel Apr 27, 2026
e9bf52c
Keep prefix-only sync out of no-prefix runs
lausannel Apr 27, 2026
8797ecb
Keep GPT-OSS no-prefix prefill offload async
lausannel Apr 27, 2026
ef8d0e4
Avoid pool-mode completion detokenize on worker ranks
lausannel Apr 27, 2026
a105db0
Keep plain host KV offload on legacy path
lausannel Apr 27, 2026
a60d566
Use backend page lookup for non-prefix host KV loads
lausannel Apr 27, 2026
5f9ed96
Use legacy batch release without shared prefix
lausannel Apr 27, 2026
990427a
Clear completed pool batch before next admission
lausannel Apr 27, 2026
e8fabe2
Keep GPT-OSS no-prefix attention call unchanged
lausannel Apr 27, 2026
42b0db3
Bypass prefix decode isolation when disabled
lausannel Apr 27, 2026
f19957b
Reset pool local slot allocator between groups
lausannel Apr 27, 2026
d9e4dd9
Reset pool buffer state between batch groups
lausannel Apr 27, 2026
96271e4
Keep pool sequence ids monotonic across batches
lausannel Apr 27, 2026
65e80e8
Keep no-prefix pool admission on main path
lausannel Apr 27, 2026
ea5bcc6
Use exact pointer pairs for host KV copy dedupe
lausannel Apr 28, 2026
3735dd1
Remove full KV reuse implementation plan doc
lausannel Apr 28, 2026
c7400c3
Merge remote-tracking branch 'origin/main' into tmp-prefix-main-merge…
lausannel Apr 28, 2026
b874f9d
Keep prefix reuse transparent to decode scheduling
lausannel Apr 28, 2026
486c120
Implement prefix cache eviction
lausannel Apr 28, 2026
3f7a48a
Remove fragile prefix rank cache unit test
lausannel Apr 28, 2026
761fdf4
Add prefix eviction rank cache tests
lausannel Apr 28, 2026
e2f5098
Fix active prefix eviction KV assertion
lausannel Apr 28, 2026
f5aa7dc
Evict prefix cache before prefill admission stalls
lausannel Apr 28, 2026
1a4220d
Add prefix cache diagnostics and safety tests
lausannel Apr 28, 2026
1dea7d1
Log prefix cache lookup stats
lausannel Apr 29, 2026
c853161
Allow overriding host KV shm names
lausannel Apr 29, 2026
2ed5be2
Bound host KV async offload concurrency
lausannel Apr 30, 2026
f945911
Chunk greedy argmax sampling
lausannel Apr 30, 2026
0b5c210
Bound prefix prefill offload backlog
lausannel Apr 30, 2026
6c19f23
Avoid full decode logits fp32 cast
lausannel Apr 30, 2026
e0b3ae9
Reduce greedy sampling fp32 chunk size
lausannel Apr 30, 2026
8c858cc
Reuse grouped MoE output buffers
lausannel Apr 30, 2026
21be1ed
Reset GPU KV between prefix pool groups
lausannel Apr 30, 2026
b2f422a
Reserve decode scratch in GPU KV budget
lausannel Apr 30, 2026
8e21a52
Fix cumulative decoded length after host KV reentry
lausannel Apr 30, 2026
39e17a2
Fix host KV reentry decode limit clamp
lausannel Apr 30, 2026
70e7b42
Synchronize pool prefill admission across ranks
lausannel Apr 30, 2026
2487e74
Optimize prefix reuse rank affinity lookup
lausannel May 1, 2026
d6bddf6
Avoid tiny back-to-back prefill batches
lausannel May 1, 2026
6b9a9e6
Make prefix admission page estimates reuse-aware
lausannel May 3, 2026
604f452
Add cached token usage reporting
lausannel May 4, 2026
75013bc
Refactor prefix reuse worker logic
lausannel May 4, 2026
e6e17de
Refactor prefix cache model adapters
lausannel May 5, 2026
ee313d7
Milestone 1: add dual prefix cache coordinators
lausannel May 5, 2026
c9a88ef
Milestone 2: route prefix reuse through host coordinator
lausannel May 5, 2026
393b850
Milestone 3: add GLM5 prefix-aware offload plumbing
lausannel May 5, 2026
dd194a9
Milestone 4: add GLM5 prefix-aware suffix prefill
lausannel May 5, 2026
95df342
Milestone 5: add GLM5 exact full-hit prefix replay
lausannel May 5, 2026
7616e54
Milestone 6: enable GLM5 DSA prefix reuse gate
lausannel May 5, 2026
7889749
Document local import failure policy
lausannel May 5, 2026
017da9a
Extract shared MLA prefix replay helpers
lausannel May 5, 2026
829a514
Add DeepSeek MLA prefix replay support
lausannel May 5, 2026
c230f60
Add Kimi MLA prefix replay support
lausannel May 5, 2026
3c374c4
Add MiniMax GQA prefix replay support
lausannel May 5, 2026
8765d2a
Enable prefix reuse gating for supported model backends
lausannel May 5, 2026
5a61153
Restore GPT-OSS logits casting behavior
lausannel May 5, 2026
601367e
Stop tracking local agent instructions
lausannel May 6, 2026
59db642
Merge remote-tracking branch 'origin/main' into feature/add-staged-pa…
lausannel May 6, 2026
f32322e
Centralize MLA prefix reuse adapters
lausannel May 6, 2026
b852c8e
Stop tracking prefix cache eviction plan
lausannel May 6, 2026
09667f9
Route MLA prefix reuse through prefill backend
lausannel May 6, 2026
02bbdb6
Add first-class attention forward metadata
lausannel May 6, 2026
f8973f1
Add forward metadata binding context
lausannel May 6, 2026
638f98f
Build prefill forward metadata explicitly
lausannel May 7, 2026
7b1018b
Prefer explicit metadata in prefix cache wrappers
lausannel May 7, 2026
bc4de6b
Introduce prefix-aware attention backends
lausannel May 7, 2026
e7daa7d
Consolidate MLA prefix metadata adapters
lausannel May 7, 2026
524c330
Add GPU paged-KV prefix extend path
lausannel May 7, 2026
182c029
Deduplicate prefix extend replay helpers
lausannel May 7, 2026
5bd4cbb
Fix decode GPU KV residency before metadata sync
lausannel May 7, 2026
2bd2786
Restore synchronous host KV load wait semantics
lausannel May 7, 2026
d0534af
Align GPT-OSS GQA decode call signature
lausannel May 7, 2026
4e327d9
Fix prefix prefill microbatch sampling metadata
lausannel May 7, 2026
e2ab089
Remove experimental GPU prefix extend path
lausannel May 10, 2026
79d9d68
Extract shared MLA prefix absorb helpers
lausannel May 10, 2026
7f28412
Materialize prefix reuse pages into GPU paged KV
lausannel May 10, 2026
f5eed99
Fix prefix GPU materialization cleanup flag
lausannel May 10, 2026
99e0610
Use scoped GPU KV managers for prefix materialization
lausannel May 10, 2026
96e0b99
Reduce redundant prefix materialization validation
lausannel May 10, 2026
2c826d2
Remove decode scratch memory reservation
lausannel May 10, 2026
7a918b6
Remove prefix metadata runtime validation from forward path
lausannel May 10, 2026
bf6a94c
Allow dual prefix caches to use independent host page IDs
lausannel May 10, 2026
625f692
Limit prefix GPU materialization to GQA replay
lausannel May 10, 2026
37f0eeb
Use GPU paged materialization for MLA prefix prefill
lausannel May 11, 2026
ae72ce0
Pass resolved host KV budget to workers
lausannel May 11, 2026
bb5a33d
Allocate host KV after resolving server budget
lausannel May 11, 2026
c2e993e
Revert "Allocate host KV after resolving server budget"
lausannel May 11, 2026
fef641d
Revert "Pass resolved host KV budget to workers"
lausannel May 11, 2026
6f25264
Support dual host prefix GPU materialization
lausannel May 11, 2026
8b09d75
Pass prefix materialization through GQA replay
lausannel May 11, 2026
4dd12a1
Fix MiniMax MoE decode buffer growth
lausannel May 11, 2026
06356a5
Merge remote-tracking branch 'origin/main' into feature/add-staged-pa…
lausannel May 11, 2026
5456e15
Use standard prefill batching for prefix reuse
lausannel May 11, 2026
865b629
Normalize DeepSeek checkpoint path for parameter server
lausannel May 12, 2026
83eab1b
Fix MLA MoE fused gate routing arguments
lausannel May 12, 2026
89b9d43
Fix MLA prefix replay query layout for suffix prefill
lausannel May 12, 2026
5573b95
Revert DeepSeek runtime fixes
lausannel May 12, 2026
0092425
Revert MLA extend refactor
lausannel May 13, 2026
08ac13c
Use FlashInfer for MLA prefix extend prefill
lausannel May 13, 2026
fe1f6fb
Remove legacy MLA prefix replay fallback
lausannel May 13, 2026
0f54d88
Route MLA full-hit prefill through FlashInfer
lausannel May 13, 2026
b1191f6
Stream prefix page materialization by layer
lausannel May 13, 2026
6108559
Use batched FlashAttention for GQA prefix extend prefill
lausannel May 13, 2026
dbe609d
Rename FlashInfer MLA extend prefill module
lausannel May 13, 2026
a4b2fa4
Shorten FlashInfer MLA extend module name
lausannel May 13, 2026
cfd8e55
Merge main and remove obsolete prefix cache coordinator state
lausannel May 23, 2026
7493c12
feat: support full-history SWA host KV (#159)
lausannel May 24, 2026
07ea675
Add host prefix cache coordinator
lausannel May 24, 2026
f02b501
Add non-mutating host prefix lookup estimate
lausannel May 24, 2026
617b540
Add host prefix cache metadata eviction
lausannel May 24, 2026
8661520
Fix host prefix eviction protection test
lausannel May 24, 2026
7e85dd7
Add host prefix cache clear API
lausannel May 24, 2026
271ad5d
Track host prefix pending loads
lausannel May 24, 2026
48739a0
Expose host prefix cache lifecycle stats
lausannel May 24, 2026
2b4e185
Add namespace-scoped host prefix clearing
lausannel May 24, 2026
87a861e
Factor shared memory utilities
lausannel May 24, 2026
1b594e1
Add host prefix page materialization load API
lausannel May 24, 2026
d2fbe1b
Add prefix reuse GPU materialization helper
lausannel May 24, 2026
24a1722
Share host page materialization copy logic
lausannel May 24, 2026
9e0543a
Batch GQA full-hit prefix decode
lausannel May 24, 2026
4ba65e1
Guard prefix materialization attachments during load
lausannel May 24, 2026
b7c668f
Materialize single KV group lookup results
lausannel May 24, 2026
c6232b5
Fix prefix materialization load guard ordering
lausannel May 24, 2026
6a77d21
Format added prefix cache files
lausannel May 25, 2026
bfb7031
Unify full-hit prefix prefill planning
lausannel May 25, 2026
da5eb39
Clamp prefix materialization for full hits
lausannel May 25, 2026
d5bd9c7
Route full-hit prefix reuse through extend prefill
lausannel May 25, 2026
1ccda00
Format added prefix-cache files
lausannel May 25, 2026
21776b4
Update full-hit legacy metadata expectation
lausannel May 25, 2026
235743b
Cover one-token full-hit prefix planning
lausannel May 25, 2026
7849309
Remove unused host prefix region identifiers
lausannel May 25, 2026
420c97d
Simplify prefix reuse metadata flow
lausannel May 25, 2026
790f6a9
Simplify FlashInfer MLA wrapper import
lausannel May 25, 2026
f0df1db
Remove redundant GLM host KV view check
lausannel May 25, 2026
505edfa
Prune redundant MLA prefix adapter arguments
lausannel May 25, 2026
93bb77c
Remove redundant prefix reuse validation helpers
lausannel May 25, 2026
5810ff6
Derive host prefix cache runtime configuration
lausannel May 25, 2026
63a8d64
Initialize host prefix cache coordinator lifecycle
lausannel May 25, 2026
6a2a31a
Add prefix cache prefill lookup helpers
lausannel May 25, 2026
df4f387
Propagate prefix cache usage from workers
lausannel May 25, 2026
e60db60
Add aligned prefix cache commit helpers
lausannel May 25, 2026
6ab424c
Add grouped prefix materialization bundle
lausannel May 25, 2026
a5b86dc
Collect Host KV pages for prefix commits
lausannel May 25, 2026
d10ed59
Estimate prefix cache hits during prefill
lausannel May 25, 2026
e900865
Fix prefix prefill range offload metadata
lausannel May 27, 2026
fb76049
Align prefix reuse prefill planning to page boundaries
lausannel May 27, 2026
36b912a
Clarify prefix reuse planner boundaries
lausannel May 27, 2026
028f207
Attach shared prefix pages to Host KV views
lausannel May 27, 2026
3375319
Wire prefix cache lookup into prefill admission
lausannel May 27, 2026
d1d9dac
Publish aligned Host prefix cache pages
lausannel May 27, 2026
4d1cd5e
Factor prefix cache commit publishing helpers
lausannel May 27, 2026
85246d0
Use explicit attributes in prefix reuse paths
lausannel May 27, 2026
9836455
Release GPU KV cache before prefill reload
lausannel May 27, 2026
01da6ed
Avoid reinitializing oversized decode KV cache for prefill
lausannel May 27, 2026
d701851
Report prefix cached tokens from owner ranks
lausannel May 27, 2026
43de419
Overlap prefix page materialization with layer compute
lausannel May 27, 2026
e2a33fc
Integrate host prefix eviction with multi-rate KV groups
lausannel May 28, 2026
e119073
Cover prefix eviction and multi-rate commit helpers
lausannel May 28, 2026
09d4c62
Unify prefix cache allocation and full-hit semantics
lausannel May 30, 2026
b4fee8f
Remove prefix prepack metadata adapter
lausannel May 30, 2026
a051282
Fix prefix eviction helper tests
lausannel May 30, 2026
d5c310b
Avoid prefill scheduler stall under prefix cache pressure
lausannel May 30, 2026
0aa4d9b
Use allocation eviction for prefix cache host pressure
lausannel May 30, 2026
460bc7c
Coordinate prefix cache eviction across host ranks
lausannel May 30, 2026
9254c4e
Simplify prefix cache runtime coordination
lausannel May 31, 2026
14692d2
Add prefix cache regression coverage
lausannel Jun 4, 2026
b8c6686
Remove over-specified prefix materialization wait test
lausannel Jun 4, 2026
5b33e9b
Merge remote-tracking branch 'origin/main' into feature/add-staged-pa…
lausannel Jun 4, 2026
17ce0a6
Store prefix cache attachments per coordinator
lausannel Jun 5, 2026
b25fe55
Fix prefix coordinator cross-process eviction test
lausannel Jun 5, 2026
a718a2c
Add runtime metrics logging for prefix-cache batches
lausannel Jun 7, 2026
ae2614a
Size Kimi decode MoE buffers from active capacity
lausannel Jun 7, 2026
3040812
Log prefix materialization GPU sizing
lausannel Jun 7, 2026
7fd2283
Avoid reusing destroyed GPU KV managers
lausannel Jun 7, 2026
f98991f
Add prefill reentry diagnostics
lausannel Jun 8, 2026
7200ecd
Avoid per-node prefix eviction filtering
lausannel Jun 8, 2026
af4b16e
Release completed decode KV before prefill admission
lausannel Jun 8, 2026
0d58ecf
Unify decode completion KV release
lausannel Jun 8, 2026
6b11a92
Retain inserted prefix page ranges
lausannel Jun 8, 2026
e817e87
Retain committed prefix pages by id
lausannel Jun 8, 2026
961d545
Scope prefix materialization to prefill microbatches
lausannel Jun 8, 2026
be35967
Fix prefix reuse microbatch planner import
lausannel Jun 8, 2026
2f26170
Cap prefix reuse prefill microbatch size
lausannel Jun 8, 2026
cdd1516
Release prefix prefill GPU memory between microbatches
lausannel Jun 8, 2026
9c21b5e
Release prefix materialization GPU cache before reuse
lausannel Jun 8, 2026
e723ab0
Avoid clearing non-null core GPU manager binding
lausannel Jun 8, 2026
1cd6e15
Cap prefix prefill microbatches by GPU page footprint
lausannel Jun 8, 2026
f14bdff
Align prefix prefill microbatching with full-context token cap
lausannel Jun 8, 2026
4750e6d
Release prefix materialization at prefill microbatch boundary
lausannel Jun 8, 2026
cb21896
Fix prefix materialization cleanup invariant test
lausannel Jun 8, 2026
39aa355
Release CUDA cache after prefix materialization reset
lausannel Jun 8, 2026
44b6ae6
Cap prefix-hit prefill materialization microbatches
lausannel Jun 8, 2026
a5f9bc0
Stream prefix-hit prefill KV materialization by layer
lausannel Jun 8, 2026
52f22d1
Align prefix commit capacity tests with delta entries
lausannel Jun 8, 2026
7c47073
Retire prefill offload tensors per microbatch
lausannel Jun 8, 2026
e4657dd
Fix paged GQA extend KV length metadata
lausannel Jun 8, 2026
cd87729
Align GQA prefix materialization with FA paged KV pages
lausannel Jun 8, 2026
c8b5651
Delay prefix materialization reuse until prefill offload retires
lausannel Jun 8, 2026
b7a1348
Optimize host prefix cache commit path
lausannel Jun 9, 2026
49bd39b
Pass FA3 new-KV boundaries for GQA extend prefill
lausannel Jun 9, 2026
c00e7fe
Avoid FA3 new-KV boundaries without append tensors
lausannel Jun 9, 2026
c6caaa5
Add prefix extend debug synchronization
lausannel Jun 9, 2026
47a4181
Add GPT-OSS MoE debug synchronization
lausannel Jun 9, 2026
e7fea21
Add GPT-OSS prefill fused gate fallback
lausannel Jun 9, 2026
1384756
Defer tiny prefix-cache prefill waves
lausannel Jun 10, 2026
8999481
Add prefix cache pin management endpoints
lausannel Jun 10, 2026
e93f483
Optimize prefix cache page release tracking
lausannel Jun 10, 2026
4dd78cb
Stop committing decode tokens to prefix cache
lausannel Jun 10, 2026
d8477cd
Make prefix prefill admission reuse-aware
lausannel Jun 10, 2026
18fda97
Fix prefix admission scheduler test expectations
lausannel Jun 10, 2026
4c4b3dd
Reserve resident prefix pages during prefill admission
lausannel Jun 10, 2026
2b216e2
Charge selected shared prefix pages in prefill admission
lausannel Jun 10, 2026
8674177
Merge branch 'main' of https://github.com/EfficientMoE/BatchGen into …
lausannel Jun 11, 2026
c86f514
fix(prefix-cache): expose resident page release on host managers
lausannel Jun 11, 2026
534c503
fix(prefix-cache): use rolling materialization for MLA prefill
lausannel Jun 11, 2026
e6fb07c
fix(prefix-cache): synchronize MLA rolling materialization
lausannel Jun 11, 2026
ed95e58
fix(prefix-cache): reuse FlashInfer MLA extend plans
lausannel Jun 11, 2026
89a147c
fix(worker): complete length-limited prefill outputs before decode
lausannel Jun 11, 2026
6d57602
fix(deepseek): pass checkpoint path as string
lausannel Jun 19, 2026
ddac5a8
fix(prefix-cache): retire subclass prefill offloads through base wrapper
lausannel Jun 19, 2026
00c3c6d
fix(moe): pass fused gate routing arguments by wrapper contract
lausannel Jun 19, 2026
d981fbb
fix(worker): preserve completed outputs for synchronous responses
lausannel Jun 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions batchgen/attention/forward_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
"""First-class forward metadata for attention execution.

These dataclasses describe the logical forward batch without depending on
legacy wrapper class variables. They intentionally do not mutate runtime state;
builders are responsible for constructing them from already-validated static
planning inputs.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Literal, Optional

import torch

ForwardPhase = Literal["prefill", "decode"]


@dataclass(frozen=True)
class PrefillAttentionMetadata:
"""Attention metadata for prefill or suffix-only prefill.

Prefix reuse is represented by q/kv length divergence:
``kv_seq_lens[i] - q_seq_lens[i]`` is the cached prefix length for sequence
``i``. The legacy wrapper context mirrors these derived values into
``AttnWrapperBase.prepack_prefix_*`` for model wrappers.
"""

cu_seqlens_q: torch.Tensor
cu_seqlens_k: torch.Tensor
max_seqlen_q: int
max_seqlen_k: int
q_seq_lens: list[int]
kv_seq_lens: list[int]
position_ids: torch.Tensor
append_seq_lens: Optional[list[int]] = None

@property
def batch_size(self) -> int:
return len(self.q_seq_lens)


@dataclass(frozen=True)
class DecodeAttentionMetadata:
"""Attention metadata for decode forward batches."""

cache_seqlens: torch.Tensor
max_seqlen: int
page_table: Optional[torch.Tensor] = None
slot_indices: Optional[torch.Tensor] = None
batch_slice: Optional[slice] = None

@property
def batch_size(self) -> int:
return int(self.cache_seqlens.numel())


@dataclass(frozen=True)
class KVCacheMetadata:
"""KV cache handles associated with a forward batch."""

gpu_paged_kv_manager: Optional[object] = None
host_worker_view: Optional[object] = None
aux_gpu_paged_kv_manager: Optional[object] = None
aux_host_worker_view: Optional[object] = None
prefill_prefix_materialization: Optional[object] = None


@dataclass(frozen=True)
class ForwardBatchMetadata:
"""Top-level metadata object for one model forward batch."""

phase: ForwardPhase
global_sequence_ids: list[int]
prefill: Optional[PrefillAttentionMetadata] = None
decode: Optional[DecodeAttentionMetadata] = None
kv_cache: Optional[KVCacheMetadata] = None

def require_prefill(self) -> PrefillAttentionMetadata:
if self.phase != "prefill" or self.prefill is None:
raise RuntimeError(
"Prefix cache prepack metadata requires prefill metadata"
)
return self.prefill

@property
def cu_seqlens(self) -> torch.Tensor:
return self.require_prefill().cu_seqlens_q

@property
def cu_seqlens_cpu(self) -> list[int]:
return _build_cu_seqlens_values(self.seq_lengths)

@property
def max_seqlen(self) -> int:
return int(self.require_prefill().max_seqlen_q)

@property
def num_sequences(self) -> int:
return int(self.require_prefill().batch_size)

@property
def seq_lengths(self) -> list[int]:
return [int(length) for length in self.require_prefill().q_seq_lens]

@property
def append_seq_lengths(self) -> list[int]:
prefill = self.require_prefill()
if prefill.append_seq_lens is None:
return [int(length) for length in prefill.q_seq_lens]
return [int(length) for length in prefill.append_seq_lens]

@property
def prefix_shared_tokens(self) -> Optional[list[int]]:
tokens = [
int(kv_len) - int(append_len)
for kv_len, append_len in zip(
self.require_prefill().kv_seq_lens,
self.append_seq_lengths,
)
]
if any(token < 0 for token in tokens):
raise RuntimeError(
"Prefix cache metadata requires kv lengths >= append lengths"
)
return tokens if any(token > 0 for token in tokens) else None

@property
def prefix_reuse_mode(self) -> bool:
tokens = self.prefix_shared_tokens
return tokens is not None and any(token > 0 for token in tokens)

@property
def full_seq_lengths(self) -> Optional[list[int]]:
if not self.prefix_reuse_mode:
return None
return [int(length) for length in self.require_prefill().kv_seq_lens]

def cu_seqlens_list(self) -> list[int]:
return list(self.cu_seqlens_cpu)

def append_seq_lengths_list(self) -> list[int]:
return list(self.append_seq_lengths)


def _build_cu_seqlens_values(seq_lengths: list[int]) -> list[int]:
values = [0]
running = 0
for length in seq_lengths:
running += int(length)
values.append(running)
return values
177 changes: 177 additions & 0 deletions batchgen/attention/forward_metadata_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
"""Context binding for first-class attention forward metadata.

This module is the compatibility bridge between explicit
``ForwardBatchMetadata`` and the legacy ``AttnWrapperBase`` class variables.
The metadata object remains the source of truth; legacy fields are only
populated for the dynamic extent of a single forward call.
"""

from __future__ import annotations

from contextlib import contextmanager
from contextvars import ContextVar
from typing import Iterator, Optional

from batchgen.attention.forward_metadata import (
DecodeAttentionMetadata,
ForwardBatchMetadata,
KVCacheMetadata,
PrefillAttentionMetadata,
)


_CURRENT_FORWARD_BATCH_METADATA: ContextVar[Optional[ForwardBatchMetadata]] = (
ContextVar("current_forward_batch_metadata", default=None)
)

_LEGACY_ATTENTION_FIELDS = (
"phase",
"cur_batch",
"position_ids",
"prepack_mode",
"prepack_cu_seqlens",
"prepack_max_seqlen",
"prepack_num_sequences",
"prepack_seq_lengths",
"prepack_append_seq_lengths",
"prepack_prefix_reuse_mode",
"prepack_prefix_shared_tokens",
"prepack_full_seq_lengths",
"cache_seqlens",
"max_seqlen",
"gpu_paged_kv_manager",
"host_paged_kv_worker_view",
"prefill_prefix_materialization",
"gpu_paged_kv_manager_aux",
"host_paged_kv_worker_view_aux",
)


def get_current_forward_batch_metadata(
required: bool = False,
) -> Optional[ForwardBatchMetadata]:
"""Return the metadata bound to the current execution context."""

metadata = _CURRENT_FORWARD_BATCH_METADATA.get()
if metadata is None and required:
raise RuntimeError("ForwardBatchMetadata is required but is not bound")
return metadata


@contextmanager
def bind_forward_batch_metadata(
metadata: ForwardBatchMetadata,
) -> Iterator[ForwardBatchMetadata]:
"""Bind metadata for one forward and mirror it into legacy wrapper fields."""

if not isinstance(metadata, ForwardBatchMetadata):
raise TypeError("metadata must be a ForwardBatchMetadata instance")

# Import lazily so metadata users can be unit-tested without importing model
# wrappers unless the compatibility bridge is actually used.
from batchgen.models.wrappers.attention import AttnWrapperBase

previous_values = {
field: getattr(AttnWrapperBase, field, None)
for field in _LEGACY_ATTENTION_FIELDS
}
token = _CURRENT_FORWARD_BATCH_METADATA.set(metadata)
try:
_sync_legacy_attention_wrapper(AttnWrapperBase, metadata)
yield metadata
finally:
_CURRENT_FORWARD_BATCH_METADATA.reset(token)
for field, value in previous_values.items():
setattr(AttnWrapperBase, field, value)


def _sync_legacy_attention_wrapper(
wrapper_cls: type,
metadata: ForwardBatchMetadata,
) -> None:
wrapper_cls.phase = metadata.phase
wrapper_cls.cur_batch = list(metadata.global_sequence_ids)

if metadata.phase == "prefill":
assert metadata.prefill is not None
_sync_prefill_fields(wrapper_cls, metadata.prefill)
else:
assert metadata.decode is not None
_sync_decode_fields(wrapper_cls, metadata.decode)

if metadata.kv_cache is not None:
_sync_kv_cache_fields(wrapper_cls, metadata.kv_cache)


def _sync_prefill_fields(
wrapper_cls: type,
prefill: PrefillAttentionMetadata,
) -> None:
wrapper_cls.position_ids = prefill.position_ids
wrapper_cls.prepack_mode = True
wrapper_cls.prepack_cu_seqlens = prefill.cu_seqlens_q
wrapper_cls.prepack_max_seqlen = int(prefill.max_seqlen_q)
wrapper_cls.prepack_num_sequences = prefill.batch_size
wrapper_cls.prepack_seq_lengths = list(prefill.q_seq_lens)
wrapper_cls.prepack_append_seq_lengths = _append_seq_lens(prefill)
wrapper_cls.cache_seqlens = None
wrapper_cls.max_seqlen = None

_sync_prefix_reuse_fields(wrapper_cls, prefill)


def _sync_prefix_reuse_fields(
wrapper_cls: type,
prefill: PrefillAttentionMetadata,
) -> None:
prefix_lens = [
int(kv_len) - int(q_len)
for q_len, kv_len in zip(prefill.q_seq_lens, prefill.kv_seq_lens)
]
if any(length < 0 for length in prefix_lens):
raise ValueError(
"prefill kv sequence lengths must be >= query sequence lengths"
)
if not any(length > 0 for length in prefix_lens):
wrapper_cls.prepack_prefix_reuse_mode = False
wrapper_cls.prepack_prefix_shared_tokens = None
wrapper_cls.prepack_full_seq_lengths = None
return

full_seq_lens = [int(length) for length in prefill.kv_seq_lens]
wrapper_cls.prepack_prefix_reuse_mode = True
wrapper_cls.prepack_prefix_shared_tokens = prefix_lens
wrapper_cls.prepack_full_seq_lengths = full_seq_lens


def _sync_decode_fields(
wrapper_cls: type, decode: DecodeAttentionMetadata
) -> None:
wrapper_cls.position_ids = None
wrapper_cls.prepack_mode = False
wrapper_cls.prepack_cu_seqlens = None
wrapper_cls.prepack_max_seqlen = None
wrapper_cls.prepack_num_sequences = None
wrapper_cls.prepack_seq_lengths = None
wrapper_cls.prepack_append_seq_lengths = None
wrapper_cls.prepack_prefix_reuse_mode = False
wrapper_cls.prepack_prefix_shared_tokens = None
wrapper_cls.prepack_full_seq_lengths = None
wrapper_cls.cache_seqlens = decode.cache_seqlens
wrapper_cls.max_seqlen = int(decode.max_seqlen)


def _sync_kv_cache_fields(wrapper_cls: type, kv_cache: KVCacheMetadata) -> None:
wrapper_cls.gpu_paged_kv_manager = kv_cache.gpu_paged_kv_manager
wrapper_cls.host_paged_kv_worker_view = kv_cache.host_worker_view
wrapper_cls.prefill_prefix_materialization = (
kv_cache.prefill_prefix_materialization
)
wrapper_cls.gpu_paged_kv_manager_aux = kv_cache.aux_gpu_paged_kv_manager
wrapper_cls.host_paged_kv_worker_view_aux = kv_cache.aux_host_worker_view


def _append_seq_lens(prefill: PrefillAttentionMetadata) -> list[int]:
if prefill.append_seq_lens is None:
return list(prefill.q_seq_lens)
return [int(length) for length in prefill.append_seq_lens]
3 changes: 3 additions & 0 deletions batchgen/attention/gqa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
Key components:
- gqa_prefill_fa: Prefill using flash_attn_varlen_func (unpadded sequences)
- gqa_decode_fa: Decode using flash_attn_with_kvcache (paged KV cache)
- gqa_extend_fa: Extend prefill using flash_attn_with_kvcache (paged KV cache)
- apply_sink_correction: Post-correction for attention sinks
- attention_ref: Reference implementation for testing

Expand All @@ -16,6 +17,7 @@

from .fa_prefill import gqa_prefill_fa
from .fa_decode import gqa_decode_fa, gqa_decode_fa_contiguous
from .fa_extend import gqa_extend_fa
from .sink_correction import apply_sink_correction
from .reference import attention_ref, attention_ref_no_sinks
from .gqa_mode3 import gqa_decoding_mode_3_bf16
Expand All @@ -25,6 +27,7 @@
'gqa_prefill_fa',
'gqa_decode_fa',
'gqa_decode_fa_contiguous',
'gqa_extend_fa',
'apply_sink_correction',
'attention_ref',
'attention_ref_no_sinks',
Expand Down
Loading
Loading