Skip to content
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

Define python level abstraction for a Bundle #5821

Open
4 of 6 tasks
Nic-Ma opened this issue Jan 6, 2023 · 8 comments
Open
4 of 6 tasks

Define python level abstraction for a Bundle #5821

Nic-Ma opened this issue Jan 6, 2023 · 8 comments

Comments

@Nic-Ma
Copy link
Contributor

Nic-Ma commented Jan 6, 2023

Is your feature request related to a problem? Please describe.
Currently, we developed many bundles in the model-zoo repo and developed the ConfigParser to load configs.
But actually we don't have a clear definition about what a Bundle is in the python level.
It would be nice to define the Bundle class to represent a bundle and enable users to follow & define their customized bundle structure, and provide the APIs for other applications to easily load and handle a bundle, like MONAI Label, MONAI FL, etc.
Several draft steps to do:

  • Develop BundleWorkflow interface and implement config-based subclass, so bundle can be implemented with JSON/YAML config or python code, just need to follow the interface.
  • How to expose the CLI entry and args for customized BYOCBundleWorkflow in bundle/scripts/.
  • Update FL monai algo to use new workflow.
  • Update MONAI Label to use new bundle workflow. #6720
  • Add tutorial to show how to develop a new pure python-based bundle.
  • Develop Bundle interface for the whole bundle, mainly about folder structure, files, download, etc.
@Nic-Ma Nic-Ma self-assigned this Jan 6, 2023
@Nic-Ma
Copy link
Contributor Author

Nic-Ma commented Jan 6, 2023

CC @wyli @SachidanandAlle for more discussion.

Thanks.

@wyli wyli added this to the Bundle class [P1 v1.2] milestone Feb 6, 2023
@Nic-Ma Nic-Ma closed this as completed in c696773 Mar 15, 2023
@Nic-Ma Nic-Ma reopened this Mar 16, 2023
Nic-Ma added a commit that referenced this issue Apr 3, 2023
part of #5821 .

### Description

This PR enhanced the bundle CLI entry to support different customized
bundle workflows.

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [ ] New tests added to cover the changes.
- [ ] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [ ] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [ ] In-line docstrings updated.
- [ ] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: Nic Ma <nma@nvidia.com>
Nic-Ma added a commit that referenced this issue Apr 19, 2023
part of #5821 
Fixes #6303 

### Description

This PR simplified the MONAI FL `MonaiAlgo` module to leverage
`BundleWorkflow`.
The main point is to decouple the bundle read / write related logic with
FL module and use predefined required-properties.

### Types of changes
<!--- Put an `x` in all the boxes that apply, and remove the not
applicable items -->
- [x] Non-breaking change (fix or new feature that would not break
existing functionality).
- [ ] Breaking change (fix or new feature that would cause existing
functionality to change).
- [ ] New tests added to cover the changes.
- [ ] Integration tests passed locally by running `./runtests.sh -f -u
--net --coverage`.
- [ ] Quick tests passed locally by running `./runtests.sh --quick
--unittests --disttests`.
- [ ] In-line docstrings updated.
- [ ] Documentation updated, tested `make html` command in the `docs/`
folder.

---------

Signed-off-by: Nic Ma <nma@nvidia.com>
Signed-off-by: monai-bot <monai.miccai2019@gmail.com>
Co-authored-by: Holger Roth <hroth@nvidia.com>
Co-authored-by: monai-bot <monai.miccai2019@gmail.com>
@vikashg
Copy link

vikashg commented Jul 7, 2023

Hi @Nic-Ma
Thanks for starting this post. As I mentioned that we need to think of usability of bundles from 2 different angles

  1. Ease of use from an end-user perspective
  2. Ease of building a MONAI Bundle

From an end-user perspective, if the monai model weights should be available from the python script (as they are for pytorch and keras) without explicitly downloading the model. For example

import torchvision
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection.mask_rcnn import MaskRCNNPredictor

or for keras

