Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Sgl project Sglang FA4 Interface

From Leeroopedia


Knowledge Sources
Domains Flash Attention, GPU Kernels, CUTLASS DSL
Last Updated 2026-02-10 00:00 GMT

Overview

Flash Attention 4 interface using the CUTLASS Cute DSL for JIT-compiled attention kernels targeting Hopper (SM90) and Blackwell (SM100/SM110) architectures.

Description

_fa4_interface.py implements the cutting-edge Flash Attention 4 (FA4) backend that leverages the CUTLASS Cute DSL to JIT-compile attention kernels via TVM FFI. This provides an alternative to the C++-based FA3 path, achieving maximum performance on the latest NVIDIA architectures.

The module contains two primary functions:

_flash_attn_fwd is the core forward attention function that handles the complete FA4 pipeline:

  • Architecture Detection: Caches device capability checks to select between FlashAttentionForwardSm90 (Hopper) and FlashAttentionForwardSm100 (Blackwell/SM110) implementations
  • Kernel Compilation and Caching: Uses a compile_cache dictionary keyed by a comprehensive tuple of configuration parameters (dtype, head_dim, causal, GQA ratio, block sizes, etc.) to avoid recompilation
  • Split-KV Support: Implements a num_splits_heuristic based on total M-blocks and SM count, with a combine kernel (FlashAttentionForwardCombine) that reduces partial outputs
  • Block Sparsity: Supports BlockSparseTensorsTorch for sparse attention patterns, with shape normalization and broadcasting
  • GQA Packing: Automatically enables GQA packing when qhead_per_kvhead > 1, with architecture-specific constraints (SM100 requires 128-divisible heads)
  • Tensor Conversion: Converts between PyTorch and Cute tensors via to_cute_tensor with configurable alignment and dynamic layout marking

flash_attn_varlen_func is the public API wrapped with the @warmup_flash_attn decorator. The warmup decorator:

  • Runs multiple warmup passes on first call covering global/causal/local attention, LSE on/off, and optional GQA packing
  • Clones arguments to avoid modifying user tensors
  • Releases GPU memory between warmup passes via torch.cuda.empty_cache()
  • Can be disabled via the SGLANG_DISABLE_FA4_WARMUP environment variable

The function supports:

  • Variable-length sequences via cu_seqlens_q and cu_seqlens_k
  • Paged KV cache via page_table (int32, with page_size constraints)
  • Causal and sliding window masking via window_size tuple
  • Softcapping via softcap parameter (converted to a score_mod internally)
  • Custom score/mask modifications via score_mod and aux_tensors
  • Learnable sink tokens via learnable_sink (bfloat16)
  • FP16 and BF16 input dtypes

Usage

Use this module when serving models on Hopper or Blackwell GPUs where FA4's JIT-compiled kernels can provide better performance than the pre-compiled FA3 path. It is typically accessed indirectly through the flash_attn.py module which dispatches between FA3 and FA4 based on the ver parameter.

Code Reference

Source Location

Signature

def _flash_attn_fwd(
    q: torch.Tensor,
    k: torch.Tensor,
    v: torch.Tensor,
    cu_seqlens_q: Optional[torch.Tensor] = None,
    cu_seqlens_k: Optional[torch.Tensor] = None,
    seqused_q: Optional[torch.Tensor] = None,
    seqused_k: Optional[torch.Tensor] = None,
    max_seqlen_q: Optional[int] = None,
    max_seqlen_k: Optional[int] = None,
    page_table: Optional[torch.Tensor] = None,
    softmax_scale: Optional[float] = None,
    causal: bool = False,
    softcap: Optional[float] = None,
    window_size_left: Optional[int] = None,
    window_size_right: Optional[int] = None,
    learnable_sink: Optional[torch.Tensor] = None,
    m_block_size: int = 128,
    n_block_size: int = 128,
    num_threads: int = 384,
    num_splits: int = 1,
    pack_gqa: Optional[bool] = None,
    _compute_capability: Optional[int] = None,
    score_mod: Optional[Callable] = None,
    mask_mod: Optional[Callable] = None,
    block_sparse_tensors: Optional[BlockSparseTensorsTorch] = None,
    return_lse: bool = False,
    out: Optional[torch.Tensor] = None,
    lse: Optional[torch.Tensor] = None,
    aux_tensors: Optional[list[torch.Tensor]] = None,
) -> Tuple[torch.Tensor, torch.Tensor]:

