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 requires output_dims to be divisible by 4 because the layer computes num_projected_features = output_dims // 4 (phase_shifts has shape (2, output_dims//4)). A non-multiple of 4 raises ValueError in __init__.
Source
Thrown at src/timesfm/torch/dense.py:67
self.activation = nn.Identity()
else:
raise ValueError(f"Activation: {config.activation} not supported.")
def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.output_layer(
self.activation(self.hidden_layer(x))
) + self.residual_layer(x)
class RandomFourierFeatures(nn.Module):
"""Random Fourier features layer."""
def __init__(self, config: configs.RandomFourierFeaturesConfig):
super().__init__()
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 = nn.Parameter(torch.zeros(2, num_projected_features))
self.projection_layer = nn.Linear(
in_features=config.input_dims,
out_features=num_projected_features,
bias=config.use_bias,
)
self.residual_layer = nn.Linear(
in_features=config.input_dims,
out_features=config.output_dims,
bias=config.use_bias,
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
projected = self.projection_layer(x)View on GitHub (pinned to 331c6d33cb)
Solutions
- Round output_dims to the nearest multiple of 4 before constructing the config (e.g. 1022 -> 1024).
- Use shipped reference values (multiples of 4 such as 1280/1024) as templates.
- Add a config-time check: assert output_dims % 4 == 0.
- If a non-multiple size is truly needed, modify the layer to pad num_projected_features, noting this changes the weights format.
Example fix
// before config = RandomFourierFeaturesConfig(output_dims=1002) # ValueError // after config = RandomFourierFeaturesConfig(output_dims=1004) # divisible by 4
Defensive patterns
Strategy: validation
Validate before calling
if cfg.output_dims % 4 != 0:
cfg = dataclasses.replace(cfg, output_dims=math.ceil(cfg.output_dims / 4) * 4) Try / catch
try:
rff = RandomFourierFeatures(cfg)
except ValueError as e:
if "multiple of 4" in str(e):
cfg = dataclasses.replace(cfg, output_dims=(cfg.output_dims // 4 + 1) * 4)
rff = RandomFourierFeatures(cfg)
else:
raise Prevention
- Round output_dims up to the nearest multiple of 4 in config factories.
- Use reference dims (1280, 1024) that satisfy the constraint.
- Add an assert output_dims % 4 == 0 wherever configs are built.
- Note the // 4 coupling with phase_shifts shape when resizing.
When it happens
Trigger: Constructing RandomFourierFeatures(RandomFourierFeaturesConfig(output_dims=N)) where N % 4 != 0 — e.g. output_dims=100 or 1023.
Common situations: Tuning the RFF dimension for a custom head with an arbitrary size; scaling dims from another model without this constraint; accidentally setting output_dims to an input feature count.
Related errors
- Activation: {config.activation} not supported.
- Memory dimension ({self.in_features}) must be divisible by '
- Context + horizon must be less than the context limit. {fc.m
- Continuous quantile head is not supported for horizons > {se
- Horizon must be less than the max horizon. {horizon} > {fc.m
AI-assisted analysis of google-research/timesfm@331c6d33cb (2026-08-29).
Data as JSON: /api/errors/d149be2534648fac.
Report an issue: GitHub.