Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ jobs:
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Create virtual environment
run: uv venv
- name: Install build dependencies
- name: Install dependencies
run: |
uv pip install build ".[torch,flax]"
uv pip install -e ".[dev,torch,flax]"
- name: Run tests
run: pytest tests/ -v
- name: Build package
run: uv run python -m build
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ wandb/
datasets/
results/
uv.lock
development_setup.md
debug.log
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ Archived v1/v2 code and notebooks are in `v1/`.
Run tests:

```bash
pytest v1/tests/
pytest tests/
```

See `README.md` for full developer setup.
For archived v1/v2 models, use `pytest v1/tests/` instead.

See `development_setup.md` and `README.md` for full developer setup.
51 changes: 51 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# How to Contribute

We would love to accept your patches and contributions to this project.

## Before you begin

### Sign our Contributor License Agreement

Contributions to this project must be accompanied by a
[Contributor License Agreement](https://cla.developers.google.com/about) (CLA).
You (or your employer) retain the copyright to your contribution; this simply
gives us permission to use and redistribute your contributions as part of the
project.

If you or your current employer have already signed the Google CLA (even if it
was for a different project), you probably don't need to do it again.

Visit <https://cla.developers.google.com/> to see your current agreements or to
sign a new one.

### Review our Community Guidelines

This project follows [Google's Open Source Community
Guidelines](https://opensource.google/conduct/).

## Development setup

See [development_setup.md](development_setup.md) for environment setup, running
tests, and the fork → PR workflow.

## Contribution process

### Code Reviews

All submissions, including submissions by project members, require review. We
use [GitHub pull requests](https://docs.github.com/articles/about-pull-requests)
for this purpose.

### Where to contribute

- **TimesFM 2.5 (current):** `src/timesfm/` and `tests/`
- **Examples and docs:** `timesfm-forecasting/`, `README.md`
- **Archived v1/v2 models:** `v1/` (legacy; separate Poetry environment)

### Pre-submit checklist

```bash
pytest tests/ --ignore=tests/test_model_loading.py
ruff check src/ tests/
uv run python -m build
```
85 changes: 85 additions & 0 deletions development_setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Development Setup

Guide for contributing to TimesFM 2.5. Archived v1/v2 code in `v1/` uses a
separate Poetry environment — see `v1/README.md` if you need legacy models.

## Prerequisites

- Python 3.10+ (3.11 recommended; matches CI)
- [uv](https://docs.astral.sh/uv/) package manager

## Local environment

```bash
git clone https://github.com/google-research/timesfm.git
cd timesfm

uv python install 3.11
uv python pin 3.11
uv venv --python 3.11
source .venv/bin/activate

# PyTorch backend (recommended for most contributors)
uv pip install -e ".[dev,torch]"

# Or install all backends for full test coverage
uv pip install -e ".[dev,torch,flax]"
```

On Apple Silicon or GPU machines, you may need to reinstall torch/jax from the
official install guides after the editable install.

## Verify setup

```bash
python -c "import timesfm; print(timesfm.TimesFM_2p5_200M_torch)"
pytest tests/ --ignore=tests/test_model_loading.py
uv run python -m build
```

## Fork and pull request workflow

1. **Fork** [google-research/timesfm](https://github.com/google-research/timesfm)
on GitHub.

2. **Add your fork** as a remote:

```bash
git remote add fork https://github.com/<your-username>/timesfm.git
```

3. **Sign the Google CLA** at <https://cla.developers.google.com/> (required
before your PR can be merged).

4. **Create a branch**, make changes, and open a PR:

```bash
git checkout -b feature/my-change
pytest tests/ --ignore=tests/test_model_loading.py
ruff check src/ tests/
git add <files>
git commit -m "Describe why, not just what"
git push -u fork feature/my-change
```

Open a pull request against `google-research/timesfm:master`.

See [CONTRIBUTING.md](CONTRIBUTING.md) for community guidelines and review
process.

## Test matrix

| Test file | Requires |
|-----------|----------|
| `tests/test_configs.py` | core |
| `tests/test_base_utils.py` | core |
| `tests/test_torch_layers.py` | `[torch]` |
| `tests/test_torch_utils.py` | `[torch]` |
| `tests/test_model_loading.py` | `[torch]` + `[flax]` |

## Lint

```bash
ruff check src/ tests/
ruff format --check src/ tests/
```
11 changes: 11 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ xreg = [
"jax[cuda]",
"scikit-learn",
]
dev = [
"pytest>=8.0",
"ruff>=0.8",
"build>=1.0",
]

[tool.setuptools.packages.find]
where = ["src"]

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.ruff]
line-length = 88
Expand Down
23 changes: 16 additions & 7 deletions timesfm-forecasting/examples/anomaly-detection/detect_anomalies.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,16 +419,25 @@ def main() -> None:
print(f" {r['date']} {r['value']:+.3f} C z={r['z_score']:+.2f}")

# --- Load TimesFM --------------------------------------------------------
print("\n Loading TimesFM 1.0 ...")
print("\n Loading TimesFM 2.5 ...")
import timesfm

hparams = timesfm.TimesFmHparams(horizon_len=HORIZON)
checkpoint = timesfm.TimesFmCheckpoint(
huggingface_repo_id="google/timesfm-1.0-200m-pytorch"
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch",
torch_compile=False,
)
model.compile(timesfm.ForecastConfig(
max_context=512,
max_horizon=HORIZON,
normalize_inputs=True,
use_continuous_quantile_head=True,
fix_quantile_crossing=True,
))

point_out, quant_out = model.forecast(
horizon=HORIZON,
inputs=[context_values],
)
model = timesfm.TimesFm(hparams=hparams, checkpoint=checkpoint)

point_out, quant_out = model.forecast([context_values], freq=[0])
point_fc = point_out[0] # shape (HORIZON,)
quant_fc = quant_out[0].T # shape (10, HORIZON)

Expand Down
Loading
Loading