Files
timesfm/timesfm-forecasting/references/api_reference.md
T
borealBytes 5aad77bd61 docs: address PR #369 review comments and add dataset preflight
- Add context limit rationale to system_requirements.md with memory formula
- Update SKILL.md to include XReg/covariates in description and usage sections
- Add dataset-aware memory estimation to check_system.py with new CLI args
- Document memory estimation in api_reference.md with Mermaid diagram
- Add dataset preflight section to SKILL.md with examples

Resolves review comments about:
- How context limits (512/1024) were determined
- Including XReg mode description in skill documentation

Bonus enhancement: Dataset preflight checking prevents OOM before loading data.
2026-02-25 21:27:31 -05:00

296 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TimesFM API Reference
## Model Classes
### `timesfm.TimesFM_2p5_200M_torch`
The primary model class for TimesFM 2.5 (200M parameters, PyTorch backend).
#### `from_pretrained()`
```python
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch",
cache_dir=None, # Optional: custom cache directory
force_download=True, # Re-download even if cached
)
```
| Parameter | Type | Default | Description |
| --------- | ---- | ------- | ----------- |
| `model_id` | str | `"google/timesfm-2.5-200m-pytorch"` | Hugging Face model ID |
| `revision` | str \| None | None | Specific model revision |
| `cache_dir` | str \| Path \| None | None | Custom cache directory |
| `force_download` | bool | True | Force re-download of weights |
**Returns**: Initialized `TimesFM_2p5_200M_torch` instance (not yet compiled).
#### `compile()`
Compiles the model with the given forecast configuration. **Must be called before `forecast()`.**
```python
model.compile(
timesfm.ForecastConfig(
max_context=1024,
max_horizon=256,
normalize_inputs=True,
per_core_batch_size=32,
use_continuous_quantile_head=True,
force_flip_invariance=True,
infer_is_positive=True,
fix_quantile_crossing=True,
)
)
```
**Raises**: Nothing (but `forecast()` will raise `RuntimeError` if not compiled).
#### `forecast()`
Run inference on one or more time series.
```python
point_forecast, quantile_forecast = model.forecast(
horizon=24,
inputs=[array1, array2, ...],
)
```
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `horizon` | int | Number of future steps to forecast |
| `inputs` | list[np.ndarray] | List of 1-D numpy arrays (each is a time series) |
**Returns**: `tuple[np.ndarray, np.ndarray]`
- `point_forecast`: shape `(batch_size, horizon)` — median (0.5 quantile)
- `quantile_forecast`: shape `(batch_size, horizon, 10)` — [mean, q10, q20, ..., q90]
**Raises**: `RuntimeError` if model is not compiled.
**Key behaviors**:
- Leading NaN values are stripped automatically
- Internal NaN values are linearly interpolated
- Series longer than `max_context` are truncated (last `max_context` points used)
- Series shorter than `max_context` are padded
#### `forecast_with_covariates()`
Run inference with exogenous variables (requires `timesfm[xreg]`).
```python
point, quantiles = model.forecast_with_covariates(
inputs=inputs,
dynamic_numerical_covariates={"temp": [temp_array1, temp_array2]},
dynamic_categorical_covariates={"dow": [dow_array1, dow_array2]},
static_categorical_covariates={"region": ["east", "west"]},
xreg_mode="xreg + timesfm",
)
```
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `inputs` | list[np.ndarray] | Target time series |
| `dynamic_numerical_covariates` | dict[str, list[np.ndarray]] | Time-varying numeric features |
| `dynamic_categorical_covariates` | dict[str, list[np.ndarray]] | Time-varying categorical features |
| `static_categorical_covariates` | dict[str, list[str]] | Fixed categorical features per series |
| `xreg_mode` | str | `"xreg + timesfm"` or `"timesfm + xreg"` |
**Note**: Dynamic covariates must have length `context + horizon` for each series.
---
## `timesfm.ForecastConfig`
Immutable dataclass controlling all forecast behavior.
```python
@dataclasses.dataclass(frozen=True)
class ForecastConfig:
max_context: int = 0
max_horizon: int = 0
normalize_inputs: bool = False
per_core_batch_size: int = 1
use_continuous_quantile_head: bool = False
force_flip_invariance: bool = True
infer_is_positive: bool = True
fix_quantile_crossing: bool = False
return_backcast: bool = False
quantiles: list[float] = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
decode_index: int = 5
```
### Parameter Details
#### `max_context` (int, default=0)
Maximum number of historical time points to use as context.
- **0**: Use the model's maximum supported context (16,384 for v2.5)
- **N**: Truncate series to last N points
- **Best practice**: Set to the length of your longest series, or 5122048 for speed
#### `max_horizon` (int, default=0)
Maximum forecast horizon.
- **0**: Use the model's maximum
- **N**: Forecasts up to N steps (can still call `forecast(horizon=M)` where M ≤ N)
- **Best practice**: Set to your expected maximum forecast length
#### `normalize_inputs` (bool, default=False)
Whether to z-normalize each series before feeding to the model.
- **True** (RECOMMENDED): Normalizes each series to zero mean, unit variance
- **False**: Raw values are passed directly
- **When False is OK**: Only if your series are already normalized or very close to scale 1.0
#### `per_core_batch_size` (int, default=1)
Number of series processed per device in each batch.
- Increase for throughput, decrease if OOM
- See `references/system_requirements.md` for recommended values by hardware
#### `use_continuous_quantile_head` (bool, default=False)
Use the 30M-parameter continuous quantile head for better interval calibration.
- **True** (RECOMMENDED): More accurate prediction intervals, especially for longer horizons
- **False**: Uses fixed quantile buckets (faster but less accurate intervals)
#### `force_flip_invariance` (bool, default=True)
Ensures the model satisfies `f(-x) = -f(x)`.
- **True** (RECOMMENDED): Mathematical consistency — forecasts are invariant to sign flip
- **False**: Slightly faster but may produce asymmetric forecasts
#### `infer_is_positive` (bool, default=True)
Automatically detect if all input values are positive and clamp forecasts ≥ 0.
- **True**: Safe for sales, demand, counts, prices, volumes
- **False**: Required for temperature, returns, PnL, any series that can be negative
#### `fix_quantile_crossing` (bool, default=False)
Post-process quantiles to ensure monotonicity (q10 ≤ q20 ≤ ... ≤ q90).
- **True** (RECOMMENDED): Guarantees well-ordered quantiles
- **False**: Slightly faster but quantiles may occasionally cross
#### `return_backcast` (bool, default=False)
Return the model's reconstruction of the input (backcast) in addition to forecast.
- **True**: Used for covariate workflows and diagnostics
- **False**: Only return forecast
---
## Available Model Checkpoints
| Model ID | Version | Params | Backend | Context |
| -------- | ------- | ------ | ------- | ------- |
| `google/timesfm-2.5-200m-pytorch` | 2.5 | 200M | PyTorch | 16,384 |
| `google/timesfm-2.5-200m-flax` | 2.5 | 200M | JAX/Flax | 16,384 |
| `google/timesfm-2.5-200m-transformers` | 2.5 | 200M | Transformers | 16,384 |
| `google/timesfm-2.0-500m-pytorch` | 2.0 | 500M | PyTorch | 2,048 |
| `google/timesfm-2.0-500m-jax` | 2.0 | 500M | JAX | 2,048 |
| `google/timesfm-1.0-200m-pytorch` | 1.0 | 200M | PyTorch | 2,048 |
| `google/timesfm-1.0-200m` | 1.0 | 200M | JAX | 2,048 |
---
## Output Shape Reference
| Output | Shape | Description |
| ------ | ----- | ----------- |
| `point_forecast` | `(B, H)` | Median forecast for B series, H steps |
| `quantile_forecast` | `(B, H, 10)` | Full quantile distribution |
| `quantile_forecast[:,:,0]` | `(B, H)` | Mean |
| `quantile_forecast[:,:,1]` | `(B, H)` | 10th percentile |
| `quantile_forecast[:,:,5]` | `(B, H)` | 50th percentile (= point_forecast) |
| `quantile_forecast[:,:,9]` | `(B, H)` | 90th percentile |
Where `B` = batch size (number of input series), `H` = forecast horizon.
---
---
## Memory Estimation
Before running forecasts on large datasets, estimate memory requirements:
### Formula
```mermaid
block-beta
columns 3
ram["Total RAM Required"] model["Model Weights<br/>~0.8 GB"] overhead["Runtime Overhead<br/>~0.5 GB"] buffers["I/O Buffers<br/>~0.2 MB per 1000 series<br/>per 1000 context"]
ram --> model
ram --> overhead
ram --> buffers
```
**Formula**:
`RAM (GB) ≈ 0.8 + 0.5 + (0.0002 × num_series × context_length)`
**Variables**:
- `num_series`: Number of time series in your batch
- `context_length`: Your `max_context` value (or max series length)
- `batch_size`: Your `per_core_batch_size` (affects parallel processing overhead)
### Quick Reference
| Dataset Size | Context=512 | Context=1024 | Context=2048 |
|--------------|-------------|--------------|--------------|
| 100 series | ~1.4 GB | ~1.5 GB | ~1.7 GB |
| 1,000 series | ~1.9 GB | ~2.3 GB | ~3.1 GB |
| 10,000 series| ~9.0 GB | ~17.0 GB | ~33.0 GB |
### Using the Preflight Checker
```bash
python scripts/check_system.py \
--num-series 1000 \
--context-length 1024 \
--batch-size 32
```
This validates both system requirements AND dataset fit before loading the model.
### Reducing Memory Usage
If your dataset is too large:
1. **Reduce context length**: Use `max_context=512` instead of 1024+ (50% reduction)
2. **Process in chunks**: Split large batches into smaller groups:
```python
CHUNK_SIZE = 100
for i in range(0, len(inputs), CHUNK_SIZE):
chunk = inputs[i:i+CHUNK_SIZE]
point, quantiles = model.forecast(horizon=H, inputs=chunk)
# Save chunk results
```
3. **Reduce batch size**: Lower `per_core_batch_size` (slower but less memory)
4. **Use CPU**: If GPU OOM, the model will automatically fall back to CPU
## Error Handling
| Error | Cause | Fix |
| ----- | ----- | --- |
| `RuntimeError: Model is not compiled` | Called `forecast()` before `compile()` | Call `model.compile(ForecastConfig(...))` first |
| `torch.cuda.OutOfMemoryError` | Batch too large for GPU | Reduce `per_core_batch_size` |
| `ValueError: inputs must be list` | Passed array instead of list | Wrap in list: `[array]` |
| `HfHubHTTPError` | Download failed | Check internet, set `HF_HOME` to writable dir |