vllm_mlx.specprefill¶
SpecPrefill: Attention-based sparse prefill for MLX.
View the complete module source at #L1-L845.
API details¶
Each callable below includes its exact signature, type annotations, inputs, defaults, return contract, documented exceptions, implementation source, and parsed docstring sections when the source provides them.
vllm_mlx.specprefill
¶
SpecPrefill: Attention-based sparse prefill for MLX.
Full pipeline for reducing TTFT on long prompts
Step 1 (score_tokens): Use a small draft model to identify important tokens Step 2 (sparse_prefill): Prefill target model with only selected tokens, preserving original positional encoding via manual RoPE
Usage
from specprefill import score_tokens, select_chunks, sparse_prefill, cleanup_rope
1. Score with draft model¶
importance = score_tokens(draft_model, tokens)
2. Select important token chunks¶
selected = select_chunks(importance, keep_pct=0.3)
3. Sparse prefill on target model¶
target_cache = make_prompt_cache(target_model) logits = sparse_prefill(target_model, tokens, selected, target_cache)
4. Generate normally using target_cache...¶
5. Cleanup¶
cleanup_rope(target_model)
Design notes
- RoPE is relative: Q_m @ K_p^T depends only on (m - p). Selected keys stored contiguously in the cache buffer with correct RoPE angles produce correct attention during decode.
- After sparse prefill of N tokens from a total prompt of M, cache.offset = N but decode RoPE needs position M. The _OffsetAdjustedRoPE adds (M - N) to each RoPE offset call, so decode position = N + i + (M - N) = M + i.
- GatedDeltaNet (linear attention) layers process sparse tokens through their conv/SSM state normally. This is lossy but acceptable per the SpecPrefill paper — attention layers are the primary long-range mechanism.
Reference: arxiv.org/abs/2502.02789 (SpecPrefill: Speculative Prefilling)
vllm_mlx.specprefill._AttentionCapture
¶
Wrapper that captures post-RoPE query vectors and delegates to original.
Installed on attention layers during lookahead decode to capture query vectors for importance scoring. Supports multiple architectures via query_extractor callback.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._AttentionCapture._query_buffer
instance-attribute
¶
vllm_mlx.specprefill._AttentionCapture._query_extractor
instance-attribute
¶
_query_extractor = query_extractor or _qwen35_extract_queries
vllm_mlx.specprefill._AttentionCapture.__call__
¶
vllm_mlx.specprefill._PositionMappedRoPE
¶
Wraps a RoPE module to apply rotation at non-contiguous positions.
Used during sparse prefill. The offset parameter from the cache tells us
which slice of the position array to use for the current chunk:
positions = all_positions[(offset - cache_start) : (offset - cache_start) + L]
When composing with a pre-populated cache (e.g., system KV cache), cache_start is the initial cache offset so indexing into the position array is correct.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._PositionMappedRoPE._all_positions
instance-attribute
¶
vllm_mlx.specprefill._PositionMappedRoPE._cache_start
instance-attribute
¶
vllm_mlx.specprefill._PositionMappedRoPE._has_custom_freqs
instance-attribute
¶
vllm_mlx.specprefill._PositionMappedRoPE._dims
instance-attribute
¶
_dims = _get_dims(original_rope)
vllm_mlx.specprefill._PositionMappedRoPE._pre_scale
instance-attribute
¶
_pre_scale = _get_pre_scale(original_rope)
vllm_mlx.specprefill._PositionMappedRoPE.__call__
¶
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._OffsetAdjustedRoPE
¶
Wraps a RoPE module to add a constant offset for decode after sparse prefill.
After sparse prefill of N tokens from a prompt of M total tokens
cache.offset = N + i (i = decode step) desired RoPE position = M + i adjustment = M - N
So: RoPE(x, offset = cache.offset + adjustment) = RoPE(x, M + i)
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._qwen35_extract_queries
¶
Extract post-RoPE queries from Qwen3.5 attention (gate split + q_norm).
Qwen3.5 q_proj output is 2x wider: [queries, gate]. We split, normalize, then apply RoPE.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._llama_extract_queries
¶
Extract post-RoPE queries from standard transformer attention.
Standard architecture: q_proj → reshape → RoPE. No gate, no q_norm. Works for Llama 3.x, Mistral, Gemma, GPT-OSS, and other GQA models.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._nemotron_h_extract_queries
¶
Extract queries from Nemotron-H attention (no RoPE, no gate, no q_norm).
Nemotron-H attention layers have NO positional encoding — RoPE is absent. Positional modeling comes from Mamba2 layers. Attention is content-based only.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._patch_attention_for_capture
¶
Replace attention modules on full-attention layers with capture wrappers.
Supports both self_attn (Qwen3.5/Llama/GPT-OSS) and mixer
(Nemotron-H block_type="*") attribute conventions.
Returns (originals, attn_layer_indices) for cleanup.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._unpatch_attention_capture
¶
vllm_mlx.specprefill._prefill_draft
¶
Prefill prompt tokens into cache. Returns logits from last token.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._lookahead_decode
¶
Run n_steps autoregressive decode, returning generated token ids.
Query vectors are captured by the monkey-patched attention layers.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._avg_pool1d
¶
1D average pooling along last axis via prefix-sum.
Parameters:
-
x–(..., M) input
-
kernel_size–window size (odd for centered)
Returns:
-
–
(..., M) pooled (same size, zero-padded at edges)
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._compute_importance
¶
Compute per-token importance from captured queries and cached keys.
Aggregation (SpecPrefill paper): 1. softmax(Q @ K^T / sqrt(d)) per head, per layer, per lookahead token 2. avg_pool1d smoothing 3. max across (layers × heads) 4. mean across lookahead tokens
Returns: (n_prompt,) importance scores.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill.score_tokens
¶
score_tokens(model, tokens, n_lookahead=8, pool_kernel=13, temp=0.6, top_p=0.95, prefill_step_size=2048, query_extractor=None, cancel_check=None)
Score token importance using attention-based analysis on a draft model.
Runs the full scoring pipeline
- Prefill the draft model with all tokens
- N lookahead decode steps, capturing query vectors from attention layers
- Compute importance: Q_lookahead @ K_prompt^T, aggregated across heads/layers
The draft model's cache is created internally and discarded after scoring.
Parameters:
-
model–Draft model (small, fast — e.g. 4B)
-
tokens–list or mx.array of token IDs
-
n_lookahead–decode steps for query capture (default 8)
-
pool_kernel–smoothing kernel for avg_pool1d (default 13, 0=disable)
-
temp–sampling temperature for lookahead (default 0.6)
-
top_p–top-p for lookahead (default 0.95)
-
prefill_step_size–chunk size for draft prefill (default 2048)
-
query_extractor–function(attn, x, cache) → queries tensor. Default: _qwen35_extract_queries. Use _llama_extract_queries for standard Llama/Mistral/Gemma models.
Returns:
-
importance–(M,) mx.array of per-token importance scores
Source code in vllm_mlx/specprefill.py
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | |
vllm_mlx.specprefill.select_chunks
¶
Select top-k% token chunks by average importance.
Parameters:
-
importance–(M,) per-token importance scores
-
keep_pct–fraction of chunks to keep (default 0.3)
-
chunk_size–tokens per chunk (default 32)
-
backbone_pct–fraction of chunks reserved for evenly-spaced coverage
Returns:
-
–
sorted mx.array of kept token indices
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill.manual_rope
¶
Apply RoPE at arbitrary (non-contiguous) positions.
Uses non-traditional (interleaved) layout matching Qwen3.5:
rotates first dims dimensions as pairs [0,half), [half,dims),
passes through [dims:] unchanged.
Parameters:
-
x–(B, n_heads, L, head_dim) input tensor
-
positions–(L,) position indices (can be non-contiguous)
-
dims–number of dimensions to rotate (head_dim * partial_rotary_factor)
-
base–RoPE base frequency (default 10000.0)
-
scale–position scale divisor (default 1.0, higher = compressed positions)
Returns:
-
–
(B, n_heads, L, head_dim) with RoPE applied
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill.manual_rope_with_freqs
¶
Apply RoPE at arbitrary positions using pre-computed frequencies.
For custom RoPE variants (Llama3, Yarn, SuScaled) that store _freqs.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._get_dims
¶
Extract rotary dimensions from any RoPE variant.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._get_pre_scale
¶
Extract pre-scale factor from custom RoPE variants (SuScaled, Yarn).
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._find_attention_layers
¶
Find all full-attention layers across architectures.
Supports
- Qwen3.5 / Llama / GPT-OSS: layers with
self_attnattribute - Nemotron-H: layers with
block_type == "*"(attention blocks usemixer)
Returns list of (layer_idx, layer) tuples.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill._get_attn_module
¶
Get the attention module from a layer (self_attn or mixer).
vllm_mlx.specprefill._get_rope
¶
Get the RoPE module from an attention layer, or None.
mlx_lm models use self.rope; mlx_vlm models use self.rotary_emb.
vllm_mlx.specprefill._set_rope
¶
Set the RoPE module on an attention layer.
vllm_mlx.specprefill._set_attn_module
¶
Set the attention module on a layer (self_attn or mixer).
vllm_mlx.specprefill._build_layer_to_cache_map
¶
Build mapping from model layer index to cache index.
Standard models (Qwen3.5, Llama, GPT-OSS): one cache entry per layer, so the mapping is identity (layer_idx → layer_idx).
Nemotron-H: only M (Mamba2) and * (attention) layers have cache entries. MLP (-) and MoE (E) layers get no cache. The mapping is compacted.
Returns dict {layer_idx: cache_idx}.
Source code in vllm_mlx/specprefill.py
vllm_mlx.specprefill.sparse_prefill
¶
sparse_prefill(model, tokens, selected_indices, cache, step_size=2048, position_offset=0, cancel_check=None)
Prefill the model cache with selected tokens at their original positions.
Runs the model forward on only the selected tokens while preserving their original positional encoding via manual RoPE. After this call, the cache contains KV entries with correct RoPE positions, and attention layers have _OffsetAdjustedRoPE installed for correct decode positioning.
Parameters:
-
model–Language model with .layers property (TextModel or VLM Model)
-
tokens–(M,) all prompt token IDs (mx.array or list)
-
selected_indices–(N,) sorted indices into tokens to keep (mx.array or list)
-
cache–list of KVCache/ArraysCache from make_prompt_cache()
-
step_size–chunk size for processing (default 2048)
-
position_offset–added to selected_indices for RoPE positions (default 0). Use when the cache already has tokens from a prior prefill (e.g., system prompt KV cache with S tokens → position_offset=S).
Returns:
-
logits–(1, 1, vocab_size) from the last selected token
Side effects
- Populates cache with KV for selected tokens
- Installs _OffsetAdjustedRoPE on attention layers for decode
- Call cleanup_rope(model) after generation to restore original RoPE
Source code in vllm_mlx/specprefill.py
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 | |
vllm_mlx.specprefill.cleanup_rope
¶
Restore original RoPE on all attention layers.
Call this after generation is complete to remove _OffsetAdjustedRoPE wrappers installed by sparse_prefill(). No-op for architectures without RoPE (e.g. Nemotron-H).
Source code in vllm_mlx/specprefill.py
Complete contract reference¶
Expand any definition for its exact inputs, annotations, defaults, return contract, directly raised exceptions, source-grounded behavior, and immutable line link. This section includes private and nested definitions that ordinary API generators omit.
vllm_mlx.specprefill._AttentionCapture · class
Wrapper that captures post-RoPE query vectors and delegates to original.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
original |
not annotated |
yes |
none |
Required positional or keyword input. |
buf_idx |
not annotated |
yes |
none |
Required positional or keyword input. |
query_buffer |
not annotated |
yes |
none |
Required positional or keyword input. |
query_extractor |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Constructs:
vllm_mlx.specprefill._AttentionCapture
Exceptions and behavior
Class _AttentionCapture declares 3 direct member(s).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._AttentionCapture.__init__ · method
vllm_mlx.specprefill._AttentionCapture.__init__(original, buf_idx, query_buffer, query_extractor = None) -> not annotated
Method _AttentionCapture.__init__ updates self._original, self._buf_idx, self._query_buffer, self._query_extractor.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
original |
not annotated |
yes |
none |
Required positional or keyword input. |
buf_idx |
not annotated |
yes |
none |
Required positional or keyword input. |
query_buffer |
not annotated |
yes |
none |
Required positional or keyword input. |
query_extractor |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated
Exceptions and behavior
Method _AttentionCapture.__init__ updates self._original, self._buf_idx, self._query_buffer, self._query_extractor.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._AttentionCapture.__call__ · method
Method _AttentionCapture.__call__ calls self._query_extractor, self._query_buffer[self._buf_idx].append, self._original; returns self._original(x, mask=mask, cache=cache).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
x |
not annotated |
yes |
none |
Required positional or keyword input. |
mask |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
cache |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
self._original(x, mask=mask, cache=cache)
Exceptions and behavior
Method _AttentionCapture.__call__ calls self._query_extractor, self._query_buffer[self._buf_idx].append, self._original; returns self._original(x, mask=mask, cache=cache).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._AttentionCapture.__getattr__ · method
Method _AttentionCapture.__getattr__ calls getattr; returns getattr(self._original, name).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
name |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
getattr(self._original, name)
Exceptions and behavior
Method _AttentionCapture.__getattr__ calls getattr; returns getattr(self._original, name).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._qwen35_extract_queries · function
Extract post-RoPE queries from Qwen3.5 attention (gate split + q_norm).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
attn |
not annotated |
yes |
none |
Required positional or keyword input. |
x |
not annotated |
yes |
none |
Required positional or keyword input. |
cache |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
queries
Exceptions and behavior
Function _qwen35_extract_queries calls attn.q_proj, mx.split, q_out.reshape, attn.q_norm(queries).transpose; returns queries.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._llama_extract_queries · function
Extract post-RoPE queries from standard transformer attention.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
attn |
not annotated |
yes |
none |
Required positional or keyword input. |
x |
not annotated |
yes |
none |
Required positional or keyword input. |
cache |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
queries
Exceptions and behavior
Function _llama_extract_queries calls getattr, attn.q_proj, queries.reshape(B, L, n_heads, -1).transpose, queries.reshape; returns queries.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._nemotron_h_extract_queries · function
Extract queries from Nemotron-H attention (no RoPE, no gate, no q_norm).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
attn |
not annotated |
yes |
none |
Required positional or keyword input. |
x |
not annotated |
yes |
none |
Required positional or keyword input. |
cache |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
queries
Exceptions and behavior
Function _nemotron_h_extract_queries calls attn.q_proj(x).reshape(B, L, attn.num_heads, -1).transpose, attn.q_proj(x).reshape, attn.q_proj; returns queries.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._patch_attention_for_capture · function
vllm_mlx.specprefill._patch_attention_for_capture(model, query_buffer, query_extractor = None) -> not annotated
Replace attention modules on full-attention layers with capture wrappers.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
query_buffer |
not annotated |
yes |
none |
Required positional or keyword input. |
query_extractor |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
(originals, attn_indices)
Exceptions and behavior
Function _patch_attention_for_capture calls _find_attention_layers, len, attn_indices.append, _get_attn_module; returns (originals, attn_indices).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._unpatch_attention_capture · function
Restore original attention modules after capture.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
originals |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated
Exceptions and behavior
Function _unpatch_attention_capture calls _set_attn_module.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._prefill_draft · function
vllm_mlx.specprefill._prefill_draft(model, tokens, cache, step_size = 2048, cancel_check = None) -> not annotated
Prefill prompt tokens into cache.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
tokens |
not annotated |
yes |
none |
Required positional or keyword input. |
cache |
not annotated |
yes |
none |
Required positional or keyword input. |
step_size |
not annotated |
no |
2048 |
Optional positional or keyword input; defaults to 2048. |
cancel_check |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
logits
Exceptions and behavior
Function _prefill_draft calls isinstance, mx.array, len, cancel_check; returns logits.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._lookahead_decode · function
vllm_mlx.specprefill._lookahead_decode(model, first_logits, cache, n_steps, temp = 0.6, top_p = 0.95, cancel_check = None) -> not annotated
Run n_steps autoregressive decode, returning generated token ids.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
first_logits |
not annotated |
yes |
none |
Required positional or keyword input. |
cache |
not annotated |
yes |
none |
Required positional or keyword input. |
n_steps |
not annotated |
yes |
none |
Required positional or keyword input. |
temp |
not annotated |
no |
0.6 |
Optional positional or keyword input; defaults to 0.6. |
top_p |
not annotated |
no |
0.95 |
Optional positional or keyword input; defaults to 0.95. |
cancel_check |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
generated
Exceptions and behavior
Function _lookahead_decode calls make_sampler, cancel_check, sampler, mx.eval; returns generated.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._avg_pool1d · function
1D average pooling along last axis via prefix-sum.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
x |
not annotated |
yes |
none |
(..., M) input |
kernel_size |
not annotated |
yes |
none |
window size (odd for centered) |
Returns
- Type:
not annotated - Direct return expressions:
x;(prefix[..., kernel_size:] - prefix[..., :-kernel_size]) / kernel_size
Exceptions and behavior
Function _avg_pool1d calls mx.pad, mx.zeros, mx.concatenate, mx.cumsum; has 2 explicit return paths.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._compute_importance · function
vllm_mlx.specprefill._compute_importance(query_buffer, attn_caches, n_prompt, n_attn_heads, n_kv_heads, pool_kernel = 13) -> not annotated
Compute per-token importance from captured queries and cached keys.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
query_buffer |
not annotated |
yes |
none |
Required positional or keyword input. |
attn_caches |
not annotated |
yes |
none |
Required positional or keyword input. |
n_prompt |
not annotated |
yes |
none |
Required positional or keyword input. |
n_attn_heads |
not annotated |
yes |
none |
Required positional or keyword input. |
n_kv_heads |
not annotated |
yes |
none |
Required positional or keyword input. |
pool_kernel |
not annotated |
no |
13 |
Optional positional or keyword input; defaults to 13. |
Returns
- Type:
not annotated - Direct return expressions:
importance
Exceptions and behavior
Function _compute_importance calls enumerate, mx.concatenate, mx.repeat, expanded_keys.transpose; can raise RuntimeError; returns importance.
Directly raised exceptions: RuntimeError.
vllm_mlx.specprefill.score_tokens · function
vllm_mlx.specprefill.score_tokens(model, tokens, n_lookahead = 8, pool_kernel = 13, temp = 0.6, top_p = 0.95, prefill_step_size = 2048, query_extractor = None, cancel_check = None) -> not annotated
Score token importance using attention-based analysis on a draft model.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Draft model (small, fast — e.g. 4B) |
tokens |
not annotated |
yes |
none |
list or mx.array of token IDs |
n_lookahead |
not annotated |
no |
8 |
decode steps for query capture (default 8) |
pool_kernel |
not annotated |
no |
13 |
smoothing kernel for avg_pool1d (default 13, 0=disable) |
temp |
not annotated |
no |
0.6 |
sampling temperature for lookahead (default 0.6) |
top_p |
not annotated |
no |
0.95 |
top-p for lookahead (default 0.95) |
prefill_step_size |
not annotated |
no |
2048 |
chunk size for draft prefill (default 2048) |
query_extractor |
not annotated |
no |
None |
function(attn, x, cache) → queries tensor. |
cancel_check |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
importance
Exceptions and behavior
Function score_tokens calls isinstance, tokens.tolist, len, _find_attention_layers; returns importance.
No direct raise statement appears in this definition.
vllm_mlx.specprefill.select_chunks · function
vllm_mlx.specprefill.select_chunks(importance, keep_pct = 0.3, chunk_size = 32, backbone_pct = 0.0) -> not annotated
Select top-k% token chunks by average importance.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
importance |
not annotated |
yes |
none |
(M,) per-token importance scores |
keep_pct |
not annotated |
no |
0.3 |
fraction of chunks to keep (default 0.3) |
chunk_size |
not annotated |
no |
32 |
tokens per chunk (default 32) |
backbone_pct |
not annotated |
no |
0.0 |
fraction of chunks reserved for evenly-spaced coverage |
Returns
- Type:
not annotated - Direct return expressions:
mx.arange(M);mx.array(indices)
Exceptions and behavior
Function select_chunks calls mx.arange, math.ceil, max, range; has 2 explicit return paths.
No direct raise statement appears in this definition.
vllm_mlx.specprefill.select_chunks._selected_token_count · nested function
Nested Function select_chunks._selected_token_count calls min; returns total.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
chunks |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
total
Exceptions and behavior
Nested Function select_chunks._selected_token_count calls min; returns total.
No direct raise statement appears in this definition.
vllm_mlx.specprefill.manual_rope · function
Apply RoPE at arbitrary (non-contiguous) positions.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
x |
not annotated |
yes |
none |
(B, n_heads, L, head_dim) input tensor |
positions |
not annotated |
yes |
none |
(L,) position indices (can be non-contiguous) |
dims |
not annotated |
yes |
none |
number of dimensions to rotate (head_dim * partial_rotary_factor) |
base |
not annotated |
no |
10000.0 |
RoPE base frequency (default 10000.0) |
scale |
not annotated |
no |
1.0 |
position scale divisor (default 1.0, higher = compressed positions) |
Returns
- Type:
not annotated - Direct return expressions:
mx.concatenate([rotated, x_pass], axis=-1)
Exceptions and behavior
Function manual_rope calls mx.arange, positions.astype, mx.cos, mx.sin; returns mx.concatenate([rotated, x_pass], axis=-1).
No direct raise statement appears in this definition.
vllm_mlx.specprefill.manual_rope_with_freqs · function
vllm_mlx.specprefill.manual_rope_with_freqs(x, positions, dims, freqs, pre_scale = 1.0) -> not annotated
Apply RoPE at arbitrary positions using pre-computed frequencies.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
x |
not annotated |
yes |
none |
Required positional or keyword input. |
positions |
not annotated |
yes |
none |
Required positional or keyword input. |
dims |
not annotated |
yes |
none |
Required positional or keyword input. |
freqs |
not annotated |
yes |
none |
Required positional or keyword input. |
pre_scale |
not annotated |
no |
1.0 |
Optional positional or keyword input; defaults to 1.0. |
Returns
- Type:
not annotated - Direct return expressions:
mx.concatenate([rotated, x_pass], axis=-1)
Exceptions and behavior
Function manual_rope_with_freqs calls (1.0 / freqs).astype, positions[:, None].astype, mx.cos, mx.sin; returns mx.concatenate([rotated, x_pass], axis=-1).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._PositionMappedRoPE · class
Wraps a RoPE module to apply rotation at non-contiguous positions.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
original_rope |
not annotated |
yes |
none |
Required positional or keyword input. |
all_positions |
not annotated |
yes |
none |
Required positional or keyword input. |
cache_start |
not annotated |
no |
0 |
Optional positional or keyword input; defaults to 0. |
Returns
- Constructs:
vllm_mlx.specprefill._PositionMappedRoPE
Exceptions and behavior
Class _PositionMappedRoPE declares 2 direct member(s).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._PositionMappedRoPE.__init__ · method
vllm_mlx.specprefill._PositionMappedRoPE.__init__(original_rope, all_positions, cache_start = 0) -> not annotated
Method _PositionMappedRoPE.__init__ updates self._original, self._all_positions, self._cache_start, self._has_custom_freqs; calls hasattr, _get_dims, _get_pre_scale.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
original_rope |
not annotated |
yes |
none |
Required positional or keyword input. |
all_positions |
not annotated |
yes |
none |
Required positional or keyword input. |
cache_start |
not annotated |
no |
0 |
Optional positional or keyword input; defaults to 0. |
Returns
- Type:
not annotated
Exceptions and behavior
Method _PositionMappedRoPE.__init__ updates self._original, self._all_positions, self._cache_start, self._has_custom_freqs; calls hasattr, _get_dims, _get_pre_scale.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._PositionMappedRoPE.__call__ · method
Method _PositionMappedRoPE.__call__ calls manual_rope_with_freqs, manual_rope; has 2 explicit return paths.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
x |
not annotated |
yes |
none |
Required positional or keyword input. |
offset |
not annotated |
no |
0 |
Optional positional or keyword input; defaults to 0. |
Returns
- Type:
not annotated - Direct return expressions:
manual_rope_with_freqs(x, positions, self._dims, self._freqs, pre_scale=self._pre_scale);manual_rope(x, positions, self._dims, base=self._base, scale=self._scale)
Exceptions and behavior
Method _PositionMappedRoPE.__call__ calls manual_rope_with_freqs, manual_rope; has 2 explicit return paths.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._OffsetAdjustedRoPE · class
Wraps a RoPE module to add a constant offset for decode after sparse prefill.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
original_rope |
not annotated |
yes |
none |
Required positional or keyword input. |
adjustment |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Constructs:
vllm_mlx.specprefill._OffsetAdjustedRoPE
Exceptions and behavior
Class _OffsetAdjustedRoPE declares 2 direct member(s).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._OffsetAdjustedRoPE.__init__ · method
Method _OffsetAdjustedRoPE.__init__ updates self._original, self._adjustment.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
original_rope |
not annotated |
yes |
none |
Required positional or keyword input. |
adjustment |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated
Exceptions and behavior
Method _OffsetAdjustedRoPE.__init__ updates self._original, self._adjustment.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._OffsetAdjustedRoPE.__call__ · method
Method _OffsetAdjustedRoPE.__call__ calls self._original; returns self._original(x, offset=offset + self._adjustment).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
x |
not annotated |
yes |
none |
Required positional or keyword input. |
offset |
not annotated |
no |
0 |
Optional positional or keyword input; defaults to 0. |
Returns
- Type:
not annotated - Direct return expressions:
self._original(x, offset=offset + self._adjustment)
Exceptions and behavior
Method _OffsetAdjustedRoPE.__call__ calls self._original; returns self._original(x, offset=offset + self._adjustment).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._get_dims · function
Extract rotary dimensions from any RoPE variant.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
rope_module |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
getattr(rope_module, attr)
Exceptions and behavior
Function _get_dims calls hasattr, getattr, ValueError, type; can raise ValueError; returns getattr(rope_module, attr).
Directly raised exceptions: ValueError.
vllm_mlx.specprefill._get_pre_scale · function
Extract pre-scale factor from custom RoPE variants (SuScaled, Yarn).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
rope_module |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
rope_module.mscale;rope_module._scale;1.0
Exceptions and behavior
Function _get_pre_scale calls hasattr; has 3 explicit return paths.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._find_attention_layers · function
Find all full-attention layers across architectures.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
results
Exceptions and behavior
Function _find_attention_layers calls enumerate, hasattr, results.append, getattr; returns results.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._get_attn_module · function
Get the attention module from a layer (self_attn or mixer).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
layer |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
layer.self_attn;layer.mixer;None
Exceptions and behavior
Function _get_attn_module calls hasattr, getattr; has 3 explicit return paths.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._get_rope · function
Get the RoPE module from an attention layer, or None.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
attn |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
getattr(attn, 'rope', None) or getattr(attn, 'rotary_emb', None)
Exceptions and behavior
Function _get_rope calls getattr; returns getattr(attn, 'rope', None) or getattr(attn, 'rotary_emb', None).
No direct raise statement appears in this definition.
vllm_mlx.specprefill._set_rope · function
Set the RoPE module on an attention layer.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
attn |
not annotated |
yes |
none |
Required positional or keyword input. |
rope_module |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated
Exceptions and behavior
Function _set_rope calls hasattr.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._set_attn_module · function
Set the attention module on a layer (self_attn or mixer).
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
layer |
not annotated |
yes |
none |
Required positional or keyword input. |
module |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated
Exceptions and behavior
Function _set_attn_module calls hasattr, getattr.
No direct raise statement appears in this definition.
vllm_mlx.specprefill._build_layer_to_cache_map · function
Build mapping from model layer index to cache index.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated - Direct return expressions:
{i: i for i in range(len(model.layers))};layer_to_cache
Exceptions and behavior
Function _build_layer_to_cache_map calls any, hasattr, range, len; has 2 explicit return paths.
No direct raise statement appears in this definition.
vllm_mlx.specprefill.sparse_prefill · function
vllm_mlx.specprefill.sparse_prefill(model, tokens, selected_indices, cache, step_size = 2048, position_offset = 0, cancel_check = None) -> not annotated
Prefill the model cache with selected tokens at their original positions.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Language model with .layers property (TextModel or VLM Model) |
tokens |
not annotated |
yes |
none |
(M,) all prompt token IDs (mx.array or list) |
selected_indices |
not annotated |
yes |
none |
(N,) sorted indices into tokens to keep (mx.array or list) |
cache |
not annotated |
yes |
none |
list of KVCache/ArraysCache from make_prompt_cache() |
step_size |
not annotated |
no |
2048 |
chunk size for processing (default 2048) |
position_offset |
not annotated |
no |
0 |
added to selected_indices for RoPE positions (default 0). Use when the cache already has tokens from a prior prefill (e.g., system prompt KV cache with S tokens → position_offset=S). |
cancel_check |
not annotated |
no |
None |
Optional positional or keyword input; defaults to None. |
Returns
- Type:
not annotated - Direct return expressions:
logits
Exceptions and behavior
Function sparse_prefill calls isinstance, mx.array, type, max; returns logits.
No direct raise statement appears in this definition.
vllm_mlx.specprefill.cleanup_rope · function
Restore original RoPE on all attention layers.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
model |
not annotated |
yes |
none |
Required positional or keyword input. |
Returns
- Type:
not annotated
Exceptions and behavior
Function cleanup_rope calls _find_attention_layers, _get_attn_module, _get_rope, isinstance.
No direct raise statement appears in this definition.
Complete symbol map¶
This map also includes private definitions and nested helpers. The signature column exposes every explicit input even when an internal helper has no dedicated parameter prose.
| Symbol | Kind | Signature and inputs | What it does | Source |
|---|---|---|---|---|
_AttentionCapture |
class | _AttentionCapture(original, buf_idx, query_buffer, query_extractor = None) |
Wrapper that captures post-RoPE query vectors and delegates to original. | #L53-L73 |
_AttentionCapture.__init__ |
method | _AttentionCapture.__init__(original, buf_idx, query_buffer, query_extractor = None) -> not annotated |
Method _AttentionCapture.__init__ updates self._original, self._buf_idx, self._query_buffer, self._query_extractor. |
#L61-L65 |
_AttentionCapture.__call__ |
method | _AttentionCapture.__call__(x, mask = None, cache = None) -> not annotated |
Method _AttentionCapture.__call__ calls self._query_extractor, self._query_buffer[self._buf_idx].append, self._original; returns self._original(x, mask=mask, cache=cache). |
#L67-L70 |
_AttentionCapture.__getattr__ |
method | _AttentionCapture.__getattr__(name) -> not annotated |
Method _AttentionCapture.__getattr__ calls getattr; returns getattr(self._original, name). |
#L72-L73 |
_qwen35_extract_queries |
function | _qwen35_extract_queries(attn, x, cache = None) -> not annotated |
Extract post-RoPE queries from Qwen3.5 attention (gate split + q_norm). | #L76-L92 |
_llama_extract_queries |
function | _llama_extract_queries(attn, x, cache = None) -> not annotated |
Extract post-RoPE queries from standard transformer attention. | #L95-L113 |
_nemotron_h_extract_queries |
function | _nemotron_h_extract_queries(attn, x, cache = None) -> not annotated |
Extract queries from Nemotron-H attention (no RoPE, no gate, no q_norm). | #L116-L125 |
_patch_attention_for_capture |
function | _patch_attention_for_capture(model, query_buffer, query_extractor = None) -> not annotated |
Replace attention modules on full-attention layers with capture wrappers. | #L128-L149 |
_unpatch_attention_capture |
function | _unpatch_attention_capture(model, originals) -> not annotated |
Restore original attention modules after capture. | #L152-L155 |
_prefill_draft |
function | _prefill_draft(model, tokens, cache, step_size = 2048, cancel_check = None) -> not annotated |
Prefill prompt tokens into cache. | #L158-L175 |
_lookahead_decode |
function | _lookahead_decode(model, first_logits, cache, n_steps, temp = 0.6, top_p = 0.95, cancel_check = None) -> not annotated |
Run n_steps autoregressive decode, returning generated token ids. | #L178-L204 |
_avg_pool1d |
function | _avg_pool1d(x, kernel_size) -> not annotated |
1D average pooling along last axis via prefix-sum. | #L207-L223 |
_compute_importance |
function | _compute_importance(query_buffer, attn_caches, n_prompt, n_attn_heads, n_kv_heads, pool_kernel = 13) -> not annotated |
Compute per-token importance from captured queries and cached keys. | #L226-L271 |
score_tokens |
function | score_tokens(model, tokens, n_lookahead = 8, pool_kernel = 13, temp = 0.6, top_p = 0.95, prefill_step_size = 2048, query_extractor = None, cancel_check = None) -> not annotated |
Score token importance using attention-based analysis on a draft model. | #L274-L396 |
select_chunks |
function | select_chunks(importance, keep_pct = 0.3, chunk_size = 32, backbone_pct = 0.0) -> not annotated |
Select top-k% token chunks by average importance. | #L399-L467 |
select_chunks._selected_token_count |
nested function | select_chunks._selected_token_count(chunks) -> not annotated |
Nested Function select_chunks._selected_token_count calls min; returns total. |
#L437-L443 |
manual_rope |
function | manual_rope(x, positions, dims, base = 10000.0, scale = 1.0) -> not annotated |
Apply RoPE at arbitrary (non-contiguous) positions. | #L480-L508 |
manual_rope_with_freqs |
function | manual_rope_with_freqs(x, positions, dims, freqs, pre_scale = 1.0) -> not annotated |
Apply RoPE at arbitrary positions using pre-computed frequencies. | #L511-L528 |
_PositionMappedRoPE |
class | _PositionMappedRoPE(original_rope, all_positions, cache_start = 0) |
Wraps a RoPE module to apply rotation at non-contiguous positions. | #L536-L571 |
_PositionMappedRoPE.__init__ |
method | _PositionMappedRoPE.__init__(original_rope, all_positions, cache_start = 0) -> not annotated |
Method _PositionMappedRoPE.__init__ updates self._original, self._all_positions, self._cache_start, self._has_custom_freqs; calls hasattr, _get_dims, _get_pre_scale. |
#L547-L561 |
_PositionMappedRoPE.__call__ |
method | _PositionMappedRoPE.__call__(x, offset = 0) -> not annotated |
Method _PositionMappedRoPE.__call__ calls manual_rope_with_freqs, manual_rope; has 2 explicit return paths. |
#L563-L571 |
_OffsetAdjustedRoPE |
class | _OffsetAdjustedRoPE(original_rope, adjustment) |
Wraps a RoPE module to add a constant offset for decode after sparse prefill. | #L574-L590 |
_OffsetAdjustedRoPE.__init__ |
method | _OffsetAdjustedRoPE.__init__(original_rope, adjustment) -> not annotated |
Method _OffsetAdjustedRoPE.__init__ updates self._original, self._adjustment. |
#L585-L587 |
_OffsetAdjustedRoPE.__call__ |
method | _OffsetAdjustedRoPE.__call__(x, offset = 0) -> not annotated |
Method _OffsetAdjustedRoPE.__call__ calls self._original; returns self._original(x, offset=offset + self._adjustment). |
#L589-L590 |
_get_dims |
function | _get_dims(rope_module) -> not annotated |
Extract rotary dimensions from any RoPE variant. | #L598-L603 |
_get_pre_scale |
function | _get_pre_scale(rope_module) -> not annotated |
Extract pre-scale factor from custom RoPE variants (SuScaled, Yarn). | #L606-L612 |
_find_attention_layers |
function | _find_attention_layers(model) -> not annotated |
Find all full-attention layers across architectures. | #L615-L630 |
_get_attn_module |
function | _get_attn_module(layer) -> not annotated |
Get the attention module from a layer (self_attn or mixer). | #L633-L639 |
_get_rope |
function | _get_rope(attn) -> not annotated |
Get the RoPE module from an attention layer, or None. | #L642-L647 |
_set_rope |
function | _set_rope(attn, rope_module) -> not annotated |
Set the RoPE module on an attention layer. | #L650-L655 |
_set_attn_module |
function | _set_attn_module(layer, module) -> not annotated |
Set the attention module on a layer (self_attn or mixer). | #L658-L663 |
_build_layer_to_cache_map |
function | _build_layer_to_cache_map(model) -> not annotated |
Build mapping from model layer index to cache index. | #L666-L690 |
sparse_prefill |
function | sparse_prefill(model, tokens, selected_indices, cache, step_size = 2048, position_offset = 0, cancel_check = None) -> not annotated |
Prefill the model cache with selected tokens at their original positions. | #L698-L827 |
cleanup_rope |
function | cleanup_rope(model) -> not annotated |
Restore original RoPE on all attention layers. | #L830-L845 |