google-research/timesfm · error · ValueError

Output dims must be a multiple of 4: {config.output_dims} %

Error message

Output dims must be a multiple of 4: {config.output_dims} % 4 != 0.

What it means

RandomFourierFeatures projection splits output_dims into 4 components, so output_dims must be divisible by 4; num_projected_features is computed as output_dims // 4. The constructor validates this upfront and raises ValueError otherwise.

Source

Thrown at src/timesfm/flax/dense.py:81

    else:
      raise ValueError(f"Activation: {config.activation} not supported.")

  def __call__(self, x: Float[Array, "b ... i"]) -> Float[Array, "b ... o"]:
    return self.output_layer(
      self.activation(self.hidden_layer(x))
    ) + self.residual_layer(x)


class RandomFourierFeatures(nnx.Module):
  """Random Fourier features layer."""

  __data__ = ("phrase_shifts",)

  def __init__(self, config: RandomFourierFeaturesConfig, *, rngs=nnx.Rngs(42)):
    self.config = config

    if config.output_dims % 4 != 0:
      raise ValueError(
        f"Output dims must be a multiple of 4: {config.output_dims} % 4 != 0."
      )
    num_projected_features = config.output_dims // 4

    self.phase_shifts = nnx.Param(jnp.zeros(shape=(2, num_projected_features)))
    self.projection_layer = nnx.Linear(
      in_features=config.input_dims,
      out_features=num_projected_features,
      use_bias=config.use_bias,
      rngs=rngs,
    )
    self.residual_layer = nnx.Linear(
      in_features=config.input_dims,
      out_features=config.output_dims,
      use_bias=config.use_bias,
      rngs=rngs,
    )

View on GitHub (pinned to 331c6d33cb)

Solutions

  1. Set config.output_dims to the nearest multiple of 4 that fits your needs (e.g. 100 -> 100 is invalid, use 100 -> 96 or 104).
  2. Derive output_dims programmatically: output_dims = desired_features * 4.
  3. If the value comes from a checkpoint/model card, use the exact documented dims.

Example fix

// before
config = RandomFourierFeaturesConfig(output_dims=100)  # ValueError
// after
config = RandomFourierFeaturesConfig(output_dims=104)  # 104 % 4 == 0
Defensive patterns

Strategy: validation

Validate before calling

if config.output_dims % 4 != 0:
    raise ValueError(f"output_dims must be a multiple of 4, got {config.output_dims}")

Try / catch

try:
    rff = RandomFourierFeatures(config)
except ValueError as e:
    if "% 4" in str(e):
        config.output_dims = ((config.output_dims // 4) + 1) * 4
        rff = RandomFourierFeatures(config)
    else:
        raise

Prevention

When it happens

Trigger: Creating a RandomFourierFeaturesConfig with output_dims such as 6, 10, 25, 100 (any non-multiple of 4) and passing it to the module's __init__.

Common situations: Choosing an arbitrary embedding size for random Fourier features (e.g. 100), copying dims from another model's hidden size, or incrementing dims by small amounts without checking divisibility.

Related errors


AI-assisted analysis of google-research/timesfm@331c6d33cb (2026-08-29). Data as JSON: /api/errors/ef7b05603b17faed. Report an issue: GitHub.