sgl-project/sglang · error · ValueError

out_channels must be divisible by tp_size for TP-sharded out

Error message

out_channels must be divisible by tp_size for TP-sharded output projection, got {arch.out_channels=} {tp_size=}.

What it means

LTX-2 DiT model validates at construction time that the architecture's out_channels is divisible by the tensor-parallel size, because the output projection layer is TP-sharded (column/row parallel split of the linear weight). If out_channels % tp_size != 0, sharding would silently produce mismatched per-rank slice sizes, so the model refuses to build.

Source

Thrown at python/sglang/multimodal_gen/runtime/models/dits/ltx_2.py:1632

                f"{self.num_attention_heads=} {tp_size=}."
            )
        if self.audio_num_attention_heads % tp_size != 0:
            raise ValueError(
                "audio_num_attention_heads must be divisible by tp_size, got "
                f"{self.audio_num_attention_heads=} {tp_size=}."
            )
        if self.hidden_size % tp_size != 0:
            raise ValueError(
                "hidden_size must be divisible by tp_size for TP-sharded projections, got "
                f"{self.hidden_size=} {tp_size=}."
            )
        if self.audio_hidden_size % tp_size != 0:
            raise ValueError(
                "audio_hidden_size must be divisible by tp_size for TP-sharded projections, got "
                f"{self.audio_hidden_size=} {tp_size=}."
            )
        if int(arch.out_channels) % tp_size != 0:
            raise ValueError(
                "out_channels must be divisible by tp_size for TP-sharded output projection, got "
                f"{arch.out_channels=} {tp_size=}."
            )
        if int(arch.audio_out_channels) % tp_size != 0:
            raise ValueError(
                "audio_out_channels must be divisible by tp_size for TP-sharded output projection, got "
                f"{arch.audio_out_channels=} {tp_size=}."
            )

    def __init__(
        self,
        config: LTX2Config,
        hf_config: dict[str, Any],
        quant_config: QuantizationConfig | None = None,
    ) -> None:
        super().__init__(config=config, hf_config=hf_config)

        arch = self.config

View on GitHub (pinned to 0132848349)

Solutions

  1. Pick a tp_size that divides arch.out_channels (powers of two and small factors of the channel count, e.g. 1, 2, 4, 8)
  2. Print/check arch.out_channels from the loaded config before launching and factorize it to find valid TP degrees
  3. If the divisibility can never be satisfied for your hardware, run with tp_size=1 or shard a different dimension (e.g. use DP instead of TP)

Example fix

# before: tp_size=6, out_channels=128 -> ValueError
model = Ltx2Model(arch, tp_size=6)

# after
assert arch.out_channels % tp_size == 0
model = Ltx2Model(arch, tp_size=4)
Defensive patterns

Strategy: validation

Validate before calling

import math
valid_tp = [t for t in range(1, 9) if int(arch.out_channels) % t == 0]
assert tp_size in valid_tp, f'tp_size must be one of {valid_tp}'

Prevention

When it happens

Trigger: Instantiating the LTX-2 model (or its runtime wrapper) with --tp / tp_size set to a value that does not divide arch.out_channels, e.g. out_channels=128 with tp_size=6, or loading a checkpoint config whose out_channels is an odd number while running multi-GPU TP.

Common situations: Choosing a large TP degree (e.g. 5, 6, 7) to fill available GPUs without checking channel divisibility; editing the model config's out_channels; using a nonstandard checkpoint variant with unusual channel counts.

Related errors


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