-
Notifications
You must be signed in to change notification settings - Fork 62
MONAISegInferenceOperator Additional Arguments #547
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
MONAISegInferenceOperator Additional Arguments #547
Conversation
Signed-off-by: bluna301 <[email protected]>
|
It is good to add these couple parameters explicitly on the A test example A function to filter out the params in the This function can be called in the init, and the resultant dictionary saved as an attribute, say self._implicit_params. When calling the sliding_window_inference, just need to add |
|
@MMelQin many thanks for your review! Completely agree with all of your suggestions, and appreciate the base filtering function you provided for handling the implicit parameters. I will work on integrating your suggestions into the operator. |
…ce forwarding Signed-off-by: bluna301 <[email protected]>
|
MMelQin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for expanding the support.
|
Hi @MMelQin - sorry to bring this one back up. I was testing with passing in a infer_operator = MonaiSegInferenceOperator(
self.fragment,
roi_size=(96, 96, 96),
pre_transforms=pre_transforms,
post_transforms=post_transforms,
overlap=0.25,
app_context=self.app_context,
model_name="",
inferer=InfererType.SLIDING_WINDOW,
sw_batch_size=1,
mode=BlendModeType.GAUSSIAN,
padding_mode=PytorchPadModeType.REPLICATE,
device=torch.device("cuda" if torch.cuda.is_available() else "cpu"),
model_path=self.model_path
)[error] [gxf_wrapper.cpp:118] Exception occurred for operator: 'ct_totalseg_op' - RuntimeError: python object could not be converted to Arg
At:
/home/bluna301/miniconda3/envs/ct-totalsegmentator/lib/python3.9/site-packages/holoscan/core/__init__.py(389): __init__
/home/bluna301/ct-totalsegmentator-map/my_app/inference_operator.py(26): __init__
/home/bluna301/ct-totalsegmentator-map/my_app/monai_seg_inference_operator.py(190): __init__
/home/bluna301/ct-totalsegmentator-map/my_app/ct_totalseg_operator.py(202): compute
[error] [entity_executor.cpp:596] Failed to tick codelet ct_totalseg_op in entity: ct_totalseg_op code: GXF_FAILURE
[warning] [greedy_scheduler.cpp:243] Error while executing entity 28 named 'ct_totalseg_op': GXF_FAILURE
[info] [greedy_scheduler.cpp:401] Scheduler finished.
[error] [program.cpp:580] wait failed. Deactivating...
[error] [runtime.cpp:1649] Graph wait failed with error: GXF_FAILURE
[warning] [gxf_executor.cpp:2428] GXF call GxfGraphWait(context) in line 2428 of file /workspace/holoscan-sdk/src/core/executors/gxf/gxf_executor.cpp failed with 'GXF_FAILURE' (1)
[info] [gxf_executor.cpp:2438] Graph execution finished.
[error] [gxf_executor.cpp:2446] Graph execution error: GXF_FAILURE
Traceback (most recent call last):
File "/home/bluna301/miniconda3/envs/ct-totalsegmentator/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/home/bluna301/miniconda3/envs/ct-totalsegmentator/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/bluna301/ct-totalsegmentator-map/my_app/__main__.py", line 25, in <module>
CTTotalSegmentatorApp().run()
File "/home/bluna301/ct-totalsegmentator-map/my_app/app.py", line 61, in run
super().run(*args, **kwargs)
File "/home/bluna301/ct-totalsegmentator-map/my_app/ct_totalseg_operator.py", line 202, in compute
infer_operator = MonaiSegInferenceOperator(
File "/home/bluna301/ct-totalsegmentator-map/my_app/monai_seg_inference_operator.py", line 190, in __init__
super().__init__(fragment, *args, **kwargs)
File "/home/bluna301/ct-totalsegmentator-map/my_app/inference_operator.py", line 26, in __init__
super().__init__(fragment, *args, **kwargs)
File "/home/bluna301/miniconda3/envs/ct-totalsegmentator/lib/python3.9/site-packages/holoscan/core/__init__.py", line 389, in __init__
_Operator.__init__(self, self, fragment, *args, **kwargs)
RuntimeError: python object could not be converted to ArgI believe this behavior is due to how Holoscan converts Because we already store the (filtered) kwargs as super().__init__(fragment, *args)If you think this is acceptable, I can commit this fix. Please let me know if you have any concerns about this fix. |
Good catch @bluna301! This is actually a common issue with all the subclass of the base operator due to the failure in py_object_to_arg. I initially also thought we could avoid using I discussed this issue with other Holoscan SDK developers. As of now, there is no built-in attributes or a bool function to check if a type can be converted, and using try/catch with So, this leaves us with the approach to have yet another filer to distill the and on calling super init Also, I needed to add Thanks. |
Signed-off-by: bluna301 <[email protected]>
|
@MMelQin - I updated the PR following your guidance, but made some additional tweaks. Admittedly there are some signficant changes in this commit - I default to you regarding implementing all of these changes. I checked all argument types explicitly defined by
I added the Holoscan conversion filter to the previously defined I noticed that some of the setter type checks (e.g. I updated the existing Lastly, |
|
Thanks @bluna301. I'll be reviewing the changes. Also, I've created a feature enhancement on Holoscan SDK, to support a Python function to test if an arg can be converted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR enhances the MONAISegInferenceOperator to accept additional arguments from MONAI's sliding_window_inference function, specifically mode and padding_mode, to improve alignment between MONAI Bundle and MAP segmentation outputs.
- Adds support for additional sliding window inference parameters via
**kwargs - Implements a filtering mechanism to validate and forward compatible arguments to
sliding_window_inference - Expands explicit parameter support for
sw_device,device, andprocess_fnwith proper type validation
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| monai/deploy/operators/monai_seg_inference_operator.py | Main implementation adding parameter filtering, new explicit parameters, improved type validation, and updated inference calls |
| monai/deploy/core/init.py | Adds Resource import to support expanded parameter types |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
MMelQin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enhancements look good to me. Please see the proposed changes to split kwargs into inference use and for base operator init, which I believe is the simplest ways to separate concerns.
|
@MMelQin thanks for your review - I will work on implementing the changes. If I understand correctly, the filtered SWI implicit params ( # def __init__():
self._filtered_params, self._filtered_base_init_params = self.filter_sw_kwargs(**kwargs) # Filter keyword args
# Pass filtered base init params
super().__init__(fragment, *args, **self._filtered_base_init_params)
# def compute_impl():
d[self._pred_dataset_key] = sliding_window_inference(
**self._filtered_params, # Additional sliding window arguments
)If Let me know if you disagree, but will plan on removing these three explicit params otherwise. |
Yes, I agree with your assessment. |
|
Great, thanks Ming! |
Signed-off-by: bluna301 <[email protected]>
Signed-off-by: bluna301 <[email protected]>
|
MMelQin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the refinement to make it the best it can be.
I have also tested the changes in existing examples successfully. Ready to merge.



When translating the MONAI CT TotalSegmentator MONAI Bundle to a MAP, it was determined that the segmentations produced by the MONAI Bundle and MAP were not exactly aligned (i.e. DICE != 1 for all organs).
This seems to be due to the
MONAISegInferenceOperatornot accepting all the possible arguments that are accepted by the sliding_window_inference method, specificallymodeandpadding_modefor this Bundle. Once a custom operator that accepted these input arguments was implemented into the MAP pipeline, the DICE for all organs was ~=0.99 when comparing to the Bundle.This initial commit includes the logic for accepting and implementing
modeandpadding_modearguments. Happy to discuss further if the additional missingsliding_window_inferencearguments should be added as well.