How to use from the
Use from the
Transformers library
# pip install -U transformers accelerate
# Load model directly
from transformers import WeatherNext2ForWeatherForecasting
model = WeatherNext2ForWeatherForecasting.from_pretrained("kashif/weathernext2-mini", device_map="auto")
Quick Links

WeatherNext 2 Mini

WeatherNext 2 Mini is the lightweight variant of Google DeepMind's WeatherNext 2, at 1° resolution instead of 0.25°. It forecasts the same quantities as the full model — 13 pressure levels of temperature, geopotential, wind and humidity, surface fields, precipitation, and 17 tropical-cyclone diagnostics — and is intended for local testing and for machines that cannot hold the 0.25° model. It is not expected to match the full model's skill.

It is a Functional Generative Network (FGN): rather than injecting a noise field into the input or running a diffusion sampler, the model draws a single 32-dimensional noise vector per ensemble member and uses it to modulate the scale and offset of every normalization layer. One draw gives one self-consistent forecast, and an ensemble is simply several draws — which here is just the batch dimension.

The architecture matches the 0.25° models at reduced width and depth. See kashif/weathernext2 and kashif/weathernext-cyclones for the full-resolution versions.

Revisions

Each revision is trained on data up to a different cut-off, so you can evaluate on a year the model has not seen.

Revision Trained through Corresponds to
main 2023 WeatherNextCyclones_Mini_<2024
<2023 2022 WeatherNextCyclones_Mini_<2023
model = WeatherNext2ForWeatherForecasting.from_pretrained("kashif/weathernext2-mini", revision="<2023")

Unlike the 0.25° releases, the Mini checkpoints ship a single trained network per cut-off rather than a four-member ensemble, so only the noise ensemble applies; see Ensembles.

Usage

WeatherNext 2 support is not in a released Transformers version yet. Until huggingface/transformers#47874 is merged, install the branch:

pip install "git+https://github.com/kashif/transformers.git@add-weathernext2" torch accelerate

The model predicts normalized fields. WeatherNext2FeatureExtractor handles normalization, clock forcings and conversion back to physical units. Initialize from two chronological HRES analysis frames, six hours apart, with ascending latitude, the checkpoint's pressure levels and all configured input fields, including static fields. See the official demo and the model documentation for data preparation. The example below assumes those physical fields have been loaded into state.

import numpy as np
import torch
from transformers import WeatherNext2FeatureExtractor, WeatherNext2ForWeatherForecasting

repo = "kashif/weathernext2-mini"
model = WeatherNext2ForWeatherForecasting.from_pretrained(repo, device_map="auto").eval()
processor = WeatherNext2FeatureExtractor.from_pretrained(repo)

# Replace the ellipses with physical HRES fields:
# time-varying fields: [batch, 2, (levels,) lat, lon]; static fields: [lat, lon].
state = {
    name: ...
    for name in processor.input_variables
    if name not in processor.forcing_variables
}
valid_time = np.array([np.datetime64("2024-10-07T06:00:00").astype("datetime64[s]").astype(np.int64)])
conditioning_times = valid_time[:, None] - (
    processor.time_step_hours * 3600 * np.arange(processor.num_input_timesteps, 0, -1)
)
state.update(processor.compute_forcings(conditioning_times))

inputs = processor(
    state, seconds_since_epoch=valid_time, generator=torch.Generator().manual_seed(0)
).to(device=model.device, dtype=model.dtype)
with torch.no_grad():
    outputs = model(**inputs)
forecast = processor.postprocess(outputs.prediction, state)
print(forecast["2m_temperature"].shape)  # torch.Size([1, 181, 360])
print(forecast["cyclone_exists_gaussian_unit_mode"].max())

Noise is sampled by the processor, not by the model forward. The processor includes both noise and the shared geometry attention_mask in inputs; do not pass a second noise argument or repeat the mask over ensemble members.

Autoregressive rollout

generate() prepares inputs, advances each member using its own predicted state, and samples fresh noise at each six-hour step. seconds_since_epoch is the valid time of the first forecast, not the last conditioning frame.

rollout = model.generate(
    state=state,
    feature_extractor=processor,
    seconds_since_epoch=valid_time,
    num_steps=20,  # 5 days
    generator=torch.Generator().manual_seed(0),
)
frames = rollout.forecasts
next_state = rollout.state

Cyclone outputs are gridded diagnostics, not tracks. Track extraction remains a separate step in the original repository.

Ensembles

Noise ensemble

Members share weights but receive independent noise. generate(num_members=8) repeats each initial condition and runs the resulting members along the batch axis. batch_size=1 limits the rows evaluated together; returned forecasts and conditioning states still contain the whole ensemble.

ensemble = model.generate(
    state=state,
    feature_extractor=processor,
    seconds_since_epoch=valid_time,
    num_steps=1,
    num_members=8,
    batch_size=1,
    generator=torch.Generator().manual_seed(0),
)
print(ensemble.forecasts[0]["2m_temperature"].shape)  # torch.Size([8, 181, 360])

For multiple initial conditions, member m of condition i is row i * num_members + m. A direct forward can use processor(..., num_members=8) instead. Step/member defaults can also be set in model.generation_config.

Mini has one trained network per cut-off, so its ensemble is entirely a noise ensemble. The full-resolution repositories also provide four independently trained networks.

Fine-tuning

Pass physical next-step targets with shape [batch, (levels,) lat, lon] and at least two ensemble members. The processor produces normalized labels; the model returns the original unbiased ensemble CRPS.

