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

  1. Ensure the derived size (head dim / compressor ratio) is a power of two, e.g. 64/128/256
  2. Check the model config for the DSV4 indexer (head dims, compressor settings) against supported values
  3. If you control the caller, validate and fail early with a clear config error before launching
  4. 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

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


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