sgl-project/sglang · error · ValueError
expected beta shape {(1, T, H)}
Error message
expected beta shape {(1, T, H)} What it means
beta is the per-token per-head decay scalar and must be exactly [1, T, H] — one scalar per (token, head), batch flattened. Any other rank or shape (e.g. [T, H], [1, T, H, 1], or per-head broadcast) is rejected.
Source
Thrown at python/sglang/kernels/ops/kimi_k3/kda_decode_mtp.py:991
commit-time exact fold, see kda_replayssm_spec_decode.py) and the per-step
intermediate_ssm state snapshots are skipped, so intermediate_ssm may be
None.
Passing all three onorm_* arguments fuses gated RMSNorm into the recurrence
kernel.
"""
import torch
H = x_q.shape[2]
N = cu_seqlens.numel() - 1
T = x_q.shape[1]
expected_shape = (1, T, H, TILE_K)
if tuple(x_q.shape) != expected_shape or tuple(x_k.shape) != expected_shape:
raise ValueError(f"expected q/k shape {expected_shape}")
if tuple(x_v.shape) != expected_shape or tuple(g.shape) != expected_shape:
raise ValueError(f"expected v/g shape {expected_shape}")
if tuple(beta.shape) != (1, T, H):
raise ValueError(f"expected beta shape {(1, T, H)}")
# T // N == 1 is num_spec == 0: one token per request, i.e. a plain decode
# step. The backend never dispatches here for it (that is the dedicated
# decode kernel's job), but the layout is legal and benchmarks compare the
# two at this point, so the wrapper accepts it.
if N <= 0 or T % N != 0 or T // N < 1:
raise ValueError(
f"DSpARK KDA MTP requires a fixed 1 + num_spec dense tokens per "
f"request; got T={T}, N={N}"
)
num_spec = T // N - 1
if recurrent_state.shape[1:] != (H, TILE_K, TILE_K):
raise ValueError("expected recurrent state layout [pool, H, V=128, K=128]")
if (
recurrent_state.dtype != torch.float32
or tuple(recurrent_state.stride()[-3:]) != (TILE_K * TILE_K, TILE_K, 1)
or recurrent_state.stride(0) % 4 != 0
or recurrent_state.storage_offset() % 4 != 0
):View on GitHub (pinned to 0132848349)
Solutions
- Squeeze/reshape beta to [1, T, H] before the call
- Audit the beta projection: compute it as x @ beta_proj.reshape(H, D).sum(-1) style giving [T, H], then beta.unsqueeze(0)
- Add a debug assert on beta.ndim == 3 in test wrappers
Example fix
# before fused_kda_decode_mtp_dspark(q, k, v, g, beta) # beta is [1, T, H, 1] # after beta = beta.reshape(1, T, H) fused_kda_decode_mtp_dspark(q, k, v, g, beta)
Defensive patterns
Strategy: validation
Validate before calling
assert tuple(beta.shape) == (1, T, H), beta.shape beta = beta.reshape(1, T, H)
Type guard
def is_dspark_beta(b: torch.Tensor, T: int, H: int) -> bool:
return tuple(b.shape) == (1, T, H) Prevention
- Squeeze the beta projection output explicitly after matmul
- Keep a shape contract table for all DSpARK MTP inputs in one place
- Add torch.testing.assert_close-style wrappers that validate shapes first
When it happens
Trigger: Passing beta with an extra unit dim, missing batch dim, or a per-token scalar [1, T, 1] to fused_kda_decode_mtp_dspark.
Common situations: Projections that return beta as [T, H, 1] from a [*, H, D] matmul and forget to squeeze; broadcasting assumptions from another KDA kernel that accepted [T, H].
Related errors
- expected q/k shape {expected_shape}
- expected v/g shape {expected_shape}
- Unexpected A_log shape: {A_log.shape}; expected numel={HV}
- Unexpected dt_bias shape: {dt_bias.shape}; expected numel={H
- Unexpected a shape for varlen: {a.shape}
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/e2042778800c0663.
Report an issue: GitHub.