Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 16 additions & 0 deletions apps/impact_reg/impact_reg_konfai/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

"""Python package for the IMPACT-Reg KonfAI app wrapper."""
16 changes: 16 additions & 0 deletions apps/impact_reg/setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

from email import message_from_string
from pathlib import Path

Expand Down
16 changes: 16 additions & 0 deletions apps/impact_seg/impact_seg_konfai/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

"""Python package for the IMPACT-Seg KonfAI app wrapper."""
16 changes: 16 additions & 0 deletions apps/impact_seg/setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

from email import message_from_string
from pathlib import Path

Expand Down
16 changes: 16 additions & 0 deletions apps/impact_synth/impact_synth_konfai/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

"""Python package for the IMPACT-Synth KonfAI app wrapper."""
16 changes: 16 additions & 0 deletions apps/impact_synth/setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

from email import message_from_string
from pathlib import Path

Expand Down
16 changes: 16 additions & 0 deletions apps/mrsegmentator/mrsegmentator_konfai/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

"""Python package for the MRSegmentator KonfAI app wrapper."""
16 changes: 16 additions & 0 deletions apps/mrsegmentator/setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

from email import message_from_string
from pathlib import Path

Expand Down
16 changes: 16 additions & 0 deletions apps/totalsegmentator/setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

from email import message_from_string
from pathlib import Path

Expand Down
16 changes: 16 additions & 0 deletions apps/totalsegmentator/totalsegmentator_konfai/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

"""Python package for the TotalSegmentator KonfAI app wrapper."""
104 changes: 98 additions & 6 deletions docs/source/concepts/yaml-model-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ metadata, optimizer configuration, and loss attachment as Python models.

The segmentation example is defined in `examples/Segmentation/UNet.yml`; its
training and prediction configs load it with `classpath: UNet.yml`. The older
Python `konfai.models.segmentation.UNet` remains available for compatibility.
Python `konfai.models.python.segmentation.UNet` remains available for compatibility.

## Document structure

Expand Down Expand Up @@ -110,14 +110,106 @@ No YAML value is passed to `eval` or used as an import path.

## Registry

Built-ins include dimension-aware `Conv`, `ConvTranspose`, `MaxPool`, and
`AvgPool` factories; explicit `Conv1d`/`Conv2d`/`Conv3d`; `ConvBlock`,
`ResBlock`, `Concat`, `Softmax`, `ArgMax`, and `Identity`.

Call `list_registered_modules()` to inspect the active registry. Applications
Built-ins, grouped:

- **Dimension-aware factories** (pick the 1-D/2-D/3-D variant from `dim`):
`Conv`, `ConvTranspose`, `MaxPool`, `AvgPool`, `AdaptiveAvgPool`, `BatchNorm`,
`InstanceNorm`; explicit `Conv1d`/`Conv2d`/`Conv3d` and `Dropout`/`Dropout1d`/`2d`/`3d`.
- **Normalization / regularization:** `GroupNorm`, `LayerNorm`, `Dropout`.
- **Activations:** `ReLU`, `LeakyReLU`, `PReLU`, `GELU`, `Sigmoid`, `Tanh`, `Softmax`.
- **Linear / shape:** `Linear`, `Flatten`, `Upsample`, `Identity`, `Permute`, `View`,
`Select`, `Unsqueeze`, `ArgMax`.
- **Routing leaves:** `Concat`, `Add`, `Multiply`.
- **Composite blocks:** `ConvBlock`, `ResBlock`, `Attention`.
- **Transformer:** `MultiHeadSelfAttention`, `PositionalEmbedding` (with `LayerNorm`,
`Linear`, `GELU`) — enough to express a ViT encoder.

Call `list_registered_modules()` for the authoritative, up-to-date list. Applications
may add a trusted `torch.nn.Module` subclass with `register_module(name, cls)`.
Duplicate names and non-module classes raise `ConfigError`.

## Shipped model catalog

`konfai/models/` is split by form: `python/` holds the builtin Python model classes
(referenced as `classpath: segmentation.UNet.UNet`), `yaml/` the declarative catalog.
KonfAI ships a catalog of common medical-imaging architectures as declarative YAML
under `konfai/models/yaml/`. Reference one from any config with a `default|` marker —
the declarative counterpart of a Python model classpath:

