Download scripts/train.py from OneScience-Group/Pangu-ICON-DKE: direct link, hf CLI and curl.
- Browser
- Download file 3.6 kB
-
https://huggingface.co/OneScience-Group/Pangu-ICON-DKE/resolve/main/scripts/train.py
- Command line
-
hf download hf://OneScience-Group/Pangu-ICON-DKE/scripts/train.py
-
curl -L -o train.py https://huggingface.co/OneScience-Group/Pangu-ICON-DKE/resolve/main/scripts/train.py
3.6 kB
| """Run the paper-accurate no-training DataLoader diagnostic dry run.""" | |
| import json | |
| import os | |
| import sys | |
| from pathlib import Path | |
| import numpy as np | |
| import torch | |
| import yaml | |
| from torch.utils.data import DataLoader, Dataset | |
| ROOT = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(ROOT)) | |
| from model.pangu_icon_dke import PanguIconDKEDiagnostics | |
| def load_protocol(config): | |
| source = np.load(ROOT / config["data"]["root"] / config["data"]["protocol_file"]) | |
| protocol = {key: source[key].tolist() for key in source.files if key not in {"phase", "amplitude", "growth_rate", "spectral_phase", "spectral_amplitude", "base_wind_ms", "spectral_slope"}} | |
| coefficients = {key: source[key].tolist() for key in ("phase", "amplitude", "growth_rate", "spectral_phase", "spectral_amplitude", "base_wind_ms", "spectral_slope")} | |
| return protocol, coefficients | |
| class ExperimentDataset(Dataset): | |
| def __init__(self, count): self.count = count | |
| def __len__(self): return self.count | |
| def __getitem__(self, index): return torch.tensor(index, dtype=torch.long) | |
| def main(): | |
| config = yaml.safe_load((ROOT / "conf/config.yaml").read_text()) | |
| protocol, coefficients = load_protocol(config) | |
| if tuple(protocol["field_shape"]) != (5, 73, 1, 721, 1440) or tuple(protocol["spectral_shape"]) != (5, 73, 1, 259560, 2): | |
| raise ValueError("protocol dimensions do not match the public evaluation data") | |
| distributed = int(os.environ.get("WORLD_SIZE", "1")) > 1 | |
| if distributed: | |
| torch.distributed.init_process_group("gloo") | |
| rank = torch.distributed.get_rank() if distributed else 0 | |
| dataset = ExperimentDataset(int(protocol["field_shape"][0])) | |
| sampler = range(rank, len(dataset), torch.distributed.get_world_size()) if distributed else None | |
| loader = DataLoader(dataset, batch_size=1, sampler=sampler, shuffle=False) | |
| model = PanguIconDKEDiagnostics(protocol, coefficients) | |
| if sum(parameter.numel() for parameter in model.parameters()) != 0: | |
| raise RuntimeError("evaluation diagnostic must not have learnable parameters") | |
| dry_values = {} | |
| with torch.no_grad(): | |
| for item in loader: | |
| experiment = int(item[0]) | |
| u, v = model.fields.wind_chunk(experiment, 0, slice(0, 8)) | |
| dry_values[experiment] = float(model(torch.from_numpy(u), torch.from_numpy(v)).mean()) | |
| if distributed: | |
| gathered = [None] * torch.distributed.get_world_size() if rank == 0 else None | |
| torch.distributed.gather_object(dry_values, gathered, dst=0) | |
| if rank == 0: | |
| dry_values = {key: value for shard in gathered for key, value in shard.items()} | |
| if rank == 0: | |
| checkpoint_path = ROOT / config["paths"]["checkpoint"] | |
| metrics_path = ROOT / config["paths"]["training_metrics"] | |
| checkpoint_path.parent.mkdir(parents=True, exist_ok=True) | |
| metrics_path.parent.mkdir(parents=True, exist_ok=True) | |
| torch.save({"model": model.state_dict(), "model_config": config["generator"], "format_version": protocol["format_version"], "protocol": protocol, "coefficients": coefficients}, checkpoint_path) | |
| metrics_path.write_text(json.dumps({"training_required": False, "backward_executed": False, "learnable_parameters": 0, "diagnostic_dry_run": True, "experiment_dry_run": [dry_values[index] for index in range(len(dataset))]}, indent=2) + "\n") | |
| print(f"checkpoint={checkpoint_path.relative_to(ROOT)} training_required=false backward=false") | |
| if distributed: | |
| torch.distributed.destroy_process_group() | |
| if __name__ == "__main__": | |
| main() | |