huggingface/pytorch-image-models · error · RuntimeError

API has changed, `state_steps` argument must contain a list

Error message

API has changed, `state_steps` argument must contain a list of singleton tensors

What it means

RuntimeError from the functional nadamw() API: every element of state_steps must be a torch.Tensor (singleton step counters). This mirrors an upstream PyTorch optimizer-API change from plain ints to tensors for capturable/foreach support.

Source

Thrown at timm/optim/nadamw.py:186

        state_steps: List[Tensor],
        foreach: Optional[bool] = None,
        capturable: bool = False,
        *,
        beta1: float,
        beta2: float,
        lr: float,
        weight_decay: float,
        eps: float,
        caution: bool,
        maximize: bool,
        max_lr: Optional[float],
) -> None:
    r"""Functional API that performs NAdamW algorithm computation.
      See NAdamW class for details.
    """

    if not all(isinstance(t, torch.Tensor) for t in state_steps):
        raise RuntimeError(
            'API has changed, `state_steps` argument must contain a list of' +
            ' singleton tensors')

    if foreach is None:
        try:
            # cannot do foreach if this overload doesn't exist when caution enabled
            foreach = not caution or 'Scalar' in torch.ops.aten._foreach_maximum_.overloads()
            # Match native PyTorch: tensor lr without capturable mode is supported by the single-tensor path.
            if foreach and torch.is_tensor(lr) and not capturable:
                foreach = False
        except Exception:
            foreach = False

    if foreach and not torch.jit.is_scripting():
        func = _multi_tensor_nadamw
    else:
        func = _single_tensor_nadamw

View on GitHub (pinned to 9a5261e31b)

Solutions

  1. Convert steps to tensors: state_steps=[torch.tensor(0.0) for _ in params] and increment in-place via step += 1
  2. Prefer using the NAdamW class .step() rather than the functional API unless you need custom control
  3. Check timm version changelog if migrating old functional-API code

Example fix

# before
functional_nadamw(params, grads, exp_avgs, exp_avg_sqs, [0, 0], ...)

# after
functional_nadamw(params, grads, exp_avgs, exp_avg_sqs, [torch.zeros(()) for _ in params], ...)
Defensive patterns

Strategy: type-guard

Validate before calling

import torch
assert all(isinstance(s, torch.Tensor) for s in state_steps)

Type guard

def steps_are_tensors(steps) -> bool:
    import torch
    return all(isinstance(s, torch.Tensor) for s in steps)

Prevention

When it happens

Trigger: Calling timm.optim.nadamw.functional_nadamw(...) (or NadamW class internals) with state_steps as a list of Python ints instead of tensors.

Common situations: Custom training loops calling the functional API directly with hand-built state, or old code written against the pre-tensor state_steps API after upgrading timm/PyTorch.

Related errors


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