Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added geometry functionals in `physicsnemo.nn.functional` for
`mesh_poisson_disk_sample`, `mesh_to_voxel_fraction`, and
`signed_distance_field`.
- Adds embedded OOD guardrail `OODGuard` at
`physicsnemo.experimental.guardrails.embedded`, optionally
wired into `GeoTransolver` via a new `guard_config` constructor argument.
The guard calibrates per-channel global bounds and a geometry-latent
kNN threshold during training, and emits warnings on out-of-distribution
inputs at inference.

### Changed

Expand Down
2 changes: 1 addition & 1 deletion examples/minimal/guardrails/geometry_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import multiprocessing as mp
from pathlib import Path

from physicsnemo.experimental.guardrails import GeometryGuardrail
from physicsnemo.experimental.guardrails.geometry import GeometryGuardrail


def prepare_datasets(
Expand Down
41 changes: 41 additions & 0 deletions examples/structural_mechanics/crash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,47 @@ torchrun --nproc_per_node=<NUM_GPUS> inference.py --config-name=bumper_geotranso
Runs are sharded across ranks: rank `r` processes `run_items[r::world_size]`.
Predicted meshes are written as .vtp files under `./predicted_vtps/`, and can be opened using ParaView.

## Guardrails (OOD detection)

GeoTransolver ships with an optional embedded out-of-distribution (OOD) guardrail
that calibrates during training and emits warnings at inference when inputs
drift outside the training distribution. It watches two surfaces:

- **Global parameters** — per-channel bounding box on the global embedding
(e.g. `velocity_x`, `thickness_scale`).
- **Geometry** — k-nearest-neighbour distance on a pooled geometry latent.

Enable it through the model config by setting `guard_config` to a mapping
(leave `null` to disable):

```yaml
# conf/my_experiment.yaml
model:
guard_config:
buffer_size: 121 # FIFO buffer; typically = num_training_samples
Comment thread
mnabian marked this conversation as resolved.
knn_k: 10 # k for geometry kNN distance
sensitivity: 1.5 # threshold multiplier on 99th-percentile kNN dist
```

No changes to `train.py` / `inference.py` are required: during training the
guard silently collects calibration statistics, and during inference it emits
warnings of the form `OOD Guard: geometry sample ...` or
`OOD Guard: global_embedding dim ...` to the Python logger whenever a sample
falls outside the calibrated training envelope. Warnings do not halt inference.

Two inference drivers are provided to synthesise OOD samples for testing the
guard end-to-end:

```bash
# Scale every global-feature scalar by 1.5x (default):
python inference_ood_global.py --config-name=bumper_geotransolver_oneshot
# Scale the geometry uniformly by 1.10x in raw space (default):
python inference_ood_geometry.py --config-name=bumper_geotransolver_oneshot
```

Override the perturbation factor from the CLI, e.g.
`inference.ood_global_scale=2.0` or `inference.ood_geometry_scale=1.05`.

## Experiments

Each experiment is a self-contained YAML file in `conf/`. Each config file includes all defaults and experiment-specific settings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ defaults:
# └───────────────────────────────────────────┘

training:
raw_data_dir: ??? # set in config or via CLI: training.raw_data_dir=/path/to/train
raw_data_dir: ??? # set in config or via CLI: training.raw_data_dir=/path/to/train
raw_data_dir_validation: ??? # set in config or via CLI: training.raw_data_dir_validation=/path/to/validation
global_features_filepath: ??? # set in config or via CLI: training.global_features_filepath=/path/to/global_features.json
optimizer: muon
Expand Down Expand Up @@ -75,4 +75,12 @@ datapipe:
model:
functional_dim: 3 # coords (3)
out_dim: 250 # (num_time_steps - 1) * 5 = 50 * 5
global_dim: 3 # must match len(datapipe.global_features)
global_dim: 3 # must match len(datapipe.global_features)
# OOD guard (disabled by default — set `guard_config` to a mapping to enable)
guard_config: null
Comment thread
mnabian marked this conversation as resolved.
# Example enabled config:
# guard_config:
# buffer_size: 121 # FIFO buffer size (= num_training_samples)
# knn_k: 10 # k for geometry kNN distance (recommended 5–15)
# sensitivity: 1.5 # threshold = sensitivity * 99th-percentile in-dist
# # kNN distance; >1 is less sensitive, <1 more.
11 changes: 8 additions & 3 deletions physicsnemo/experimental/guardrails/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@

This package provides utilities for detecting out-of-distribution data
and validating inputs to physics-based machine learning models.
"""

from .geometry import GeometryGuardrail
Import individual guardrails from their respective subpackages, e.g.::

from physicsnemo.experimental.guardrails.geometry import GeometryGuardrail
from physicsnemo.experimental.guardrails.embedded import OODGuard

__all__ = ["GeometryGuardrail"]
The top-level namespace intentionally does not re-export guardrail classes so
that importing one subpackage does not force-load the others (some carry
optional dependencies like ``pyvista``).
"""
27 changes: 27 additions & 0 deletions physicsnemo/experimental/guardrails/embedded/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES.
# SPDX-FileCopyrightText: All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Embedded (in-forward) guardrails for PhysicsNemo models.

This submodule provides guardrails that live inside a model's forward pass,
calibrating during training and checking during inference. Contrast with
``physicsnemo.experimental.guardrails.geometry``, which operates on raw mesh
data offline prior to inference.
"""

from .ood_guard import OODGuard, OODGuardConfig

__all__ = ["OODGuard", "OODGuardConfig"]
Loading
Loading