AMC-Lahti · v1.0
CRAN-PM v1.0
A multi-scale Vision Transformer for high-resolution PM2.5 forecasting over Europe
Open-source Python package that downscales 25 km ERA5/CAMS reanalysis fields to 1 km daily PM2.5 forecasts through a cross-resolution attention bridge with wind-guided ordering and an elevation-aware attention bias.
- RMSE 6.85 µg m-3 @ T+1 (Europe, 2971 EEA stations)
- OOD 8 zero-shot regions tested (India, China, USA…)
- GPU dual NVIDIA CUDA + AMD ROCm
Training: Europe (in-distribution). Zero-shot OOD: 8 regions.
Abstract
We present CRAN-PM v1.0, an open-source Python package for short-range high-resolution surface PM2.5 forecasting over Europe. The underlying model is a dual-branch Vision Transformer that fuses 25 km meteorological and chemistry fields with 1 km satellite-derived PM2.5 analyses through a cross-resolution attention bridge. Beyond its scientific accuracy (RMSE = 6.85 µg m-3 at T+1 against 2 971 EEA stations, 4.7–10.7 % lower than the best deep-learning baseline), the package emphasises reproducibility, GPU portability and accessibility to atmospheric scientists. CRAN-PM ships with a stable Python API, command-line interface, training and inference workflows, dual support for NVIDIA CUDA and AMD ROCm, container images, a HuggingFace model repository and a Gradio web demonstrator.
How it works
From 25 km meteorology/chemistry and 1 km satellite PM2.5 to a 1 km next-day forecast, validated against ground stations — end to end:
Live demo
Enter any coordinates in Europe and pick a date in the 2022 test year; the back-end runs a genuine CRAN-PM forward pass on cached ERA5/CAMS/GHAP inputs and renders the 1 km T+1 forecast, scored against the EEA stations. No setup required.
Running on HuggingFace Spaces (CPU free tier; ~60 s/inference). For heavy workloads, install the package locally — see Code & data.
Figures
Selected figures from the paper. All are reproducible from the
scripts in paper/scripts/; click any thumbnail for the
full-size PDF.
Study domain
Robinson global view: training Europe + 8 zero-shot OOD regions + 12 k stations.
Elevation-aware attention
Attention from a Po Valley source: the elevation bias carves a clear shadow along the Alpine ridge.
Froude diagnostic
Fr = U/(NH) over Europe: lower CRAN-PM error inside blocked (Fr<1) regions.
Patch shuffling (animation)
Random vs raster vs wind-guided ordering on the China OOD domain (animated GIF).
Lagrangian frame
Wind-guided ordering = discrete streamline coordinate of an advective transport.
Shuffling ablation
From-scratch training of 3 patch-ordering strategies, 3 epochs each.
Physics ablation
Test-time interventions on each physical prior: the model is materially sensitive to wind, elevation, and chemistry.
Physics × method heatmap
RMSE degradation per (model × intervention). CRAN-PM has the largest sensitivity to physics.
Zero-shot — India
Hotspot day map with Delhi NCR / IGP / Mumbai zooms.
Zero-shot scatter — India
Annual mean GHAP vs CRAN-PM (2022, 364 days).
Case study — Saharan dust
March 2022 intrusion: CRAN-PM tracks the trans-boundary advection.
GPU benchmarks
Throughput & memory on AMD MI250X (ROCm) across bf16 / fp16 / fp32.
Code & data availability
Source code
- GitHub: AmmarKheder/cran-pm
- Zenodo DOI (v1.0.0):
10.5281/zenodo.20285633 - Install:
pip install cran-pm - Docker (reproducible runtime):
docker run --rm ghcr.io/ammarkheder/cran-pm:v1.0.0 cranpm --help
ghcr.io/ammarkheder/cran-pm - License: MIT
Pre-trained model
- HuggingFace: ammarkheder/cran-pm-europe
- File:
cranpm-europe-v1.0.ckpt(1.14 GB) - Loader:
from cranpm import CRANPMForecaster m = CRANPMForecaster.from_pretrained( "ammarkheder/cran-pm-europe")
Input datasets
- ERA5 reanalysis — Copernicus CDS
- CAMS atmospheric composition — Copernicus ADS
- GHAP daily PM2.5 — Wei et al. 2023 (Zenodo 10.5281/zenodo.6398971)
- GMTED2010 elevation — USGS
- EEA air-quality stations — European Environment Agency
Predictions & evaluations
- Europe 2022 per-date input bundles + CRAN-PM forecasts + matched EEA observations: HuggingFace dataset
- 8 OOD region predictions & evaluation JSONs/figures (in the repo release)
Run with Docker
A pinned CPU/CUDA image is published to the GitHub Container Registry on every release, so you can run CRAN-PM with no local Python setup — identical environment, reproducible for years.
# pull the released image
docker pull ghcr.io/ammarkheder/cran-pm:v1.0.0
# command-line help
docker run --rm ghcr.io/ammarkheder/cran-pm:v1.0.0 cranpm --help
# run a forecast (mount a folder for inputs/outputs)
docker run --rm -v "$PWD":/data ghcr.io/ammarkheder/cran-pm:v1.0.0 \
cranpm forecast --date 2022-03-15 --region europe --out /data
Image:
ghcr.io/ammarkheder/cran-pm · built from
docker/Dockerfile by the Publish Docker image
GitHub Actions workflow. Training on AMD MI250X (LUMI) uses the
ROCm stack via Singularity — see the
README.
Cite
If you use CRAN-PM in your research, please cite the software release:
@software{kheder2026cranpm,
title = {CRAN-PM v1.0: a multi-scale Vision Transformer for
high-resolution PM2.5 forecasting over Europe},
author = {Kheder, Ammar and Peng, Wenqing and Toropainen, Helmi and
Liu, Zhi-Song and Boy, Michael},
year = {2026},
note = {Atmospheric Modelling Centre Lahti (AMC-Lahti)},
}
Contact & report a problem
Found a bug, a suspicious forecast, or have a question? Send a ticket to the AMC-Lahti team. It opens a tracked issue on GitHub (you can also use the chat in the live demo).
Existing tickets
Live from GitHub Issues — open reports from the community.