model = WeatherNext2ForWeatherForecasting.from_pretrained(repo, device_map="auto")
train_inputs = processor(
    state,
    seconds_since_epoch=valid_time,
    targets=targets,
    num_members=2,
    generator=torch.Generator().manual_seed(0),
).to(device=model.device, dtype=model.dtype)
model.train()
loss = model(**train_inputs).loss
loss.backward()

The loss uses latitude and pressure-level weights plus the checkpoint's loss_weights, vars_with_nan_targets and loss_for_nan_targets. Missing cyclone targets are masked in both CRPS terms. Training memory requirements differ from inference; the optional Hub kernel optimizations below are for inference.

Model details

  • Architecture: encode–process–decode graph network. The lat/lon grid is encoded, projected onto an icosahedral mesh by a graph network (ball-query connectivity), processed by a 16-layer transformer whose attention is restricted to a 16-hop neighbourhood on the mesh, projected back (in-triangle connectivity), and decoded.
  • Hidden size / layers / heads: 512 / 16 / 4, feed-forward 2048. 56.7M parameters.
  • Mesh: icosahedron refined 5 times → 10,242 nodes, with 16-hop attention.
  • Positional information: none learned. Exact geometry is stored as persistent buffers in model.geometry; the processor loads the separate attention_mask.safetensors asset and passes the shared mask to the model.
  • Inputs: two frames 6h apart, 13 pressure levels, plus static fields and calendar forcings.
  • Time step: 6 hours.

Evaluation

A single 6-hour step from ECMWF HRES analysis (initialized 2024-10-07 00:00 UTC), scored against the verifying analysis with latitude weighting, using the main revision at 1° resolution:

Field WeatherNext 2 Mini Persistence
2m temperature 0.785 K 2.620 K
Temperature @500hPa 0.414 K 1.197 K
Geopotential @500hPa 31.7 m²/s² 224.5 m²/s²

This is a single case, meant as a smoke test of the port rather than a benchmark. For cyclone track and intensity scorecards see the Nature paper; for general forecast skill see WeatherBench 2.

Hardware and optional kernels

Memory and runtime depend on resolution, dtype, attention implementation, ensemble size and device. Geometry and the attention mask are included in the checkpoint assets; loading does not rebuild the mesh and does not require SciPy or trimesh.

For supported devices, optional Hub kernels tile the grid encoder, grid-to-mesh and mesh-to-grid operations, and forecast head. Install kernels, then enable them when loading:

model = WeatherNext2ForWeatherForecasting.from_pretrained(
    repo, device_map="auto", use_kernels=True
).eval()

chunk_size controls the inference tile size and can be supplied when loading. Smaller tiles reduce intermediate allocations but may increase overhead. To limit the number of ensemble members evaluated together, use generate(..., batch_size=1); returned forecasts and conditioning states still retain every member.

Limitations

This is a research model, not an operational warning system, and it does not replace official alerts, warnings or notices from national meteorological agencies. It was not produced in collaboration with, nor endorsed by, any government meteorological agency. It is designed to be initialized from operational HRES analysis rather than from reanalysis.

License

The weights are released by Google DeepMind under CC-BY-4.0. The original code is Apache-2.0. Original repository: google-deepmind/weathernext.

Acknowledgements

Data and products of the European Centre for Medium-range Weather Forecasts (ECMWF), as modified by Google. Modified Copernicus Climate Change Service information 2023. NOAA's International Best Track Archive for Climate Stewardship (IBTrACS) data, first accessed on 1 Dec 2022. Neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus information or data it contains. ECMWF HRES datasets copyright statement: Copyright "© 2023 European Centre for Medium-Range Weather Forecasts (ECMWF)". Source: www.ecmwf.int. License statement: ECMWF open data is published under a Creative Commons Attribution 4.0 International (CC BY 4.0), https://creativecommons.org/licenses/by/4.0/. Disclaimer: ECMWF does not accept any liability whatsoever for any error or omission in the data, their availability, or for any loss or damage arising from their use.

Citation

@article{Alet2026,
  title={Operational Tropical Cyclone Forecasting with AI},
  author={Alet, Ferran and Andersson, Tom R. and Price, Ilan and Markou, Stratis and El-Kadi, Andrew and Masters, Dominic and Li, Amy and Merchant, Samier and Williams, Natalie and Thornton, Gregory and MacKay, Ken and Graham, Olivia and Uddin, Akib and Gaiarin, Ben and Shah, Devaja and Kruse, Elinor and Hogsett, Wallace and Zelinsky, David and Cangialosi, John and Martinez, Jonathan and Franklin, James and DeMaria, Mark and Musgrave, Kate and Bain, Caroline L. and Titley, Helen and Stott, Jacklynn and Lam, Remi and Bell, Aaron and Komarek, Paul and Willson, Matthew and Sanchez-Gonzalez, Alvaro and Battaglia, Peter},
  journal={Nature},
  year={2026},
  issn={1476-4687},
  doi={10.1038/s41586-026-10953-2},
  url={https://doi.org/10.1038/s41586-026-10953-2}
}
@article{alet2025skillful,
  title={Skillful joint probabilistic weather forecasting from marginals},
  author={Alet, Ferran and Price, Ilan and El-Kadi, Andrew and Masters, Dominic and Markou, Stratis and Andersson, Tom R and Stott, Jacklynn and Lam, Remi and Willson, Matthew and Sanchez-Gonzalez, Alvaro and Battaglia, Peter},
  journal={arXiv preprint arXiv:2506.10772},
  year={2025}
}
Downloads last month
145
Safetensors
Model size
58.7M params
Tensor type
I64
·
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for kashif/weathernext2-mini

Finetunes
1 model

Paper for kashif/weathernext2-mini