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
The functional timm.optim.adamw.adamw() API requires state_steps to be a list of singleton torch tensors (one per parameter), matching PyTorch's modern functional optimizer API. Passing floats or ints (the pre-1.5 API) triggers this guard.
Source
Thrown at timm/optim/adamw.py:205
foreach: Optional[bool] = None,
capturable: bool = False,
*,
amsgrad: bool,
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 AdamW algorithm computation.
See AdamWLegacy 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_adamw
else:
func = _single_tensor_adamw
View on GitHub (pinned to 9a5261e31b)
Solutions
- Convert each step count to a tensor: state_steps = [torch.tensor(float(step)) for step in state_steps]
- Or let the AdamW class manage state and call step() instead of the functional API
- If migrating from torch.optim.adamw, reuse the same tensor-based state_steps convention
Example fix
# before adamw(params, grads, exp_avgs, exp_avg_sqs, max_exp_avg_sqs, state_steps=[0], lr=1e-3) # after adamw(params, grads, exp_avgs, exp_avg_sqs, max_exp_avg_sqs, state_steps=[torch.tensor(0.)], lr=1e-3)
Defensive patterns
Strategy: validation
Validate before calling
assert all(isinstance(t, torch.Tensor) and t.numel() == 1 for t in state_steps)
Type guard
def valid_state_steps(state_steps: list) -> bool:
return all(isinstance(t, torch.Tensor) and t.numel() == 1 for t in state_steps) Prevention
- Prefer the class API (AdamW.step()) over the functional API
- Initialize state_steps as torch.zeros(1) tensors from the start
- Convert legacy int counters once at migration time
When it happens
Trigger: Calling timm.optim.adamw.adamw(..., state_steps=[0, 1, 2]) with Python numbers instead of state_steps=[torch.tensor(0.), ...]. It is also raised if any element of the list is not a torch.Tensor.
Common situations: Copying old tutorial code that used the pre-2020 functional Adam API, or hand-rolling a training loop that tracks step counts as ints and forwards them to the functional API.
Related errors
- Invalid beta parameter at index 0: {}
- Invalid beta parameter at index 1: {}
- AdamW does not support sparse gradients
- {name} must be a scalar or scalar tensor.
- Invalid {name}: {value}
AI-assisted analysis of huggingface/pytorch-image-models@9a5261e31b (2026-08-27).
Data as JSON: /api/errors/be67de4130c1ed0b.
Report an issue: GitHub.