sgl-project/sglang · error · ValueError
{name} must have shape {tuple(shape)}, got {tuple(t.shape)}
Error message
{name} must have shape {tuple(shape)}, got {tuple(t.shape)} What it means
sparse_mla_q8kv8_prefill_fwd validates caller-provided output buffers through _check_out_buffer; each buffer must exactly match the expected shape for the kernel launch. A mismatch raises ValueError naming the buffer, expected shape, and actual shape.
Source
Thrown at python/sglang/kernels/ops/attention/sparse_mla_q8kv8_prefill_sm90.py:114
# ---------------------------------------------------------------------------
# torch._C._cuda_getCurrentRawStream returns the cudaStream_t pointer expected
# by the JIT wrapper. torch._C._cuda_getCurrentStream returns a packed stream
# id and must not be used here.
_get_current_stream_raw = torch._C._cuda_getCurrentRawStream
# Module-level cache for kernel-write-only output tensors. The active s_q rows
# are overwritten every call; buffers grow monotonically by device/head shape.
def _check_out_buffer(
t: torch.Tensor,
name: str,
shape: tuple,
dtype: torch.dtype,
device: torch.device,
) -> None:
if tuple(t.shape) != tuple(shape):
raise ValueError(f"{name} must have shape {tuple(shape)}, got {tuple(t.shape)}")
if t.dtype != dtype:
raise ValueError(f"{name} must have dtype {dtype}, got {t.dtype}")
if t.device != device:
raise ValueError(f"{name} must be on device {device}, got {t.device}")
if not t.is_contiguous():
raise ValueError(f"{name} must be contiguous")
# Internal custom-op wrappers so the JIT kernel calls participate in
# torch.library / torch.compile tracing and kernel-API debug logging.
# The dispatch_full variant carries the optional attn_sink / topk_length
# tensors as required args; the public API chooses which op to call.
@register_custom_op(
op_name="sparse_mla_q8kv8_prefill",
mutates_args=["out", "max_logits", "lse"],
)
def _sparse_mla_q8kv8_prefill_op(
q: torch.Tensor,View on GitHub (pinned to 0132848349)
Solutions
- Allocate output buffers from the current inputs' shapes at call time (or use the API variant that allocates outputs)
- Key any output-buffer cache on (s_q, h_q, topk, dtype) exactly
- Re-check the documented shapes in the docstring (e.g. out [s_q,h_q,d_v], max_logits/lse [s_q,h_q])
Example fix
# before out = torch.empty(prev_s_q, h_q, d_v, ...) # stale s_q sparse_mla_q8kv8_prefill_fwd(q, kv, indices, out=out, ...) # after out = torch.empty(q.shape[0], q.shape[1], d_v, dtype=torch.bfloat16, device=q.device) sparse_mla_q8kv8_prefill_fwd(q, kv, indices, out=out, ...)
Defensive patterns
Strategy: validation
Validate before calling
expected = (s_q, h_q, d_v) assert tuple(out.shape) == expected, (out.shape, expected) sparse_mla_q8kv8_prefill_fwd(q, kv, idx, out=out, ...)
Prevention
- Allocate outputs per call from current input shapes
- Key output-buffer caches on the full shape tuple
When it happens
Trigger: Calling sparse_mla_q8kv8_prefill_fwd with an out= buffer (e.g. out/max_logits/lse) allocated with wrong dimensions — typically a stale shape from a different batch size, num heads, or sequence length.
Common situations: Reusing preallocated output buffers across requests with changing s_q or h_q; buffer caches keyed incompletely (missing a dim); after changing topk or head config without reallocating outputs.
Related errors
- {name} must have dtype {dtype}, got {t.dtype}
- D={D_check} must be divisible by GROUP_SIZE={_FP8_GROUP_SIZE
- kv_scales shape {tuple(kv_scales.shape)} does not match expe
- `out` must have shape {(B, 1, HV, V)} (got out.shape={tuple(
- `out` must have shape {(B, 1, HV, V)} (got out.shape={tuple(
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/cac2235813b9dce0.
Report an issue: GitHub.