sgl-project/sglang · error · ValueError
dim {dim} must be divisible by head_dim {head_dim}.
Error message
dim {dim} must be divisible by head_dim {head_dim}. What it means
The decoder's neighborhood-attention block splits `dim` into `heads = dim // head_dim` attention heads; if dim is not an exact multiple of head_dim the reshape is impossible, so __init__ validates it up front.
Source
Thrown at python/sglang/multimodal_gen/runtime/models/decoders/ltx_2_5_diffusion_decoder.py:374
"platform; falling back to eager"
),
)
return self._apply_rope(query, tables), self._apply_rope(key, tables)
class LTX2VideoVaeNeighborhoodAttention(nn.Module):
"""3D neighborhood attention over a channels-last `(B, T, H, W, C)` volume."""
def __init__(
self,
dim: int,
kernel_size: tuple[int, int, int],
head_dim: int = 64,
rope_base: float = 10000.0,
) -> None:
super().__init__()
if dim % head_dim != 0:
raise ValueError(f"dim {dim} must be divisible by head_dim {head_dim}.")
self.heads = dim // head_dim
self.head_dim = head_dim
self.kernel_size = tuple(kernel_size)
self.scale = head_dim**-0.5
self.to_q = nn.Linear(dim, dim, bias=True)
self.to_k = nn.Linear(dim, dim, bias=True)
self.to_v = nn.Linear(dim, dim, bias=True)
self.to_out = nn.ModuleList([nn.Linear(dim, dim, bias=True), nn.Dropout(0.0)])
self.norm_q = nn.RMSNorm(head_dim, eps=1e-6)
self.norm_k = nn.RMSNorm(head_dim, eps=1e-6)
self.rope = LTX2VideoVaeRotaryPosEmbed3D(head_dim, base=rope_base)
def project_qkv(
self, hidden_states: torch.Tensor
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
"""Q/K/V as `(B, T, H, W, heads, head_dim)`: normed, query pre-scaled, rotated.
View on GitHub (pinned to 0132848349)
Solutions
- Align stage channel dims to be multiples of head_dim (e.g. multiples of 64)
- Or pass head_dim that divides dim exactly (e.g. head_dim=50 for dim=1000)
- Re-check the full decoder_stage_channels list against the shipped arch defaults
Example fix
# before block = NeighborhoodAttentionBlock(dim=1000, kernel_size=(3,3,3), head_dim=64) # after block = NeighborhoodAttentionBlock(dim=1024, kernel_size=(3,3,3), head_dim=64)
Defensive patterns
Strategy: validation
Validate before calling
if dim % head_dim != 0:
raise ValueError(f"dim {dim} not divisible by head_dim {head_dim}") Type guard
def dims_aligned(dim: int, head_dim: int) -> bool:
return head_dim > 0 and dim % head_dim == 0 Try / catch
try:
block = NeighborhoodAttentionBlock(dim=dim, kernel_size=k, head_dim=head_dim)
except ValueError:
head_dim = next(h for h in (64, 32, 16, 8) if dim % h == 0)
block = NeighborhoodAttentionBlock(dim=dim, kernel_size=k, head_dim=head_dim) Prevention
- Use power-of-two channel widths that are multiples of your head_dim
- Derive head_dim from dim programmatically in config builders
When it happens
Trigger: Constructing the attention block with dim not divisible by head_dim — e.g. dim=1000 with head_dim=64, or a stage_channels value from arch config that doesn't align with the default head_dim=64.
Common situations: Customizing decoder stage widths without adjusting head_dim; mixing config values from a different model revision where dims changed; typos in width lists.
Related errors
- Invalid spatial patching for packed token latents. Expected
- head_dim must be a multiple of 8, got {head_dim}.
- Neighborhood attention requires each dim to be at least its
- decoder_model_output_type must be 'x0' or 'v', got {arch.dec
- decoder_stage_channels[{stage_idx + 1}] must be {expected},
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/056e011ce79fe23f.
Report an issue: GitHub.