huggingface/transformers · error · TypeError

`skip` must be an iterable of strings.

Error message

`skip` must be an iterable of strings.

What it means

_normalize_layer_overrides validates the per-layer 'skip' entry used by heterogeneity (layer-wise heterogeneous) configs. A bare string is rejected (it would be interpreted as an iterable of characters) and non-iterables are rejected too: skip must be an iterable (list/set/tuple) whose elements are strings naming things to skip. Violations raise TypeError immediately at config normalization time.

Source

Thrown at src/transformers/integrations/heterogeneity/configuration_utils.py:52

class AmbiguousGlobalPerLayerAttributeError(RuntimeError):
    """Raised when a per-layer attribute is read from a heterogeneous global config."""


@dataclass
class _HeterogeneitySpec:
    per_layer_overrides: dict[int, dict[str, Any]]
    per_layer_attributes: set[str]
    explicit_per_layer_attributes: set[str]


def _normalize_layer_overrides(layer_overrides: dict[str, Any]) -> dict[str, Any]:
    normalized = copy.deepcopy(layer_overrides)

    if "skip" in normalized:
        skip = normalized.pop("skip")
        if isinstance(skip, str) or not isinstance(skip, Iterable):
            raise TypeError("`skip` must be an iterable of strings.")

        skip = set(skip)
        if not all(isinstance(item, str) for item in skip):
            raise TypeError("`skip` must contain only strings.")

        if skip:
            normalized["skip"] = sorted(skip)

    return normalized


def _validate_layer_indices(config: PreTrainedConfig, per_layer_overrides: dict[int, dict[str, Any]]) -> None:
    if not per_layer_overrides:
        return

    num_hidden_layers = config.num_hidden_layers
    invalid_layer_indices = [
        layer_idx for layer_idx in per_layer_overrides if layer_idx < 0 or layer_idx >= num_hidden_layers

View on GitHub (pinned to a597f97485)

Solutions

  1. Wrap the value in a list: "skip": ["mlp"] instead of "skip": "mlp"
  2. Ensure every element is a string naming a component to skip

Example fix

# before
config.per_layer_config = {0: {"skip": "mlp"}}

# after
config.per_layer_config = {0: {"skip": ["mlp"]}}
Defensive patterns

Strategy: type-guard

Validate before calling

def normalize_skip(overrides):
    for layer, ov in overrides.items():
        if "skip" in ov:
            s = ov["skip"]
            assert not isinstance(s, str) and isinstance(s, Iterable), "skip must be a list of strings"
            ov["skip"] = [str(x) for x in s]
    return overrides

Type guard

from typing import Iterable

def is_valid_skip(v) -> bool:
    return (
        not isinstance(v, str)
        and isinstance(v, Iterable)
        and all(isinstance(item, str) for item in v)
    )

Prevention

When it happens

Trigger: Setting per_layer_config = {i: {"skip": "mlp"}} or {"skip": 3} in a model config with heterogeneity enabled — the string/int form hits the isinstance guard and raises TypeError.

Common situations: Users writing a single layer name instead of a list; JSON configs where skip was simplified to a string during hand-editing; assuming skip counts layers rather than names modules.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/37f5736a649cb051. Report an issue: GitHub.