sgl-project/sglang · error · NotImplementedError

FA4 does not support updating KV cache in-place.

Error message

FA4 does not support updating KV cache in-place.

What it means

The sm120 FA4 kvcache path mirrors the FA4 contract: it does not support in-place KV cache updates, so passing k or v tensors raises NotImplementedError.

Source

Thrown at python/sglang/kernels/ops/attention/flash_attention_v4_sm120.py:242

    num_splits: int = 0,
    pack_gqa: Optional[bool] = None,
    sm_margin: int = 0,
    sinks: Optional[torch.Tensor] = None,
    score_mod: Optional[Callable] = None,
    aux_tensors: Optional[list] = None,
    sfq: Optional[torch.Tensor] = None,
    sfk: Optional[torch.Tensor] = None,
    sfv: Optional[torch.Tensor] = None,
    rel_bias: Optional[torch.Tensor] = None,
    rel_bias_prep_cache: Optional[dict] = None,
    return_softmax_lse: bool = False,
    out: Optional[torch.Tensor] = None,
    max_seqlen_k: Optional[int] = None,
    **_: object,
):
    _validate_out_contract(out)
    if k is not None or v is not None:
        raise NotImplementedError("FA4 does not support updating KV cache in-place.")
    if rotary_cos is not None or rotary_sin is not None or rotary_seqlens is not None:
        raise NotImplementedError("FA4 path does not support rotary embedding.")
    if cache_batch_idx is not None or cache_leftpad is not None:
        raise NotImplementedError(
            "FA4 path does not support non-consecutive batch indices or left padding."
        )
    if isinstance(cache_seqlens, int):
        cache_seqlens = torch.full(
            (k_cache.shape[0],), cache_seqlens, dtype=torch.int32, device=k_cache.device
        )

    forward_arch = get_forward_arch(q.device) if get_forward_arch is not None else None
    if (
        forward_arch is not None
        and not return_softmax_lse
        and softcap in (None, 0.0)
        and all(
            value is None

View on GitHub (pinned to 0132848349)

Solutions

  1. Pre-write k/v into the paged cache and call with k=None, v=None
  2. Rely on cache_seqlens for valid lengths
  3. Use FA2/FA3 backend when append semantics are needed

Example fix

# before
out = fa.flash_attn_with_kvcache(q, k, v, kc, vc, cache_seqlens=s)
# after
out = fa.flash_attn_with_kvcache(q, None, None, kc, vc, cache_seqlens=s)
Defensive patterns

Strategy: validation

Validate before calling

assert k is None and v is None, 'write k/v into cache before FA4 sm120 call'

Prevention

When it happens

Trigger: Calling flash_attn_with_kvcache(k=..., v=..., ...) in flash_attention_v4_sm120 while also giving k_cache/v_cache.

Common situations: Shared attention-backend code that always passes new k/v (FA2-style) regardless of backend.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/219a5070795c6e06. Report an issue: GitHub.