def flash_attn_varlen_func(
    q: torch.Tensor,
    k: torch.Tensor,
    v: torch.Tensor,
    cu_seqlens_q: Optional[torch.Tensor] = None,
    cu_seqlens_k: Optional[torch.Tensor] = None,
    seqused_q: Optional[torch.Tensor] = None,
    seqused_k: Optional[torch.Tensor] = None,
    page_table: Optional[torch.Tensor] = None,
    softmax_scale: Optional[float] = None,
    causal: bool = False,
    window_size: Tuple[Optional[int], Optional[int]] = (None, None),
    learnable_sink: Optional[torch.Tensor] = None,
    softcap: float = 0.0,
    num_splits: int = 1,
    pack_gqa: Optional[bool] = None,
    return_softmax_lse: Optional[bool] = False,
    score_mod: Optional[Callable] = None,
    aux_tensors: Optional[list] = None,
) -> Tuple[torch.Tensor, torch.Tensor]:

def num_splits_heuristic(total_mblocks, num_SMs, num_n_blocks, max_splits) -> int:

def maybe_contiguous(x):

def to_cute_tensor(t, assumed_align=16, leading_dim=-1, fully_dynamic=False):

Import

from sgl_kernel._fa4_interface import flash_attn_varlen_func

I/O Contract

Inputs

Name Type Required Description
q torch.Tensor (fp16/bf16) Yes Query tensor: (batch, seqlen_q, num_heads, head_dim) or (total_q, num_heads, head_dim)
k torch.Tensor (fp16/bf16) Yes Key tensor: (batch, seqlen_k, num_heads_kv, head_dim) or paged layout
v torch.Tensor (fp16/bf16) Yes Value tensor: same layout as k, head_dim_v may differ
cu_seqlens_q torch.Tensor (int32) No Cumulative query sequence lengths (batch_size+1,)
cu_seqlens_k torch.Tensor (int32) No Cumulative key sequence lengths (batch_size+1,)
page_table torch.Tensor (int32) No Page table for paged KV cache (batch_size, max_pages)
softmax_scale float No Attention scale factor, defaults to 1/sqrt(head_dim)
causal bool No Whether to apply causal attention mask
window_size Tuple[Optional[int], Optional[int]] No Sliding window (left, right) sizes
softcap float No Softcapping value (0.0 to disable)
num_splits int No Number of KV splits (0 for heuristic, 1 for no split)

Outputs

Name Type Description
out torch.Tensor Attention output, same shape and dtype as q (with head_dim_v)
lse torch.Tensor (float32) Log-sum-exp values (only if return_softmax_lse=True)

Usage Examples

from sgl_kernel._fa4_interface import flash_attn_varlen_func

# Variable-length attention with causal masking
out = flash_attn_varlen_func(
    q=query_tensor,       # (total_q, num_heads, head_dim)
    k=key_tensor,         # (total_k, num_heads_kv, head_dim)
    v=value_tensor,       # (total_k, num_heads_kv, head_dim_v)
    cu_seqlens_q=cu_q,    # (batch_size + 1,), int32
    cu_seqlens_k=cu_k,    # (batch_size + 1,), int32
    causal=True,
    softmax_scale=1.0 / math.sqrt(128),
)

# With paged KV cache and sliding window
out, lse = flash_attn_varlen_func(
    q=query_tensor,
    k=paged_key_cache,     # (num_pages, page_size, num_heads_kv, head_dim)
    v=paged_value_cache,
    cu_seqlens_q=cu_q,
    seqused_k=cache_seqlens,
    page_table=page_table,  # (batch_size, max_num_pages)
    window_size=(256, 0),   # left=256, right=0 (causal with window)
    return_softmax_lse=True,
)

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment