sgl-project/sglang · error · ValueError
attn_sink must be a CUDA tensor
Error message
attn_sink must be a CUDA tensor
What it means
The optional attn_sink argument to sparse_mla_q8kv8_prefill_fwd must live on CUDA memory. The kernel dereferences the sink pointer on the GPU, so a CPU tensor would cause illegal memory access; the Python validation rejects it up front.
Source
Thrown at python/sglang/kernels/ops/attention/sparse_mla_q8kv8_prefill_sm90.py:413
"topk_length values must satisfy " f"0 <= topk_length <= topk ({topk})"
)
if d_v != 512:
raise ValueError(
f"sparse_mla_q8kv8_prefill_fwd only supports d_v=512, got {d_v}"
)
if attn_sink is not None and topk_length is None:
raise ValueError("attn_sink requires topk_length to be provided as well")
if attn_sink is not None:
if attn_sink.shape != (h_q,) or attn_sink.dtype != torch.float32:
raise ValueError(
f"attn_sink must be float32 with shape ({h_q},), got "
f"{tuple(attn_sink.shape)}/{attn_sink.dtype}"
)
if not attn_sink.is_cuda:
raise ValueError("attn_sink must be a CUDA tensor")
if attn_sink.device != device:
raise ValueError(
f"attn_sink must be on q's device {device}, got {attn_sink.device}"
)
if not attn_sink.is_contiguous():
raise ValueError("attn_sink must be contiguous")
for name, scale in (("q_scale", q_scale), ("kv_scale", kv_scale)):
if not isinstance(scale, torch.Tensor):
raise ValueError(f"{name} must be a torch.Tensor")
if not scale.is_cuda:
raise ValueError(f"{name} must be a CUDA tensor")
if scale.device != device:
raise ValueError(
f"{name} must be on q's device {device}, got {scale.device}"
)
if scale.dtype != torch.float32:
raise ValueError(f"{name} must be float32, got {scale.dtype}")View on GitHub (pinned to 0132848349)
Solutions
- Move the sink to the compute device: attn_sink = attn_sink.to(q.device, non_blocking=True)
- Allocate the sink directly on q.device when constructing it
Example fix
// before attn_sink = torch.zeros(h_q, dtype=torch.float32) # CPU // after attn_sink = torch.zeros(h_q, dtype=torch.float32, device=q.device)
Defensive patterns
Strategy: validation
Validate before calling
assert attn_sink.is_cuda, 'attn_sink must be on CUDA'
Type guard
def sink_on_cuda(t: torch.Tensor) -> bool:
return t.is_cuda Prevention
- Always allocate per-layer metadata tensors with device=q.device
- After loading checkpoints, move small buffers to the model device in one pass
When it happens
Trigger: Calling sparse_mla_q8kv8_prefill_fwd(..., attn_sink=cpu_tensor) where cpu_tensor.is_cuda is False, e.g. a tensor created without a device= argument or loaded from checkpoint on CPU.
Common situations: Loading sink values from a safetensors checkpoint (which defaults to CPU) and passing them straight to the kernel without a .to(q.device) transfer.
Related errors
- attn_sink must be float32 with shape ({h_q},), got {tuple(at
- attn_sink must be contiguous
- sparse_mla_q8kv8_prefill_fwd requires h_kv=1, got {h_kv}
- attn_sink must be on q's device {device}, got {attn_sink.dev
- {name} must be a torch.Tensor
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/50c38797f41c65ae.
Report an issue: GitHub.