huggingface/pytorch-image-models · error · ValueError

Coefficient must be length-3 of real numbers, got: {x!r}

Error message

Coefficient must be length-3 of real numbers, got: {x!r}

What it means

Newton–Schulz coefficients passed to Muon must be sequences of exactly three real numbers (the a, b, c per iteration). This validation runs when parsing user-supplied coefficient tuples (or preset contents) via as_coeff.

Source

Thrown at timm/optim/muon.py:1025

                    for shape in shapes[:10]:
                        _logger.info(f"      {shape}")
                    if len(shapes) > 10:
                        _logger.info(f"      ... and {len(shapes) - 10} more")

        return loss


def resolve_ns_coefficients(
        value: Union[str, Sequence[float], Sequence[Sequence[float]]],
        presets: Mapping[str, Sequence[Sequence[float]]]
) -> List[Tuple[float, float, float]]:
    # tiny helpers (kept inline for succinctness)
    is_seq = lambda x: isinstance(x, Sequence) and not isinstance(x, (str, bytes))
    is_real = lambda x: isinstance(x, numbers.Real) and not isinstance(x, bool)

    def as_coeff(x: Sequence[float]) -> Tuple[float, float, float]:
        if not is_seq(x) or len(x) != 3 or not all(is_real(v) for v in x):
            raise ValueError(f"Coefficient must be length-3 of real numbers, got: {x!r}")
        a, b, c = x  # type: ignore[misc]
        return float(a), float(b), float(c)

    if isinstance(value, str):
        if value not in presets:
            valid = ", ".join(sorted(presets.keys()))
            raise ValueError(f"Unknown coefficients preset '{value}'. Valid options: {valid}")
        seq = presets[value]
        if not is_seq(seq) or len(seq) == 0:
            raise ValueError(f"Preset '{value}' is empty or invalid")
        return [as_coeff(item) for item in seq]  # validate & cast

    if not is_seq(value):
        raise TypeError(
            "Coefficients must be a preset name (str), a 3-sequence (a,b,c), "
            "or a sequence of 3-sequences."
        )

View on GitHub (pinned to 9a5261e31b)

Solutions

  1. Supply exactly three floats per Newton–Schulz step, e.g. (3.4445, -4.7750, 2.0315)
  2. Use a named preset string instead of hand-written triples
  3. Validate config values before constructing the optimizer

Example fix

# before
Muon(params, ns_coefficients=[(3.4445, -4.7750)])
# after
Muon(params, ns_coefficients=[(3.4445, -4.7750, 2.0315)])
Defensive patterns

Strategy: type-guard

Validate before calling

import numbers
def coeff_ok(t):
    return (isinstance(t, (list, tuple)) and len(t) == 3
            and all(isinstance(v, numbers.Real) and not isinstance(v, bool) for v in t))
assert all(coeff_ok(t) for t in cfg.ns_coefficients)

Type guard

def is_coeff_triple(t) -> bool:
    import numbers
    return (isinstance(t, (list, tuple)) and len(t) == 3
            and all(isinstance(v, numbers.Real) and not isinstance(v, bool) for v in t))

Prevention

When it happens

Trigger: Passing ns_coefficients (or a preset entry) like (3.4445,), (1,2,3,4), (1.0,'a',-1.0), or a bool-containing tuple (bools are explicitly rejected as non-real).

Common situations: Copying coefficient triples from papers/code with a missing element; passing nested lists of wrong arity; passing Python booleans from a config system that coerces numbers.

Related errors


AI-assisted analysis of huggingface/pytorch-image-models@9a5261e31b (2026-08-27). Data as JSON: /api/errors/a03096479a333ce8. Report an issue: GitHub.