base_model = keras.applications.Xception(
    weights="imagenet",  # Load weights pre-trained on ImageNet.
    input_shape=(150, 150, 3),
    include_top=False,
)  # Do not include the ImageNet classifier at the top.

# Freeze the base_model
base_model.trainable = False

It will be nice to have similar interface for MONAI models. As far as I understand and used, we can create a model architecture in the similar way in MONAI, but they are not populated with model weights. We looked at loading torchvision models and fine-tuning their model weights in this pull request last year with @wyli.

So maybe if we can reach a place where we can load the model weights as follows

from monai.model_zoo import brats_tumor_segmentation_model
model = brats_tumor_segmentation_model.load_weights(dataset="Brats_challenge_2020")

At this point, the user might want to query the model I/O for the purposes of fine-tuning. A user should be able to call something like

print("Model Info")
print(model.info)
print("Model I/O Config")
print(model.config.io)

which should produce an output

Model Info
Model Name: Brats Tumor Segmentation Model
Dataset model is trained on: Brats Challenge 20
Last updated date: 3 July 2021
Author: xxxx xxxx

Model I/O Config
Input Shape: [3, 256, 256, 256]
Intensity Range for input: [0, 1]

Output Labels: [4, 256, 256, 256] 
Produces Binary label for each class.

The user should be able to peel the last layer and attach a different layer for fine-tuning purposes.

@surajpaib
Copy link
Contributor

Hi Team,

I would like to add my 2 cents to the issue based on what @vikashg proposed.

We primarily use MONAI for our config parsing (through ConfigParser), network architecture, and transform requirements, coupled with Pytorch Lightning for training. It's been a great experience working with the MONAI library throughout! Our work focuses on primarily building self-supervised models for medical imaging and we have planned to ship our trained models with MONAI bundle and make it compatible with frameworks like MONAI label so these pre-trained models can be used by the larger community.

However, what we would really like is for users to have simplified access to a model-loading interface. The MONAI bundles on model zoo provide a very nice way to ship models for training and inference but I fear users could be a bit challenged by a new interface. Offering a standard torchvision-like interface, in addition to the existing interface, would be amazing.
E.g:

from monai.networks.nets import densenet121
model = densenet121(pretrained="pathology_nuclei_classification") # pretrained / weights 

Where the model now loads pre-trained weights from the pathology_nuclei_classification bundle.

In terms of implementation, I spotted that there is already a load function to get models from bundles.

def load(

Could it be of interest to look at this feature for existing networks in the MONAI library? This way the weights could be loaded for inference (even finetuning, especially in our case as we provide self-supervised models) and users could be pointed toward the full bundle for reproducibility and more advanced use cases. So this would be sort of an easy "entry point" to existing MONAI bundle models.

@surajpaib
Copy link
Contributor

Hi @wyli, do you think something like the above would be of interest?

@wyli
Copy link
Contributor

wyli commented Aug 8, 2023

yes, that's a good point, thanks for the comments @surajpaib, @KumoLiu is designing a new pythonic user experience https://docs.google.com/presentation/d/1z3rVJWX7LMcyTrCH-K9dFehBuEksFj0f8bobmJ-DJPA will let you know when a prototype is ready

@surajpaib
Copy link
Contributor

Thank you very much for sharing this @wyli

This looks very promising @KumoLiu. Let me know if you would like any help with testing

@vikashg vikashg self-assigned this Aug 11, 2023
@KumoLiu
Copy link
Contributor

KumoLiu commented Oct 20, 2023

E.g:
from monai.networks.nets import densenet121
model = densenet121(pretrained="pathology_nuclei_classification") # pretrained / weights
Where the model now loads pre-trained weights from the pathology_nuclei_classification bundle.

Hi @surajpaib, given your comment above, we were able to support getting instantiated nets directly from a bundle in the 1.3 release, which can be used directly in the existing pipeline.

from monai.bundle import load

model = load("pathology_nuclei_classification", bundle_dir="/workspace/", return_state_dict=False)

Feel free to share the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In progress
Development

No branches or pull requests

6 participants