Add giant.analysis module for notebook-based model quality diagnostics

Provides stratified marginal comparisons, joint-structure checks (correlation
matrices, physically-coupled pairwise plots, direction alignment), and
physical-constraint validation (unit-norm directions, non-negative raw
targets) for a trained model's generated samples, building on the aggregate
marginal/KL check already in giant.validate.

Supports two entry points: live sampling against a checkpoint + val data
(load_model_bundle/collect_samples), or loading a precomputed
`giant predict --coord local` parquet directly (load_predicted_local) without
needing the checkpoint at all. Predict output is now tagged with parquet
schema metadata so the loader can verify a file's format and reject
coord=global or untagged files with a clear error instead of guessing from
column names.

Also extends the config git-hash mismatch warning (added for --config
loading) to checkpoint loading: both `giant predict` and
analysis.load_model_bundle now look for a config.toml next to the checkpoint
and warn (without failing) if it was generated from a different git commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 16:36:19 +02:00
parent da84801625
commit a867fc4aae
8 changed files with 1307 additions and 2 deletions
+12 -1
View File
@@ -11,7 +11,12 @@ import pyarrow as pa
import pyarrow.parquet as pq
from giant import config as gconfig
from giant.constants import LOCAL_TARGET_NAMES
from giant.constants import (
LOCAL_TARGET_NAMES,
PREDICT_COORD_METADATA_KEY,
PREDICT_SCHEMA_VERSION,
PREDICT_SCHEMA_VERSION_KEY,
)
from giant.data.loader import (
find_parquet_files,
iter_file_chunks,
@@ -135,6 +140,7 @@ def predict(
model.load_state_dict(ckpt["model"])
model.to(_device).eval()
typer.echo(f"loaded checkpoint: {checkpoint}")
gconfig.warn_if_checkpoint_config_mismatch(checkpoint)
# --- Output path ---
if out is None:
@@ -234,6 +240,11 @@ def predict(
"post_z": post_pos_world[:, 2],
})
table = table.replace_schema_metadata({
PREDICT_COORD_METADATA_KEY: coord.value,
PREDICT_SCHEMA_VERSION_KEY: PREDICT_SCHEMA_VERSION,
})
if writer is None:
writer = pq.ParquetWriter(out, table.schema)
writer.write_table(table)