Skip to content

Perf: accelerate DeepSeek V4 Flash prefill sparse attention - #834

Merged
zhangqi-chen merged 3 commits into
hw-native-sys:mainfrom
hashiqiqixian:perf/dsv4-prefill-sparse-attn
Jul 28, 2026
Merged

Perf: accelerate DeepSeek V4 Flash prefill sparse attention#834
zhangqi-chen merged 3 commits into
hw-native-sys:mainfrom
hashiqiqixian:perf/dsv4-prefill-sparse-attn

Conversation

@hashiqiqixian

@hashiqiqixian hashiqiqixian commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Pass per-token compressed-row counts through CSA, HCA, and SWA prefill so sparse gather, QK/PV, and online-softmax merge skip inactive blocks.
  • Fan the DeepSeek V4 Flash prefill indexer score over 8-token groups, cap the useful top-k prefix at 256, and remove the redundant final merge stage.
  • Preserve separate QK/PV and online-merge SPMD tasks with an explicit dependency, so AIC-produced statistics are published before the vector merge consumes them.

Performance

  • Standalone sparse-attention median run mean: 635.2 -> 609.6 us (ratio 4, 128 tokens, a2a3 auto device, 3 x 20 rounds).
  • Standalone indexer latency: 952.9 -> 488.7 us (128 tokens, start-pos 896, a2a3, 20 rounds).

Validation

  • On 686/a2a3, serial standalone sparse attention, CSA, HCA, and SWA tests pass.
  • The two-device EP2 prefill_fwd.py -p a2a3 test passes without scheduler stalls.
  • The exact eight-device DeepSeek serving accuracy test passes: 4 passed.

ChenShenAi added 2 commits July 25, 2026 14:12
- Pass aligned compressed-row counts through SWA, CSA, and HCA
- Bound gather, QK/PV, and merge loops to each token's active blocks

Standalone sparse-attention median run mean 635.2 -> 609.6 us
(ratio 4, 128 tokens, a2a3 auto device, 3 x 20 rounds).
- Fan score work over 8-token groups while retaining cache-block reuse
- Cap the useful top-k prefix at 256 and remove the redundant final merge

Standalone indexer latency 952.9 -> 488.7 us (128 tokens,
start-pos 896, a2a3, 20 rounds).
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds per-token compressed-slot counts to packed prefill sparse attention, updates CSA, HCA, and SWA call sites, changes indexer score tiling and top-k sorting, and fuses sparse attention scoring with online-softmax merging.

Changes

Sparse prefill count propagation

Layer / File(s) Summary
Indexer tiling and top-k pipeline
models/deepseek/v4-flash/prefill_indexer.py
Score computation uses eight-token groups, requires divisible token counts, adopts INDEXER_TOPK_CAP, and removes the extended merge-sort stage.
Compressed count production
models/deepseek/v4-flash/prefill_attention_csa.py, models/deepseek/v4-flash/prefill_attention_hca.py, models/deepseek/v4-flash/prefill_attention_swa.py
CSA and HCA compute clamped cmp_counts; SWA passes a zero-initialized dummy count tensor.
Sparse gather and fused attention
models/deepseek/v4-flash/prefill_sparse_attn.py
Sparse KV gathering and online-softmax merging use per-token compressed counts, with the qk_pv and merge stages fused.
Sparse attention test plumbing
models/deepseek/v4-flash/prefill_sparse_attn.py
Test signatures, calls, tensor specifications, and count initialization are updated for cmp_counts.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PrefillIndexer
  participant CSA_HCA_SWA
  participant PrefillSparseAttn
  PrefillIndexer->>CSA_HCA_SWA: provide sparse indices and visible compressed range
  CSA_HCA_SWA->>CSA_HCA_SWA: compute per-token cmp_counts
  CSA_HCA_SWA->>PrefillSparseAttn: pass cmp_counts with sparse metadata
  PrefillSparseAttn->>PrefillSparseAttn: gather valid compressed KV slots
  PrefillSparseAttn->>PrefillSparseAttn: merge attention outputs over active blocks
Loading

Possibly related PRs

Poem

I’m a rabbit with counts in my pack,
Eight bright tokens marching in track.
Sparse keys now know where to play,
Fused merges hop through the day.
Top-k sorts with a nimble twist—
Count every carrot on the list!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: faster DeepSeek V4 Flash prefill sparse attention.
Description check ✅ Passed The description is clearly related to the changeset and matches the performance and validation-focused updates.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

- Keep QK/PV and online merge in separate SPMD tasks
- Add an explicit dependency so AIC-produced statistics publish before the vector merge consumes them
- Prevent nondeterministic attention output and full-prefill stalls

Validated on a2a3 with sparse, CSA, HCA, SWA, EP2 prefill_fwd, and eight-device DeepSeek serving accuracy.
@hashiqiqixian
hashiqiqixian force-pushed the perf/dsv4-prefill-sparse-attn branch from 0d3c4f1 to cc78191 Compare July 27, 2026 04:39
@zhangqi-chen
zhangqi-chen merged commit 5aead34 into hw-native-sys:main Jul 28, 2026
7 of 9 checks passed
MaxwellF1 added a commit to MaxwellF1/pypto-lib that referenced this pull request Jul 28, 2026
Rebased onto main after hw-native-sys#834, which independently landed an overlapping
optimisation. Where the two differ this keeps whichever measured better:

- Sparse-attention block skipping switches from hw-native-sys#834's cmp_counts (a
  per-token compressed-row count, which can only express "the first N
  blocks are live" and always treats the whole WIN window as live) to an
  explicit per-block valid_block_mask. Tokens with abs_pos < WIN can then
  skip genuinely empty window blocks, which is most of a 128-token
  prefill. CSA also stops re-filtering the indexer top-k per token and
  passes cmp_topk_indices straight through.
- Indexer: TOPK_TILE 16 -> 4 for a finer top-k SPMD fan-out, and the Q
  RoPE folds into the Hadamard-quant loop, dropping the qr_rope_out
  staging tensor and the separate prefill_idx_qr_rope pass.
- Keeps hw-native-sys#834's two-stage mrgsort and INDEXER_TOPK_CAP prefix: measured
  identical to the three-stage/IDX_TOPK variant (221.4 vs 224.4 us min),
  and since visible_t is capped at INDEXER_SCORE_CAP=256 the extra 256
  top-k slots can never select a finite score.
- Adds topk_prefix_contract_error, asserting the top-k visible prefix is
  dense, unique and in range with a -1 tail.

a2a3, PYPTO_BENCH 50 rounds (prefill_layer 20, 2 cards), min us:

  prefill_indexer          305.6 -> 220.0   -28%
  prefill_attention_csa   1189.9 -> 979.3   -18%
  prefill_attention_hca    898.3 -> 790.7   -12%
  prefill_sparse_attn      506.3 -> 444.9   -12%
  prefill_attention_swa    812.4 -> 785.6    -3%
  prefill_layer           2812.1 -> 2563.6   -9%

All six validate against Golden on a2a3.
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.

2 participants