Download scripts/inference.py from OneScience-Group/QCPINN-CavityFlow: direct link, hf CLI and curl.
- Browser
- Download file 5.71 kB
-
https://huggingface.co/OneScience-Group/QCPINN-CavityFlow/resolve/main/scripts/inference.py
- Command line
-
hf download hf://OneScience-Group/QCPINN-CavityFlow/scripts/inference.py
-
curl -L -o inference.py https://huggingface.co/OneScience-Group/QCPINN-CavityFlow/resolve/main/scripts/inference.py
5.71 kB
| """Reload a trained checkpoint; stream evaluation from the supplied MATLAB HDF5.""" | |
| import argparse | |
| import json | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| import h5py | |
| import numpy as np | |
| import torch | |
| from common import (ROOT, atomic_json, build_model, load_checkpoint, load_config, | |
| predict, relative_metrics, resolved, seed_everything, sha256, | |
| validation_indices) | |
| def infer(config, checkpoint_path, output_dir, metrics_only=False): | |
| seed_everything(0, config["training"]["num_threads"]) | |
| model = build_model(config) | |
| checkpoint = load_checkpoint(checkpoint_path, model) | |
| if checkpoint["config"]["model"] != config["model"]: | |
| raise ValueError("Checkpoint and requested model configuration differ") | |
| model.eval() | |
| out = Path(output_dir) | |
| out.mkdir(parents=True, exist_ok=True) | |
| source_path = resolved(config, "reference") | |
| report = {"checkpoint": str(Path(checkpoint_path).resolve()), "checkpoint_sha256": sha256(checkpoint_path), | |
| "source": str(source_path), "source_sha256": sha256(source_path), | |
| "seed": checkpoint["seed"], "epoch": checkpoint["epoch"], "selection_score": checkpoint["selection_score"], | |
| "validation_metrics": checkpoint["validation_metrics"], | |
| "metric": "raw ||pred-ref||2/||ref||2; no pressure gauge alignment", | |
| "groups": {}, "reference_regenerated": False, "checkpoint_reloaded": True} | |
| size = config["inference"]["batch_size"] | |
| global_num, global_den = np.zeros(3), np.zeros(3) | |
| output = None if metrics_only else h5py.File(out/"predictions.h5.tmp", "w") | |
| try: | |
| with h5py.File(source_path, "r") as source: | |
| for key in config["inference"]["reference_keys"]: | |
| data = source[key] | |
| if data.ndim != 2 or data.shape[0] != 6: raise ValueError(f"Invalid {key} shape: {data.shape}") | |
| count = data.shape[1] | |
| numer, denom, hold_num, hold_den = [np.zeros(3) for _ in range(4)] | |
| if key == config["validation"]["reference_key"]: | |
| valids = validation_indices(config, count) | |
| group = None | |
| if output is not None: | |
| group = output.create_group(key) | |
| group.create_dataset("coordinates", (count, 3), dtype="f8", chunks=True) | |
| group.create_dataset("prediction", (count, 3), dtype="f4", chunks=True) | |
| for start in range(0, count, size): | |
| end = min(start+size, count) | |
| rows = data[:, start:end].T | |
| if not np.isfinite(rows).all(): raise ValueError(f"Nonfinite input in {key} at {start}") | |
| preds = predict(model, rows[:, :3], size) | |
| if not np.isfinite(preds).all(): raise FloatingPointError("Nonfinite predictions") | |
| error2 = (preds.astype(np.float64)-rows[:, 3:])**2 | |
| ref2 = rows[:, 3:]**2 | |
| numer += error2.sum(0) | |
| denom += ref2.sum(0) | |
| if key == config["validation"]["reference_key"]: | |
| keep = ~np.isin(np.arange(start, end), valids, assume_unique=True) | |
| hold_num += error2[keep].sum(0) | |
| hold_den += ref2[keep].sum(0) | |
| if group is not None: | |
| group["coordinates"][start:end] = rows[:, :3] | |
| group["prediction"][start:end] = preds | |
| metrics = relative_metrics(numer, denom) | |
| report["groups"][key] = {"count": count, "metrics": metrics} | |
| global_num += numer | |
| global_den += denom | |
| if key == config["validation"]["reference_key"]: | |
| report["internal_holdout"] = {"count": count-len(valids), "metrics": relative_metrics(hold_num, hold_den)} | |
| print(f"INFERENCE key={key} count={count} metrics={json.dumps(metrics)}", flush=True) | |
| report["all_reference"] = {"metrics": relative_metrics(global_num, global_den), | |
| "count": sum(v["count"] for v in report["groups"].values())} | |
| if output is not None: | |
| output.attrs["provenance"] = json.dumps({k: v for k, v in report.items() if k not in ["groups", "internal_holdout", "all_reference"]}) | |
| output.close() | |
| output = None | |
| (out/"predictions.h5.tmp").replace(out/"predictions.h5") | |
| atomic_json(out/"metrics.json", report) | |
| finally: | |
| if output is not None: output.close() | |
| print("INFERENCE_COMPLETED", flush=True) | |
| return report | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--config", default=str(ROOT/"config/config.yaml")) | |
| parser.add_argument("--checkpoint", type=Path) | |
| parser.add_argument("--output-dir", type=Path) | |
| parser.add_argument("--seed", type=int) | |
| parser.add_argument("--kind", choices=["best", "last"], default="best") | |
| parser.add_argument("--metrics-only", action="store_true") | |
| args = parser.parse_args() | |
| cfg = load_config(args.config) | |
| checkpoint = args.checkpoint or (resolved(cfg, "weights")/f"seed_{args.seed}"/("best_model.pt" if args.kind == "best" else "last_model.pt") if args.seed is not None else resolved(cfg, "weights")/"best_model.pt") | |
| output = args.output_dir or (resolved(cfg, "results")/f"seed_{args.seed}"/("best_eval" if args.kind == "best" else "final_eval") if args.seed is not None else resolved(cfg, "results")/"best_model") | |
| infer(cfg, checkpoint, output, args.metrics_only) | |