Navigation
πŸ”§ CUDA & Kernel EngineeringΒ· 10 min read

Block-Sparse & Linear Attention Kernels

Beyond dense attention β€” sparse masks, sliding window, linear attention approximations, and their kernel implementations.

cudasparse-attentionlinear-attentionsliding-windowblock-sparse

Dense attention computes every token-to-token interaction. For many workloads, most of these interactions are unnecessary β€” a token 50K positions away rarely matters. Sparse and linear attention kernels exploit this structure for efficiency.


1. Why Sparse Attention?

Dense attention: O(S2)O(S^2) compute and memory. For S=128K, that’s 16 billion operations per head per layer.

But attention weights are often sparse in practice β€” most attention mass concentrates on:

  • Nearby tokens (local context)
  • A few globally important tokens (BOS, separator, key entities)
  • Structured patterns (every-Nth token for summarization)

If we can skip the near-zero entries, we save compute proportional to the sparsity.


2. Block-Sparse Attention

The Idea

Instead of computing every position pair, define a mask at the block level: which blocks of Q attend to which blocks of K/V.

Block mask (16Γ—16 blocks, each covers 256 tokens):

    K blocks: 0  1  2  3  4  5  6  7 ...
Q block 0:    β–   β–   β–‘  β–‘  β–‘  β–‘  β–‘  β–‘      ← causal, attend to self + neighbor
Q block 1:    β–   β–   β–   β–‘  β–‘  β–‘  β–‘  β–‘
Q block 2:    β–‘  β–   β–   β–   β–‘  β–‘  β–‘  β–‘      ← sliding window pattern
Q block 3:    β–‘  β–‘  β–   β–   β–   β–‘  β–‘  β–‘
...

β–  = compute attention (dense within block)
β–‘ = skip (zero attention)

Kernel Implementation

Block-sparse attention uses the same FlashAttention tiling β€” but skips tiles where the mask says zero:

# Pseudocode: block-sparse FlashAttention
for each Q block i:
    for each K/V block j WHERE mask[i][j] == 1:  # skip zero blocks
        compute_attention_tile(Q_i, K_j, V_j)

If the mask has density dd (fraction of non-zero blocks), compute is O(dΓ—S2)O(d \times S^2) instead of O(S2)O(S^2).

Common Sparse Patterns

PatternDescriptionDensityUse case
CausalLower triangle50%Standard LLM (already used everywhere)
Sliding windowLocal band of width www/Sw/SMistral, local context models
StridedEvery k-th block1/k1/kLongformer-style global + local
CustomData-dependentVariesDynamic sparse attention

Sliding Window Attention (Mistral)

Mistral uses a sliding window of W=4096W=4096 tokens β€” each token attends only to the nearest 4K tokens:

Attention(qi,K,V)=softmax(qiK[iβˆ’W:i]⊀dk)V[iβˆ’W:i]\text{Attention}(q_i, K, V) = \text{softmax}\left(\frac{q_i K_{[i-W:i]}^\top}{\sqrt{d_k}}\right) V_{[i-W:i]}

Complexity: O(SΓ—W)O(S \times W) instead of O(S2)O(S^2). For S=128K, W=4K: 32Γ—32\times reduction.

KV cache benefit: Only the most recent WW tokens’ KV cache is needed β€” old entries can be evicted. This caps KV cache at a fixed size regardless of conversation length.


3. Linear Attention

The Idea

Standard attention:

O=softmax(QK⊀)VO(S2dk)O = \text{softmax}(QK^\top) V \qquad O(S^2 d_k)

Linear attention removes softmax and uses a kernel trick:

O=Ο•(Q)(Ο•(K)⊀V)O(Sdk2)O = \phi(Q) (\phi(K)^\top V) \qquad O(S d_k^2)

By computing Ο•(K)⊀V\phi(K)^\top V first (shape dkΓ—dkd_k \times d_k), then multiplying by Ο•(Q)\phi(Q), we avoid the SΓ—SS \times S matrix entirely.

The Tradeoff

Dense attentionLinear attention
ComputeO(S2dk)O(S^2 d_k)O(Sdk2)O(S d_k^2)
MemoryO(S2)O(S^2) or O(S)O(S) with FlashAttnO(dk2)O(d_k^2) fixed state
QualityExactApproximate (no softmax)
Best whenS<dk2/dk=dkS < d_k^2 / d_k = d_k (always for S>128S > 128)Never competitive on quality for LLMs

In practice: No production LLM uses pure linear attention. The approximation quality gap is too large for tasks requiring precise recall.

Hybrid Approaches

State-space models (Mamba) and hybrid architectures (Jamba) use linear-time recurrence for most layers and standard attention for a few β€œretrieval” layers. This is covered in the Attention Variants chapter.


4. Kernel Implementation Challenges

Block-Sparse Challenges

ChallengeSolution
Irregular memory accessPrecompute block indices, use gather
Load imbalanceDynamic block scheduling
Warp utilizationChoose block size β‰₯ warp size (32)
Mask representationCompressed sparse row (CSR) or block-level bitmap

FlashAttention + Sparsity

FlashAttention V2 natively supports block-sparse masks:

from flash_attn import flash_attn_func

# Custom block-sparse mask
# block_mask[i][j] = True if Q block i attends to K block j
output = flash_attn_func(Q, K, V, causal=False, block_mask=block_mask)

The kernel skips tiles where block_mask[i][j] = False β€” no wasted compute.


5. When to Use Which

Attention typeBest forKV cacheQuality
Dense causalStandard LLM servingFull (grows with S)Best
Sliding windowLong context with local biasCapped at WGood (loses very distant context)
Block-sparseDomain-specific patternsDepends on patternGood if pattern matches task
LinearInfinite context streamingFixed sizeWorst (no precise recall)
Hybrid (Mamba+Attn)Long context with some retrievalMixedGood balance

Default recommendation: Use dense causal attention with FlashAttention V2. Switch to sliding window (Mistral-style) only if context length exceeds what KV cache can support. Use hybrid architectures for 100K+ context applications.


Self-Check

  • Explain why most attention weights are near-zero and how sparse attention exploits this
  • Explain sliding window attention and its KV cache benefit
  • Explain the order-of-operations trick that makes linear attention O(S dkΒ²)
  • Explain why linear attention isn’t used in production LLMs
  • Choose the right attention type for a given sequence length and quality requirement

References