FourCastNet_v2 / scripts /inference.py
yzt15806542928's picture
Upload folder using huggingface_hub
eca4864 verified
Raw
History Blame Contribute Delete
3.57 kB
from __future__ import annotations
import argparse
import sys
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
MODEL_DIR = SCRIPT_DIR.parent / "model"
for module_dir in (SCRIPT_DIR, MODEL_DIR):
if str(module_dir) not in sys.path:
sys.path.insert(0, str(module_dir))
import numpy as np
import torch
from common import DEFAULT_CONFIG, active_model_config, load_config, resolve_path
from data import build_loader, load_statistics
from fourcastnet_v2 import (
FourCastNetV2,
load_checkpoint,
)
def choose_device() -> torch.device:
return torch.device("cuda", 0) if torch.cuda.is_available() else torch.device("cpu")
def main() -> None:
parser = argparse.ArgumentParser(description="Run FourCastNet v2 inference")
parser.add_argument("--config", default=str(DEFAULT_CONFIG))
parser.add_argument("--checkpoint")
args = parser.parse_args()
config = load_config(args.config)
inference = config["inference"]
device = choose_device()
model = FourCastNetV2(active_model_config(config)).to(device)
if args.checkpoint:
checkpoint_path = resolve_path(config, args.checkpoint)
else:
checkpoint_path = resolve_path(config, inference["checkpoint_path"])
result = load_checkpoint(
model,
checkpoint_path,
expected_profile=config["model"]["profile"],
expected_variables=config["data"]["variables"],
allowed_stages={"one_step", "finetune"},
allowed_initializations={"random", "one_step_checkpoint"},
strict=config["checkpoint"]["strict"],
map_location=device,
)
if result["missing_keys"] or result["unexpected_keys"]:
print(
f"missing_keys={result['missing_keys']} "
f"unexpected_keys={result['unexpected_keys']}"
)
loader, _ = build_loader(
config,
config["data"]["test_years"],
train=False,
distributed=False,
output_steps=inference["rollout_steps"],
)
means, stds = load_statistics(config)
means = means.numpy()
stds = stds.numpy()
output_dir = resolve_path(config, inference["output_dir"])
output_dir.mkdir(parents=True, exist_ok=True)
model.eval()
with torch.no_grad():
for sample_index, batch in enumerate(loader):
if sample_index >= inference["max_samples"]:
break
inputs = batch[0].to(device)
targets = batch[1]
state = inputs
predictions = []
for _ in range(inference["rollout_steps"]):
state = model(state)
predictions.append(state.cpu())
prediction = torch.stack(predictions, dim=1).numpy()
if targets.ndim == 4:
targets = targets.unsqueeze(1)
target = targets.numpy()
input_array = inputs.cpu().numpy()
if not inference["save_normalized"]:
prediction = prediction * stds[:, None] + means[:, None]
target = target * stds[:, None] + means[:, None]
input_array = input_array * stds + means
path = output_dir / f"sample_{sample_index:04d}.npz"
np.savez_compressed(
path,
input=input_array,
prediction=prediction,
target=target,
variables=np.asarray(config["data"]["variables"]),
time_index=np.asarray(batch[4], dtype=str).T,
)
print(path)
if __name__ == "__main__":
main()