google-research/timesfm · error · ValueError
Inputs must be of rank 3 or 4.
Error message
Inputs must be of rank 3 or 4.
What it means
The sinusoid broadcasting logic in the rotary embedding supports only rank-3 (b, n, d) and rank-4 (b, h, n, d) inputs, adjusting position/timescale axes accordingly. Any other rank falls through to this ValueError at forward time.
Source
Thrown at src/timesfm/flax/transformer.py:106
"The embedding dims of the rotary position embedding"
"must match the hidden dimension of the inputs."
)
half_embedding_dim = self.embedding_dims // 2
fraction = 2 * jnp.arange(0, half_embedding_dim) / self.embedding_dims
timescale = (
self.min_timescale * (self.max_timescale / self.min_timescale) ** fraction
)
if position is None:
seq_length = inputs.shape[1]
position = jnp.arange(seq_length, dtype=jnp.float32)[None, :]
if len(inputs.shape) == 4:
position = position[..., None, None]
timescale = timescale[None, None, None, :]
elif len(inputs.shape) == 3:
position = position[..., None]
timescale = timescale[None, None, :]
else:
raise ValueError("Inputs must be of rank 3 or 4.")
sinusoid_inp = position / timescale
sin = jnp.sin(sinusoid_inp)
cos = jnp.cos(sinusoid_inp)
first_half, second_half = jnp.split(inputs, 2, axis=-1)
first_part = first_half * cos - second_half * sin
second_part = second_half * cos + first_half * sin
first_part = first_part.astype(None)
second_part = second_part.astype(None)
return jnp.concatenate([first_part, second_part], axis=-1)
class PerDimScale(nnx.Module):
"""Per-dimension scaling."""
__data__ = ("per_dim_scale",)
def __init__(self, num_dims: int, *, rngs=nnx.Rngs(42)):
del rngsView on GitHub (pinned to 331c6d33cb)
Solutions
- Add a batch axis: reshape inputs from (n, d) to (1, n, d) before the call.
- Ensure the tensor is exactly rank 3 or 4 (batch, [heads,] positions, features) when entering the module.
- Check upstream code for unintended squeeze()/reshape() calls that drop or add axes.
Example fix
// before y = rotary(x) # x.shape == (n, d) -> ValueError // after x = x[None, :, :] # now rank 3: (1, n, d) y = rotary(x)
Defensive patterns
Strategy: validation
Validate before calling
if inputs.ndim not in (3, 4):
raise ValueError(f"expected rank 3 or 4 input, got rank {inputs.ndim}") Type guard
def is_rank_3_or_4(x) -> bool:
return x.ndim in (3, 4) Try / catch
try:
out = rotary(x)
except ValueError as e:
if "rank 3 or 4" in str(e):
while x.ndim < 3:
x = x[None]
out = rotary(x)
else:
raise Prevention
- Never drop the batch axis before positional-embedding layers; use x[None] instead of squeeze().
- Log/check tensor ranks at pipeline boundaries.
- Write a smoke test running a rank-3 dummy tensor through the model.
When it happens
Trigger: Calling the rotary position embedding __call__ with a 2D tensor (no batch), a 1D vector, or a 5D tensor, e.g. passing a single sequence of shape (n, d) without a batch axis.
Common situations: Debugging with a single example and forgetting the batch dimension, squeezing the batch axis before the rotary layer, or piping in a tensor from another module that adds/removes an axis.
Related errors
- The embedding dims of the rotary position embeddingmust matc
- Activation: {config.activation} not supported.
- Output dims must be a multiple of 4: {config.output_dims} %
- Incompatible input dimension, got {input_in_features} but mo
- Memory dimension ({self.qkv_features}) must be divisible by
AI-assisted analysis of google-research/timesfm@331c6d33cb (2026-08-29).
Data as JSON: /api/errors/58958ec9930a9526.
Report an issue: GitHub.