sgl-project/sglang · error · ValueError
n must be a positive power of 2, got {n}
Error message
n must be a positive power of 2, got {n} What it means
_walsh_hadamard_matrix builds a cached Walsh–Hadamard transform matrix used by the Ascend DSV4 indexer; the fast iterative construction only works for sizes that are positive powers of two, so any other n is rejected before construction.
Source
Thrown at python/sglang/srt/hardware_backend/npu/attention/ascend_dsv4_backend.py:40
from sglang.srt.runtime_context import get_parallel
if TYPE_CHECKING:
from sglang.srt.layers.radix_attention import RadixAttention
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
from sglang.srt.model_executor.model_runner import ModelRunner
logger = logging.getLogger(__name__)
def _walsh_hadamard_matrix(n: int, dtype: torch.dtype, device) -> torch.Tensor:
# n**-0.5 norm is baked in via the sqrt(2) division per doubling; _apply_hadamard is a plain matmul
cache = _walsh_hadamard_matrix._cache
key = (n, str(device))
cached = cache.get(key)
if cached is not None:
return cached
if not ((n & (n - 1) == 0) and (n > 0)):
raise ValueError(f"n must be a positive power of 2, got {n}")
had = torch.ones(1, 1, dtype=torch.bfloat16, device=device)
while had.shape[0] != n:
had = torch.cat((torch.cat([had, had], 1), torch.cat([had, -had], 1)), 0)
had /= math.sqrt(2)
had = had.contiguous()
cache[key] = had
return had
_walsh_hadamard_matrix._cache = {}
def _apply_hadamard(inp: torch.Tensor, hadamard_matrix: torch.Tensor) -> torch.Tensor:
init_shape = inp.shape
flat = inp.view(-1, hadamard_matrix.shape[0])
return flat.matmul(hadamard_matrix).view(init_shape).to(torch.bfloat16)
View on GitHub (pinned to 0132848349)
Solutions
- Ensure the derived size (head dim / compressor ratio) is a power of two, e.g. 64/128/256
- Check the model config for the DSV4 indexer (head dims, compressor settings) against supported values
- If you control the caller, validate and fail early with a clear config error before launching
- Use the standard DeepSeek v4 config, which produces power-of-2 sizes
Example fix
# before H = _walsh_hadamard_matrix(96) # ValueError # after H = _walsh_hadamard_matrix(128)
Defensive patterns
Strategy: validation
Validate before calling
def is_pow2(n: int) -> bool:
return isinstance(n, int) and n > 0 and (n & (n - 1)) == 0
assert is_pow2(n), f"n={n} is not a positive power of two" Type guard
def is_valid_hadamard_size(n) -> bool:
return isinstance(n, int) and n > 0 and (n & (n - 1)) == 0 Try / catch
try:
had = _walsh_hadamard_matrix(n)
except ValueError as e:
n2 = 1 << (n - 1).bit_length() # round up to next power of two
had = _walsh_hadamard_matrix(n2) Prevention
- Validate head dims / compressor ratios are powers of two before building the indexer
- Use stock DSV4 model configs
- Wrap indexer construction with a config linter at startup
When it happens
Trigger: Calling _walsh_hadamard_matrix(n) with n not a positive power of two — e.g. n=3, n=0, negative n, or a non-integer that slips through — typically from _ensure_compressor_hadamard/_ensure_npu_c4_indexer deriving n from a head dim or compressor ratio that isn't a power of two.
Common situations: Configuring the DSV4 NPU indexer with a custom head_dim/compressor ratio like 3/4 or 6 that yields non-power-of-2 sizes; model configs with unusual qk/down-proj dims; unit tests probing invalid shapes.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- {name} and its host copy must have the same length
- {name} must start with 0 and contain at least one sequence
- {name} must be non-decreasing
- NPU packed attention requires q, k, and v on the same NPU; i
- NPU packed attention requires q, k, and v with the same dtyp
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/0edb70db00b9db53.
Report an issue: GitHub.