Skip to content

[Metal] Add sdpa_split kernels for mid rows for speculative decoding - #4723

Merged
zcbenz merged 2 commits into
ml-explore:mainfrom
dhiltgen:sdpa-nax-split
Oct 25, 2026
Merged

zcbenz merged 2 commits into
ml-explore:mainfrom
dhiltgen:sdpa-nax-split

Conversation

@dhiltgen

Copy link
Copy Markdown
Contributor

This PR aims to speed up speculative decoding. The existing SDPA has 2 fast paths: The vector kernel handles up to 8 query tokens provided tokens × query heads per KV head is 32 or less; the full-attention kernel covers over 8 tokens. This leaves a gap which makes checking more drafted tokens fall into the slow path (e.g. 4+ drafts on 7-8 heads.) This PR implements fast paths for NAX and pre-NAX for up to 8 tokens with 33-128 rows.

Performance:

mlx_lm.generate --model mlx-community/Qwen2.5-7B-Instruct-4bit --draft-model mlx-community/Qwen2.5-0.5B-Instruct-4bit --num-draft-tokens 5 --ignore-chat-template --temp 0 --max-tokens 256 --prompt - < prompt.txt

Using a 32k code prompt on M5 Max:

Draft setting Stock MLX This branch
No draft 77 79
3 drafts 86 (best) 87
5 drafts 54 (worse than none) 119 (best)
7 drafts 55 110

Best result examples on a few test systems:

GPU, model, context Stock best This branch best Speedup
M5 Max, 7B, 16K 103.0 (3 drafts) 105.0 (5 drafts) 1.02x
M5 Max, 7B, 32K 85.5 (3 drafts) 118.6 (5 drafts) 1.39x
M4 Pro, 7B, 16K 48.3 (3 drafts) 49.2 (3 drafts) 1.02x
M4 Pro, 7B, 32K 42.6 (3 drafts) 49.5 (5 drafts) 1.16x
  • ☑️ I understand it is strictly prohibited to use AI to write PR description
  • AI usage disclosure: co-developed with a coding agent

@zcbenz zcbenz added the await verification This pull request is non-trivial and requires a human expert to verify its correctness. label Oct 19, 2026
dhiltgen added a commit to dhiltgen/ollama that referenced this pull request Oct 20, 2026
SDPA fast paths for speculative verify: up to 8 query tokens whose
query heads per KV head stack to 33-128 rows. Applied to the pinned MLX
until the pin includes it; drop this commit then.
dhiltgen added a commit to dhiltgen/ollama that referenced this pull request Oct 22, 2026
SDPA fast paths for speculative verify: up to 8 query tokens whose
query heads per KV head stack to 33-128 rows. Applied to the pinned MLX
until the pin includes it; drop this commit then.

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#4734 adds support for sliding window which we will merge before this PR. I think the sliding window is not used for speculative decoding so we don't need to add support in this PR.

q, k, v, has_mask, has_arr_mask, do_causal, output_logsumexp, s);
if (force_fused) {
if (!has_fused) {
if (!has_fused && !split) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the supported dims of sdpa_split is a subset of other fused sdpa kernel, we shouldn't need to check it here, if not then we should have has_fused_kernel also check use_split.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved into has_fused_kernel

@zcbenz zcbenz removed the await verification This pull request is non-trivial and requires a human expert to verify its correctness. label Oct 22, 2026
@zcbenz
zcbenz force-pushed the sdpa-nax-split branch 3 times, most recently from 5260f32 to 7a00a76 Compare October 25, 2026 10:40
@zcbenz zcbenz changed the title [Metal] Add SDPA fast paths for speculative decoding [Metal] Add sdpa_split kernels for mid rows for speculative decoding Oct 25, 2026
@zcbenz
zcbenz merged commit 065ec46 into ml-explore:main Oct 25, 2026
30 checks passed
@dhiltgen
dhiltgen deleted the sdpa-nax-split branch October 25, 2026 18:32
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