```yaml
Model:
classpath: default|AttentionUNet.yml
```

Every catalog entry is built from the curated registry (no code execution) and is
locked by a test at the strongest available level — weight-exact graph equivalence
against a reference implementation where one exists, otherwise a structural check
(builds, forward on 2-D and 3-D inputs, correct output shape, deep-supervision heads)
with any divergence from the reference documented in the file header:

| Entry | Validation | Loads pretrained from |
|---|---|---|
| `UNet`, `NestedUNet`, `ResNet` | weight-exact vs their KonfAI Python classes | KonfAI checkpoints |
| `SegResNet`, `VNet`, `DynUNet` | weight-exact vs MONAI | MONAI checkpoints (via the bridge) |
| `ResNet18` | weight-exact vs torchvision ResNet-18 | torchvision ImageNet (via the bridge) |
| `PlainConvUNet` | weight-exact vs nnU-Net `dynamic_network_architectures.PlainConvUNet` | nnU-Net / TotalSegmentator / MRSeg checkpoints (via the bridge) |
| `VGG16` | weight-exact vs torchvision (all 5 feature maps exact) | torchvision ImageNet (via the bridge) |
| `ViT` | structural + encoder token-features allclose vs MONAI | — (encoder maths verified) |
| `AttentionUNet`, `UNETR` | structural-strict (graph differs from MONAI, documented) | — |

`VGG16` is the feature-extractor entry: it exposes five named multi-layer outputs
(`Block_0:Out` … `Block_4:Out`, channels 64/128/256/512/512 — the torchvision
`features` slices `[0:4]/[4:9]/[9:16]/[16:23]/[23:30]`) so a perceptual / feature /
IMPACT-style loss can be attached to any of them through `outputs_criterions`.

The MCP server lists the catalog via `list_components(kind="model")` alongside the
Python model classes.

## Which form should I use?

There are three ways to put a common architecture into a KonfAI config, and they are
not redundant — pick by what you need:

| You want to… | Use | Why |
|---|---|---|
| Train/run the vanilla model as-is, one output, one loss | `classpath: monai.networks.nets:SegResNet` (or any installed class) | KonfAI wraps any `nn.Module` in `MinimalModel` automatically — no rebuild needed. Simplest path. |
| Supervise **internal** layers (deep supervision, feature/perceptual losses), edit the architecture without code, or share it safely | `classpath: default|SegResNet.yml` | The YAML builds a KonfAI `Network` whose every submodule is addressable in `outputs_criterions`, editable in YAML, and safe by construction (registry-only, no imported code). |
| Do the above **and** start from someone's pretrained weights | `default|<Name>.yml` + the pretrained bridge (below) | You get the reference's trained weights inside the addressable KonfAI graph. |

An imported `nn.Module` is a black box: only its final output is visible to KonfAI's
loss/evaluation machinery. The YAML form is what unlocks per-node supervision — that is
the reason to rebuild an architecture rather than import it.

## Loading pretrained weights

A catalog entry that is weight-exact to a reference (e.g. `SegResNet.yml` ↔ MONAI
`SegResNet`) can be loaded from that reference's checkpoint even though the two use
different module names, via `konfai.utils.pretrained.transfer_weights_by_execution_order`.
It pairs the two graphs' weighted leaves in forward-execution order and copies them with
a shape check, so no hand-written key map is needed:

```python
from monai.networks.nets import SegResNet
from konfai.utils.model_builder import build_model_from_yaml
from konfai.utils.pretrained import transfer_weights_by_execution_order

reference = SegResNet(spatial_dims=3, init_filters=8, in_channels=1, out_channels=2,
blocks_down=(1, 2, 2, 4), blocks_up=(1, 1, 1))
reference.load_state_dict(torch.load("segresnet_pretrained.pt")) # your trained checkpoint

net = build_model_from_yaml(yaml_path="konfai/models/yaml/SegResNet.yml",
parameters={"dim": 3, "upsample_mode": "trilinear", "nb_class": 2})
example = torch.randn(1, 1, 16, 16, 16)
transfer_weights_by_execution_order(
target=net, source=reference,
target_forward=lambda: list(net.named_forward(example)),
source_forward=lambda: reference(example),
)
```

