Install native-sparse-attention-pytorch
mainInstall the core package using pip:
$ pip install native-sparse-attention-pytorchrepository·main·Indexed 21 days ago
https://github.com/lucidrains/native-sparse-attention-pytorchA PyTorch implementation of the Native Sparse Attention pattern proposed by the Deepseek team. It provides a hardware-aligned, natively trainable mechanism that combines compressed attention, fine-grained selection attention, and sliding window attention. The library includes the SparseAttention class, various compression networks (ConvLinearCompress, AttentionPool, GroupedMLP, SingleProjection, CompressTransformer), and support for PyTorch's flex_attention and custom Triton kernels for optimized inference and training.
Install the core package using pip:
$ pip install native-sparse-attention-pytorchThe Triton-based kernels in this project require a specific version of Triton. It is recommended to install triton-nightly to ensure compatibility with the kernels.
Run the following command to install the required version:
pip install -U --index-url https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/Triton-Nightly/pypi/simple/ triton-nightlyNote: The project requires triton >= 3.0.0.
pip install -U --index-url https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/Triton-Nightly/pypi/simple/ triton-nightlyThe NSA class is a torch.autograd.Function implementation that wraps the Triton kernels. It manages the forward and backward passes for the sparse attention mechanism.
Forward Pass Requirements:
fq, fk, and fv are cast to half precision internally.fq, fk, fv, selected_block_indices, fmask, out, slide_out, lse, slide_lse) for the backward pass.sel_scale is provided, it enables gradient computation for the selection mechanism (must be 1.0 for straight-through).Backward Pass Behavior:
dq), keys (dk), and values (dv).return_sel_grads is enabled, it also returns gradients for the selection indices (sel_grads).return_sliding_window_out was used in the forward pass.The SparseAttention module combines three pathways using a learned strategy_combine_mlp with a Sigmoid activation. The output is a weighted sum of the three branches:
compressed_attn_out): Performs coarse attention over a reduced set of KV tokens generated by a compression MLP. This captures long-range dependencies efficiently.fine_attn_out): Uses the importance scores from the compressed pathway to select the most relevant num_selected_blocks of high-resolution KV tokens for detailed attention.sliding_window_attn_out): Performs standard local attention on the most recent tokens to ensure high-fidelity local context.This combination allows the model to balance computational efficiency (via compression) with high-resolution accuracy (via fine selection and sliding windows).
The Transformer implementation integrates sparse attention through two primary paths:
Standard Attention: If use_sparse_attn is False, it uses the standard Attention class which performs dense scaled dot-product attention.
Sparse Attention: If use_sparse_attn is True, it instantiates SparseAttention layers. These layers can be configured for:
When using flex_attention (via use_flex_sliding_window or use_flex_fine_selection), the model automatically generates appropriate block masks using create_sliding_mask or create_fine_mask to optimize the attention pattern on supported hardware.
For autoregressive generation, use the forward method with a cache object. The cache is a nested tuple containing:
cache_kv: (cache_k, cache_v) for standard KV storage.cache_compressed_kv: ((cache_ck, cache_cv), (run_k, run_v)) where ck/cv are compressed tokens and run_k/run_v are the running uncompressed tokens used for the next compression step.Note: During inference, the input inp must have a sequence length of 1.
# Initial forward pass to get cache
cache = None
out, cache = model(inp, return_cache=True)
# Subsequent inference steps
# inp_next must be (batch, 1, dim)
out_next, cache = model(inp_next, cache=cache, return_cache=True)To run the Enwik8 language modeling example, you must install the package with the [examples] extra, then execute the training script.
pip install .[examples]python train.pyNote: To record experiments via Weights & Biases, run wandb login before starting the training script.
$ pip install .[examples]
$ python train.pyThe SparseAttention class implements the sparse attention pattern proposed by the Deepseek team. It allows for hardware-aligned and natively trainable sparse attention.
Key parameters for initialization:
dim: The input dimension.dim_head: The dimension of each attention head.heads: The number of attention heads.sliding_window_size: Size of the sliding window.compress_block_size: Size of the compression blocks.compress_block_sliding_stride: Stride for the compression block sliding window.selection_block_size: Size of the selection blocks.num_selected_blocks: Number of blocks to be selected.import torch
from native_sparse_attention_pytorch import SparseAttention
attn = SparseAttention(
dim = 512,
dim_head = 64,
heads = 8,
sliding_window_size = 2,
compress_block_size = 4,
compress_block_sliding_stride = 2,
selection_block_size = 4,
num_selected_blocks = 2
)
tokens = torch.randn(2, 31, 512)
attended = attn(tokens)
assert tokens.shape == attended.shapeWhen initializing SparseAttention, use the following parameters to control the sparsity and attention behavior:
| Parameter | Description |
|---|---|
dim | Input feature dimension |
dim_head | Dimension of each attention head |
heads | Total number of query heads |
kv_heads | Number of key/value heads (set < heads for GQA) |
sliding_window_size | Size of the local sliding window |
compress_block_size | Size of the blocks used for compression |
compress_block_sliding_stride | Stride for the compression window |
selection_block_size | Size of the blocks used for fine-grained selection |
num_selected_blocks | Number of top-k KV blocks to select for fine attention |
num_compressed_mem_kv | Number of compressed KV tokens to keep in memory |
causal | Whether to apply causal masking |
query_heads_share_selected_kv | If True, importance scores are averaged across query heads to select KV buckets. If False, each query head can select different buckets (higher compute/memory). |
use_diff_topk | Whether to use differential top-k gating for training |
use_triton_kernel | Whether to use the optimized Triton kernel for fine attention |
The implementation provides utility functions to create block_mask objects compatible with PyTorch's flex_attention. These can be passed to SparseAttention.forward via sliding_window_flex_mask or fine_selection_flex_mask to accelerate computation.
create_sliding_mask(seq_len, window_size, causal=True): Creates a mask for local sliding window attention.create_compress_mask(seq_len, kv_seq_len, compress_block_sliding_stride, mem_kv_len=0, causal=True): Creates a mask for the compressed attention pathway.create_fine_mask(seq_len, fine_block_size, causal=True): Returns a function that, when used with create_block_mask, defines the fine-grained selection mask based on provided selected_block_indices.from torch.nn.attention.flex_attention import create_block_mask
# Example: Creating a sliding window mask for flex_attention
seq_len = 1024
window_size = 128
def sliding_mask(_, __, q_idx, kv_idx):
distance = q_idx - kv_idx
backward_sliding_mask = distance <= window_size
forward_distance = 0 # assuming causal
forward_sliding_mask = distance >= forward_distance
return backward_sliding_mask & forward_sliding_mask
block_mask = create_block_mask(sliding_mask, B=None, H=None, Q_LEN=seq_len, KV_LEN=seq_len, _compile=True)The Transformer class is the main entry point for building a model with sparse attention capabilities. You can choose between standard dense attention or various sparse attention mechanisms (sliding window, fine selection, etc.) using the use_sparse_attn flag and specific configuration kwargs.
Key configuration parameters:
num_tokens: Vocabulary size.dim: Model dimension.depth: Number of layers.use_sparse_attn: Set to True to enable sparse attention modes.use_flex_sliding_window: Enables sliding window attention using PyTorch's flex_attention.use_flex_fine_selection: Enables fine-grained selection using flex_attention.use_triton_fine_selection: Enables fine-grained selection using a custom Triton kernel (cannot be used with use_flex_fine_selection).sparse_attn_kwargs: A dictionary passed to the underlying SparseAttention module to configure window sizes, block sizes, and selection parameters.from native_sparse_attention_pytorch.transformer import Transformer
model = Transformer(
num_tokens = 50257,
dim = 512,
depth = 12,
use_sparse_attn = True,
use_flex_sliding_window = True,
sparse_attn_kwargs = dict(
sliding_window_size = 64,
compress_block_size = 4,
compress_block_overlap_len = 0,
selection_block_size = 4,
num_selected_blocks = 4,
)
)The native_sparse_attn_forward function provides a Triton-accelerated implementation of sparse attention. It supports causal masking, sliding window attention, and grouped query attention (GQA).
Requirements:
q, k, v, and kv_block_indices must be contiguous tensors.q, k, and v must be on a CUDA device.q, k, and v must have the same dtype (either torch.float16 or torch.bfloat16).dim) must be $\le 128$.kv_block_indices and kv_block_mask must have matching shapes.Parameters:
q: Query tensor of shape (batch, nheads, seqlen_q, dim).k: Key tensor of shape (batch, kv_heads, seqlen_k, dim).v: Value tensor of shape (batch, kv_heads, seqlen_k, dim).kv_block_indices: Indices of selected KV blocks.kv_block_mask: Mask for the selected KV blocks.block_size: Size of the attention block (must be a multiple of 16; default is 128).include_block_causal: Whether to include block-diagonal causal masking (default True).return_sliding_window_out: If True, returns both the standard output and a sliding window output.Returns:
o: The attention output tensor.slide_o: The sliding window attention output (only if return_sliding_window_out is True).lse: Log-sum-exp statistics for the attention.slide_lse: Log-sum-exp statistics for the sliding window (only if return_sliding_window_out is True).from native_sparse_attention_pytorch.triton_native_sparse_attention import native_sparse_attn_forward
# Example usage (shapes are illustrative)
o, slide_o, lse, slide_lse = native_sparse_attn_forward(
q=q,
k=k,
v=v,
kv_block_indices=kv_block_indices,
kv_block_mask=kv_block_mask,
block_size=128,
include_block_causal=True,
return_sliding_window_out=True
)