-
Notifications
You must be signed in to change notification settings - Fork 68
MONet Bundle Integration into MONAI Deploy #574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b7843ec
5441654
a8f5979
7a5ce63
9ab5248
04a081e
655ad66
ea678d4
d8e502d
09b569a
40e6d94
a98d24f
0743b3e
67d24d6
aaa5158
635cd5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,101 @@ | ||||||||||||||||||||||||
| # Copyright 2025 MONAI Consortium | ||||||||||||||||||||||||
| # 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. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| from typing import Any, Dict, Tuple, Union | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| from monai.deploy.core import Image | ||||||||||||||||||||||||
| from monai.deploy.operators.monai_bundle_inference_operator import MonaiBundleInferenceOperator, get_bundle_config | ||||||||||||||||||||||||
| from monai.deploy.utils.importutil import optional_import | ||||||||||||||||||||||||
| from monai.transforms import ConcatItemsd, ResampleToMatch | ||||||||||||||||||||||||
| from monai.deploy.core.models.torch_model import TorchScriptModel | ||||||||||||||||||||||||
| from monai.deploy.core.models.triton_model import TritonModel | ||||||||||||||||||||||||
| torch, _ = optional_import("torch", "1.10.2") | ||||||||||||||||||||||||
| MetaTensor, _ = optional_import("monai.data.meta_tensor", name="MetaTensor") | ||||||||||||||||||||||||
| __all__ = ["MONetBundleInferenceOperator"] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class MONetBundleInferenceOperator(MonaiBundleInferenceOperator): | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
| A specialized operator for performing inference using the MONet bundle (https://github.com/minnelab/MONet-Bundle). | ||||||||||||||||||||||||
| For more details, please refer to the [MONet-Bundle](https://github.com/minnelab/MONet-Bundle) repository. | ||||||||||||||||||||||||
| This operator extends the `MonaiBundleInferenceOperator` to support nnUNet-specific | ||||||||||||||||||||||||
| configurations and prediction logic. It initializes the nnUNet predictor and provides | ||||||||||||||||||||||||
| a method for performing inference on input data. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Attributes | ||||||||||||||||||||||||
| ---------- | ||||||||||||||||||||||||
| _nnunet_predictor : torch.nn.Module | ||||||||||||||||||||||||
| The nnUNet predictor module used for inference. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Methods | ||||||||||||||||||||||||
| ------- | ||||||||||||||||||||||||
| _init_config(config_names) | ||||||||||||||||||||||||
| Initializes the configuration for the nnUNet bundle, including parsing the bundle | ||||||||||||||||||||||||
| configuration and setting up the nnUNet predictor. | ||||||||||||||||||||||||
| predict(data, *args, **kwargs) | ||||||||||||||||||||||||
| Performs inference on the input data using the nnUNet predictor. | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def __init__( | ||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||
| *args, | ||||||||||||||||||||||||
| **kwargs, | ||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| super().__init__(*args, **kwargs) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| self._nnunet_predictor: torch.nn.Module = None | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def _init_config(self, config_names): | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| super()._init_config(config_names) | ||||||||||||||||||||||||
| parser = get_bundle_config(str(self._bundle_path), config_names) | ||||||||||||||||||||||||
| self._parser = parser | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| self._nnunet_predictor = parser.get_parsed_content("network_def") | ||||||||||||||||||||||||
|
Comment on lines
+57
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Double parsing:
If the intent is just to get Proposed fix def _init_config(self, config_names):
super()._init_config(config_names)
- parser = get_bundle_config(str(self._bundle_path), config_names)
- self._parser = parser
-
- self._nnunet_predictor = parser.get_parsed_content("network_def")
+ self._nnunet_predictor = self._parser.get_parsed_content("network_def")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This suggestion from copilot needs review - If the parent class is initializing the model properly, we can accept the suggestion, but I am not sure if get_bundle_config is needed to apply any config patch.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SimoneBendazzoli93 - please review this suggestion above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def _set_model_network(self, model_network): | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
| Sets the model network for the nnUNet predictor. | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Parameters | ||||||||||||||||||||||||
| ---------- | ||||||||||||||||||||||||
| model_network : torch.nn.Module or torch.jit.ScriptModule | ||||||||||||||||||||||||
| The model network to be used for inference. | ||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||
| not isinstance(model_network, torch.nn.Module) | ||||||||||||||||||||||||
| and not isinstance(model_network, torch.jit.ScriptModule) | ||||||||||||||||||||||||
| and not isinstance(model_network, TorchScriptModel) | ||||||||||||||||||||||||
| and not isinstance(model_network, TritonModel) | ||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||
| raise TypeError("model_network must be an instance of torch.nn.Module or torch.jit.ScriptModule") | ||||||||||||||||||||||||
chezhia marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||
| self._nnunet_predictor.predictor.network = model_network | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def predict(self, data: Any, *args, **kwargs) -> Union[Image, Any, Tuple[Any, ...], Dict[Any, Any]]: | ||||||||||||||||||||||||
| """Predicts output using the inferer. If multimodal data is provided as keyword arguments, | ||||||||||||||||||||||||
| it concatenates the data with the main input data.""" | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| self._set_model_network(self._model_network) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if len(kwargs) > 0: | ||||||||||||||||||||||||
| multimodal_data = {"image": data} | ||||||||||||||||||||||||
| for key in kwargs.keys(): | ||||||||||||||||||||||||
| if isinstance(kwargs[key], MetaTensor): | ||||||||||||||||||||||||
| multimodal_data[key] = ResampleToMatch(mode="bilinear")(kwargs[key], img_dst=data) | ||||||||||||||||||||||||
| data = ConcatItemsd(keys=list(multimodal_data.keys()), name="image")(multimodal_data)["image"] | ||||||||||||||||||||||||
|
Comment on lines
+89
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not silently drop non- At Line 92–94, only Proposed fix if len(kwargs) > 0:
multimodal_data = {"image": data}
for key in kwargs.keys():
if isinstance(kwargs[key], MetaTensor):
multimodal_data[key] = ResampleToMatch(mode="bilinear")(kwargs[key], img_dst=data)
+ else:
+ multimodal_data[key] = kwargs[key]
data = ConcatItemsd(keys=list(multimodal_data.keys()), name="image")(multimodal_data)["image"]🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can be ignored There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||
| if len(data.shape) == 4: | ||||||||||||||||||||||||
| data = data[None] | ||||||||||||||||||||||||
| prediction = self._nnunet_predictor(data) | ||||||||||||||||||||||||
| if hasattr(prediction, "meta") and hasattr(data, "meta"): | ||||||||||||||||||||||||
| prediction.meta = data.meta | ||||||||||||||||||||||||
| return prediction | ||||||||||||||||||||||||
| return prediction | ||||||||||||||||||||||||
|
Check warning on line 101 in monai/deploy/operators/monet_bundle_inference_operator.py
|
||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.