The transfer is strict: if the two graphs are not weight-exact (different leaf count or a
mismatched shape) it raises `ConfigError` rather than silently mis-loading a network.

## Configuration example

```yaml
Expand Down
16 changes: 16 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Copyright (c) 2025 Valentin Boussot
#
# 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.
#
# SPDX-License-Identifier: Apache-2.0

import os
import sys
from datetime import datetime
Expand Down
22 changes: 17 additions & 5 deletions docs/source/reference/components/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,19 @@ VoxelMorph, …) are written as Python classes. The registry is deliberately sma
— see {doc}`../../concepts/yaml-model-builder`.
```

## Segmentation — `konfai.models.segmentation`
## Segmentation — `konfai.models.python.segmentation`

`PlainConvUNet` is the parametric nnU-Net backbone (n_stages / features_per_stage /
strides / n_conv_per_stage as real arguments), weight-exact to
`dynamic_network_architectures.PlainConvUNet` for any topology — a real nnU-Net /
TotalSegmentator / MRSeg checkpoint loads into it through the pretrained bridge. Every
decoder resolution has a deep-supervision head as a named output.

`SMP` wraps any `segmentation_models_pytorch` architecture/encoder pair (Unet,
UnetPlusPlus, FPN, DeepLabV3Plus, … × resnet/efficientnet/timm encoders), with
optional ImageNet encoder weights (`encoder_weights: imagenet`) that survive
training start. 2D-only (SMP's encoder zoo is 2D); use slice-wise patches or
2.5D channels on volumes. Requires `pip install konfai[smp]`.

| Model | Classpath | Purpose | Key args (defaults) | Dims | YAML-buildable |
| --- | --- | --- | --- | --- | --- |
Expand All @@ -29,14 +41,14 @@ The `Model:UNetpp5` used in the `Synthesis` example is a **local** class in
built-in `UNetpp` above.
```

## Classification — `konfai.models.classification`
## Classification — `konfai.models.python.classification`

| Model | Classpath | Purpose | Key args (defaults) | Dims | YAML-buildable |
| --- | --- | --- | --- | --- | --- |
| `ResNet` | `classification.resnet.ResNet` | ResNet-18/34/50/101/152 family with torchvision-compatible weight aliases. | `dim=3`, `in_channels=1`, `depths=[2,2,2,2]`, `widths=[64,64,128,256,512]`, `num_classes=10`, `use_bottleneck=False` | 2D / 3D | Yes |
| `ConvNeXt` | `classification.convNeXt.ConvNeXt` | ConvNeXt (tiny→xlarge presets) with a multi-head classifier (`num_classes` is a list). | `dim=3`, `in_channels=1`, `depths=[3,3,27,3]`, `widths=[128,256,512,1024]`, `drop_p=0.1`, `num_classes=[4,7]` | 2D | No (custom `forward`) |

## Generation — `konfai.models.generation`
## Generation — `konfai.models.python.generation`

| Model | Classpath | Purpose | Dims | YAML-buildable |
| --- | --- | --- | --- | --- |
Expand All @@ -47,13 +59,13 @@ built-in `UNetpp` above.
| `DiffusionGan`, `DiffusionGanV2`, `DiffusionCycleGan`, `CycleGan*` | `generation.diffusionGan.*` | Adversarial + diffusion + CycleGAN family. | 2D / 3D | No |
| `cStyleGan.Generator` | `generation.cStyleGan.Generator` | Conditional StyleGAN-style generator with weight-modulated convs. | 2D / 3D | No |

## Registration — `konfai.models.registration`
## Registration — `konfai.models.python.registration`

| Model | Classpath | Purpose | Dims | YAML-buildable |
| --- | --- | --- | --- | --- |
| `VoxelMorph` | `registration.registration.VoxelMorph` | Learning-based deformable/rigid registration (U-Net flow field + spatial-transformer warp + scaling-and-squaring integration). Pass `dim: 2`. | 2D | No |

## Representation — `konfai.models.representation`
## Representation — `konfai.models.python.representation`

| Model | Classpath | Purpose | Dims | YAML-buildable |
| --- | --- | --- | --- | --- |
Expand Down
Loading
Loading