unslothai/unsloth · error · ValueError

ConvRot group size must be a power of 4, got {group_size!r}

Error message

ConvRot group size must be a power of 4, got {group_size!r}

What it means

The offline rotation entry point validates group_size up front: the Hadamard construction only exists for powers of four, so anything else is refused before any module is touched. This is the build-time twin of the check in build_convrot_hadamard().

Source

Thrown at studio/backend/core/inference/diffusion_convrot.py:309

            continue
        (rotatable if module.in_features % group_size == 0 else not_divisible).append(fqn)
    return tuple(rotatable), tuple(not_divisible)


def rotate_linears_(
    transformer: Any,
    fqns: Iterable[str],
    group_size: int = DEFAULT_CONVROT_GROUPSIZE,
) -> tuple[str, ...]:
    """OFFLINE half: rotate the weights of ``fqns`` and install the online rotation on each.

    Call BEFORE ``quantize_``, on a dense model: the whole point is that the quantizer sees the
    flatter distribution. Returns the fqns rotated, in the order given. Raises on anything it
    cannot rotate, so a builder can never record a set larger than the one it actually applied."""
    from torch import nn

    if not is_power_of_four(group_size):
        raise ValueError(f"ConvRot group size must be a power of 4, got {group_size!r}")
    modules = dict(transformer.named_modules())
    rotated: list[str] = []
    for fqn in fqns:
        module = modules.get(fqn)
        if not isinstance(module, nn.Linear):
            raise ValueError(f"cannot rotate {fqn!r}: not an nn.Linear on this model")
        rotate_convrot_weight_(module, group_size)
        _install_rotation(module, group_size)
        rotated.append(fqn)
    return tuple(rotated)


def apply_activation_rotation(
    transformer: Any,
    metadata: Any,
    *,
    logger: Any = None,
) -> tuple[str, ...]:

View on GitHub (pinned to 203007d190)

Solutions

  1. Set the group to 4, 16, or 64 in the builder config
  2. Validate the config at startup with is_power_of_four(group_size) so builders fail fast before downloading/loading a checkpoint
  3. Keep the group out of per-request paths; it is a build-time constant recorded into checkpoint metadata

Example fix

# before
apply_rotation(transformer, fqns, group_size=128)

# after
apply_rotation(transformer, fqns, group_size=64)
Defensive patterns

Strategy: validation

Validate before calling

from studio.backend.core.inference.diffusion_convrot import is_power_of_four

assert is_power_of_four(group_size), f"ConvRot group {group_size} must be 4, 16, or 64"

Try / catch

try:
    rotated = apply_rotation(transformer, fqns, group_size=group_size)
except ValueError as e:
    raise BuildConfigError(str(e)) from e  # stop the build; never silently rotate fewer layers

Prevention

When it happens

Trigger: Calling the offline rotate-weights function (apply_rotation) with a group_size that fails is_power_of_four — e.g. 128 (common in Hadamard/Quarot configs), 8, or 0; typically from a hand-edited builder config.

Common situations: Porting a SpinQuant/Quarot recipe that assumes powers of two; sharing a quantization config across models with a group size tuned for a different rotation scheme; typo in the builder's group parameter.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/ba6c21b339d9e609. Report an issue: GitHub.