GLM-5.2-FP8 with DSA enablement - #1760
Open
jkaniecki wants to merge 8 commits into
Open
Conversation
Signed-off-by: Jan Kaniecki <jkaniecki@habana.ai>
jkaniecki
had a problem deploying
to
pre-merge-approval
August 27, 2026 14:19 — with
GitHub Actions
Error
Contributor
There was a problem hiding this comment.
Pull request overview
Enable GLM-5.2 FP8 with DeepSeek Sparse Attention (DSA) execution on Intel Gaudi (HPU) by wiring sparse indexer execution and adding a sparse decode attention path in the HPU MLA backend.
Changes:
- Add an HPU SparseAttnIndexer implementation and route upstream
SparseAttnIndexer.forward_nativeto it for HPU. - Introduce an HPU MLA sparse decode path (
forward_mqa_sparse) and dispatch to it from the OOT MLA wrapper whenuse_sparse=True. - Extend KV-cache spec discovery / platform routing to recognize attention modules that provide their own KV-cache spec and to log sparse-attention selection.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| vllm_gaudi/v1/worker/hpu_model_runner.py | Adds KV-cache spec extraction for attention layers implementing AttentionLayerBase.get_kv_cache_spec. |
| vllm_gaudi/platform.py | Updates sparse-attention backend selection logging and adds a runner KV-cache multi-layer hook. |
| vllm_gaudi/ops/hpu_sparse_attn_indexer.py | New HPU indexer implementation used by DSA to produce top-k cache slot indices. |
| vllm_gaudi/models/deepseek_v2.py | Monkey-patches DeepSeek indexer/cache paths to use BF16 and dispatch SparseAttnIndexer to the HPU implementation. |
| vllm_gaudi/attention/oot_mla.py | Routes decode to forward_mqa_sparse when sparse mode is active and passes the top-k index buffer through. |
| vllm_gaudi/attention/backends/hpu_attn.py | Adds forward_mqa_sparse implementation that gathers/decompresses top-k KV and runs sparse decode attention. |
Suppressed comments (2)
vllm_gaudi/ops/hpu_sparse_attn_indexer.py:9
- The docstring claims "BF16 matmul + torch.topk", but the implementation currently does not do Q·K scoring or
torch.topk, andhidden_states/weightsare unused. This is misleading for maintainers and reviewers.
def forward_hpu(self, hidden_states, q, k, weights):
"""HPU SparseAttnIndexer: BF16 matmul + torch.topk."""
forward_context = get_forward_context()
attn_metadata = forward_context.attn_metadata
vllm_gaudi/ops/hpu_sparse_attn_indexer.py:40
- Decode-path slot selection uses the batch-wide
attn_metadata.block_listand then expands the sameall_slotsto every sequence in the batch. In this codebaseblock_listis a flattened list across requests andblock_groupsindicates which request each block belongs to (seehpu_model_runner.py:2446-2451). As written, this can mix KV slots between different requests, which is both a correctness issue and a potential cross-request data exposure.
# Decode: use first-N physical slots from the request's context blocks.
# Full top-K logit scoring deferred to kernel optimization phase.
batch_size = q.shape[0]
block_list = attn_metadata.block_list
pos_range = torch.arange(block_size, device=block_list.device)
all_slots = (block_list.unsqueeze(1) * block_size + pos_range.unsqueeze(0)).reshape(-1)
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Jan Kaniecki <jkaniecki@habana.ai>
jkaniecki
had a problem deploying
to
pre-merge-approval
September 2, 2026 12:42 — with
GitHub Actions
Error
jkaniecki
marked this pull request as ready for review
September 2, 2026 12:43
jkaniecki
requested review from
PatrykWo,
adobrzyn,
afierka-intel,
iboiko-habana,
jbyczkow,
mgawarkiewicz-intel,
michalkuligowski and
xuechendi
as code owners
September 2, 2026 12:43
jkaniecki
had a problem deploying
to
pre-merge-approval
September 2, 2026 12:43 — with
GitHub Actions
Error
jkaniecki
had a problem deploying
to
pre-merge-approval
September 2, 2026 12:43 — with
GitHub Actions
Error
Replace first-slot decode selection with per-request BF16 QK scoring and top-K selection. Mask repeated top-K entries for short contexts in sparse MLA decode.
jkaniecki
had a problem deploying
to
pre-merge-approval
September 2, 2026 12:56 — with
GitHub Actions
Error
Issue vllm-project#1 (Copilot review): _fill_sequential() was only initializing topk columns based on batch size, leaving remaining columns stale/uninitialized. When gather uses the full buffer width (topk_tokens), stale indices can cause out-of-range KV cache access. Fix: fill entire buffer width. Issue vllm-project#2 (Copilot review): masked_fill(-inf) followed by softmax can produce NaN when valid_topk == 0 (entire row masked). Fix: use torch.finfo(dtype).min for finite masking and explicitly zero rows where entire sequence is masked.
jkaniecki
had a problem deploying
to
pre-merge-approval
September 4, 2026 07:22 — with
GitHub Actions
Error
jkaniecki
had a problem deploying
to
pre-merge-approval
September 4, 2026 13:58 — with
GitHub Actions
Error
jkaniecki
added a commit
to jkaniecki/vllm-gaudi
that referenced
this pull request
Sep 7, 2026
Enable GLM-5.2 with DSA (DeepSeek Sparse Attention) on HPU. What changed: - hpu_sparse_attn_indexer.py (new): per-request Q.K BF16 scoring + torch.topk to select top-2048 KV cache slots per decode step. Rewritten to derive per-request valid slots via block_groups/block_usage masking instead of a fragile block_offset walk that assumed block_list was an unpadded per-request concatenation (breaks under contiguous PA, which scatters/reorders blocks by physical block id). Padding now uses the upstream -1 sentinel convention instead of repeating the last valid slot or leaving stale buffer contents. - hpu_attn.py: forward_mqa_sparse - gathers top-K latent KV, decompresses, runs masked MLA decode attention. Masking is now driven directly by the -1 sentinel in topk_indices instead of seq_lens_tensor/context_lens_tensor, which are always None on HPU decode for models without mamba-like layers (the previous fallback silently handed every request in the batch the same first topk_tokens slots). Uses torch.finfo(dtype).min instead of -inf for masking to avoid NaN on fully-padded rows, and zeroes fully padded rows' output with a dtype- and shape-correct multiply (previously promoted bf16 attn to fp32 before a bf16 matmul, and used a 3D mask that only broadcast correctly by coincidence when num_heads == batch_size). HPUMLAImpl.__init__ now stores topk_indices_buffer (previously swallowed by **kwargs and never read) and sets is_sparse per-instance, which is what actually makes forward_mqa_sparse reachable. - oot_mla.py: dispatches to forward_mqa_sparse when use_sparse=True, reading topk_indices_buffer from self.impl (where HPUMLAImpl now stores it) instead of the wrapper module (where it was never set). - deepseek_v2.py: BF16 indexer cache, HPU-safe Indexer.forward, SparseAttnIndexer dispatch. - platform.py / hpu_model_runner.py: DSA routing + indexer cache layer index fix. Ports the get_kv_cache_spec AttentionLayerBase branch from the main-branch sibling (vllm-project#1760), which this backport was missing - without it DeepseekV32IndexerCache never gets a KV cache allocation, so kv_cache.numel() is always 0 and the indexer never runs. Addresses review feedback from Pawel Olejniczak and Copilot on PR vllm-project#1777: - Sparse decode path is now actually reachable (three independent gates previously routed every DSA decode back to dense MLA). - Fixed NaN-producing masked_fill(-inf) on fully-masked rows. - Fixed uninitialized/stale topk_indices_buffer columns. - Fixed bf16->fp32 dtype promotion before a bf16 matmul. - Removed unused _orig_forward_native and an orphaned comment. - Added missing -> None annotation on check_runner_kv_caches_multi_layer. - Applied yapf 0.43.0 (column_limit=120) formatting; ruff 0.11.7 clean. Still open (not addressed here, needs checkpoint inspection on the pod): whether the validated GLM-5.2-FP8 checkpoint still ships indexers_proj weights now that the load_weights filter for them has been dropped. Validated on 8x Gaudi3 (GLM-5.2-FP8, TP=8): GSM8K 5-shot (1319 samples): 93.6% exact match Signed-off-by: Jan Kaniecki <jkaniecki@habana.ai>
…ejniczak) - get_kv_cache_spec (already present): DSA indexer cache gets a spec so kv_cache.numel() != 0 and the sparse path is actually reachable - hpu_sparse_attn_indexer.py: derive per-request valid cache slots from block_groups/block_usage masking instead of an always-None seq_lens_tensor/context_lens_tensor fallback and a block_offset walk that assumed an unpadded per-request block_list layout; adopt upstream's -1 sentinel for padding instead of repeating a valid slot - forward_mqa_sparse: mask via the -1 sentinel directly instead of the unreliable seq_lens derivation; use finfo(dtype).min instead of -inf to avoid NaN on fully-masked rows; fix a bf16->fp32 dtype promotion bug in the empty-row zero-mask multiply - HPUMLAImpl: store topk_indices_buffer (previously swallowed by **kwargs) and set is_sparse per-instance so forward_mqa_sparse is actually reachable - oot_mla.py: read topk_indices_buffer from self.impl (where it is actually stored) instead of the wrapper; drop an orphaned comment - deepseek_v2.py: drop an unused _orig_forward_native assignment - platform.py: add -> None annotation to check_runner_kv_caches_multi_layer Signed-off-by: Jan Kaniecki <jkaniecki@habana.ai>
jkaniecki
had a problem deploying
to
pre-merge-approval
September 7, 2026 12:07 — with
GitHub Actions
Error
…g for GLM DSA Signed-off-by: Jan Kaniecki <jkaniecki@habana.ai>
jkaniecki
requested a deployment
to
pre-merge-approval
September 7, 2026 16:35 — with
GitHub Actions
Waiting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Enable GLM-5.2 with DSA (DeepSeek Sparse Attention) on HPU
What changed:
hpu_sparse_attn_indexer.py(new): per-request Q·K BF16 scoring + torch.topk to select top-2048 KV cache slots per decode stephpu_attn.py: forward_mqa_sparse — gathers top-K latent KV, decompresses, runs masked MLA decode attentionoot_mla.py: dispatches to forward_mqa_sparse when use_sparse=Truedeepseek_v2.py: BF16 indexer cache, HPU-safe Indexer.forward, SparseAttnIndexer dispatchplatform.py / hpu_model_runner.py: DSA routing + indexer cache layer index fixValidated on 8× Gaudi3 (GLM-5.2-FP8, TP=8):
GSM8K 5-shot (1319 samples): 93.6% exact match
AIME 2026 - 100% - on pair with model card's target (99,2 % mean for multiple reruns)