Downloads · 30 days
10
13% of all-time downloads
kdahal/vitg-streamflow-arizona
vitg-streamflow-arizona is a time series forecasting model from kdahal. Use it for the time series forecasting task on the model card, and read the license before you ship it in a product. It is set up for pytorch. The card lists the license as mit.
A Transformer streamflow model that fuses meteorological time series with ViT-DINOv2 satellite embeddings through a learnable per-timestep gate. The gate conditions on weather, compressed ViT features, and a staleness…
Downloads · 30 days
10
13% of all-time downloads
All-time downloads
75
Public
Parameters
5.4M
34.3 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors21.5 MB · 62%
From the Hugging Face model README
A Transformer streamflow model that fuses meteorological time series with ViT-DINOv2 satellite embeddings through a learnable per-timestep gate. The gate conditions on weather, compressed ViT features, and a staleness signal (how many days since the ViT token last changed), so the network learns when to trust the satellite signal instead of treating it as a constant nuisance.
It warm-starts from the TNFR baseline (kdahal/tnfr-streamflow-arizona),
freezes the 40-year-trained Transformer backbone, and trains only the
compressor + gate. This was the strongest single model on natural,
monsoon-driven basins in the TADA study.
from huggingface_hub import snapshot_download
import sys, json, torch
from safetensors.torch import load_file
local = snapshot_download(repo_id="kdahal/vitg-streamflow-arizona")
sys.path.insert(0, local)
from model_code import Model
cfg = json.load(open(f"{local}/config.json"))
model = Model(
enc_in=cfg["enc_in"], dec_in=cfg["dec_in"], c_out=cfg["c_out"], out_len=cfg["out_len"],
d_model=cfg["d_model"], n_heads=cfg["n_heads"],
e_layers=cfg["e_layers"], d_layers=cfg["d_layers"], d_ff=cfg["d_ff"],
dropout=cfg["dropout"], embed=cfg["embed"], freq=cfg["freq"],
activation=cfg["activation"], output_attention=cfg["output_attention"], mix=cfg["mix"],
)
model.load_state_dict(load_file(f"{local}/model.safetensors"))
model.eval()
Bundled demo:
pip install -r requirements.txt
python inference.py
| Name | Shape | Dtype | Meaning |
|---|---|---|---|
x_enc | (B, 365, 634) | float32 | `[weather(250) |
x_mark_enc | (B, 365, 4) | float32 | Time marks (unused; pass zeros for daily data) |
x_dec | (B, 180+30, 1) | float32 | Decoder seed: 180 days history + 30 zeros |
x_mark_dec | (B, 180+30, 4) | float32 | Decoder time marks |
The ViT segment should be DINOv2 ViT-small-14 CLS embeddings (dim 384) from your catchment-centered Sentinel-2 tile for each day; repeat the last-available embedding when no new tile is produced — the model's staleness logic handles the carry.
Output: tuple (pred, attns) where pred has shape (B, 30, 1) because
output_attention=True. Use out[0] for the forecast.
x_enc ─ split ┬─ weather (250) ──────────────────────────────┐
│ ├─ concat ─► Transformer (TADA) ─► pred
└─ ViT (384) ─► compressor (384→128→32) ─► * ──┘
▲
gate(weather | compressed | staleness) ─┘
d_model=d_ff=256, dropout=0.2Strongest single model on natural / monsoon-dominated Arizona basins in the TADA study — see paper for median NSE/KGE tables by regulation tier and season.
Inputs to this model must be z-score normalized with the frozen training
statistics — not statistics computed from your own data. The stats for
ViT-G include the 384 ViT-DINOv2 feature dimensions (so this file is ~13 MB,
larger than the base variant). Shipped as locked_stats.json.
import json, numpy as np
stats = json.load(open("locked_stats.json"))
site = "09379025"
means = stats["basin_dynamic_stats"][site]["means"] # includes vit_0 … vit_383
stds = stats["basin_dynamic_stats"][site]["stds"]
# apply to a daily dataframe `df` with columns matching feature names
for col in means:
df[col] = (df[col] - means[col]) / (stds[col] + 1e-6)
# un-normalize streamflow output
mean_q, std_q = means["streamflow"], stds["streamflow"]
y_real = np.maximum(y_pred.numpy() * std_q + mean_q, 0.0)
Top-level keys in locked_stats.json:
basin_dynamic_stats: per-basin means/stds for 424 features (40 met/hydro + 384 ViT dims)global_static_stats: static catchment-attribute means/stdsstatic_data_lookup: per-basin raw static attribute valuesThe ViT dimensions in basin_dynamic_stats correspond to DINOv2 ViT-small-14
CLS embeddings of catchment-centered Sentinel-2 tiles.
model.safetensors — weights (state_dict)config.json — constructor kwargs (including weather_dim, vit_dim, compressed_dim)locked_stats.json — frozen per-basin normalization statistics (315 Arizona basins, 424 dynamic features)model_code/ — self-contained PyTorch sourceinference.py — end-to-end demoMIT.
kdahal/tnfr-streamflow-arizona — time-series-only baselinekdahal/cnn-streamflow-arizona — CNN hybrid (raster tiles instead of ViT embeddings)