Skip to content

Commit

Permalink
Merge branch 'Project-MONAI:dev' into fix-6840
Browse files Browse the repository at this point in the history
  • Loading branch information
slicepaste authored Mar 6, 2025
2 parents 8b7463d + 2e391c8 commit 5da7c66
Show file tree
Hide file tree
Showing 37 changed files with 671 additions and 148 deletions.
10 changes: 3 additions & 7 deletions .github/workflows/cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,13 @@ jobs:
strategy:
matrix:
environment:
- "PT113+CUDA118"
- "PT210+CUDA121"
- "PT230+CUDA121"
- "PT240+CUDA126"
- "PTLATEST+CUDA126"
include:
# https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes
- environment: PT113+CUDA118
pytorch: "torch==1.13.1 torchvision==0.14.1 --extra-index-url https://download.pytorch.org/whl/cu121"
base: "nvcr.io/nvidia/pytorch:22.10-py3" # CUDA 11.8
- environment: PT210+CUDA121
pytorch: "pytorch==2.1.0 torchvision==0.16.0 --extra-index-url https://download.pytorch.org/whl/cu121"
- environment: PT230+CUDA121
pytorch: "pytorch==2.3.0 torchvision==0.18.0 --extra-index-url https://download.pytorch.org/whl/cu121"
base: "nvcr.io/nvidia/pytorch:23.08-py3" # CUDA 12.1
- environment: PT240+CUDA126
pytorch: "pytorch==2.4.0 torchvision==0.19.0 --extra-index-url https://download.pytorch.org/whl/cu121"
Expand Down
26 changes: 14 additions & 12 deletions .github/workflows/pythonapp-gpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ jobs:
strategy:
matrix:
environment:
- "PT113+CUDA116"
- "PT210+CUDA121DOCKER"
- "PT230+CUDA124DOCKER"
- "PT240+CUDA125DOCKER"
- "PT250+CUDA126DOCKER"
include:
# https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes
- environment: PT113+CUDA116
pytorch: "torch==1.13.1 torchvision==0.14.1"
base: "nvcr.io/nvidia/cuda:11.6.1-devel-ubuntu18.04"
- environment: PT210+CUDA121DOCKER
# 23.08: 2.1.0a0+29c30b1
- environment: PT230+CUDA124DOCKER
# 24.04: 2.3.0a0+6ddf5cf85e
pytorch: "-h" # we explicitly set pytorch to -h to avoid pip install error
base: "nvcr.io/nvidia/pytorch:23.08-py3"
- environment: PT210+CUDA121DOCKER
# 24.08: 2.3.0a0+40ec155e58.nv24.3
base: "nvcr.io/nvidia/pytorch:24.04-py3"
- environment: PT240+CUDA125DOCKER
# 24.06: 2.4.0a0+f70bd71a48
pytorch: "-h" # we explicitly set pytorch to -h to avoid pip install error
base: "nvcr.io/nvidia/pytorch:24.06-py3"
- environment: PT250+CUDA126DOCKER
# 24.08: 2.5.0a0+872d972e41
pytorch: "-h" # we explicitly set pytorch to -h to avoid pip install error
base: "nvcr.io/nvidia/pytorch:24.08-py3"
container:
Expand All @@ -49,7 +51,7 @@ jobs:
apt-get update
apt-get install -y wget
if [ ${{ matrix.environment }} = "PT113+CUDA116" ]
if [ ${{ matrix.environment }} = "PT230+CUDA124" ]
then
PYVER=3.9 PYSFX=3 DISTUTILS=python3-distutils && \
apt-get update && apt-get install -y --no-install-recommends \
Expand Down Expand Up @@ -114,7 +116,7 @@ jobs:
# build for the current self-hosted CI Tesla V100
BUILD_MONAI=1 TORCH_CUDA_ARCH_LIST="7.0" ./runtests.sh --build --disttests
./runtests.sh --quick --unittests
if [ ${{ matrix.environment }} = "PT113+CUDA116" ]; then
if [ ${{ matrix.environment }} = "PT230+CUDA124" ]; then
# test the clang-format tool downloading once
coverage run -m tests.clang_format_utils
fi
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp-min.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ jobs:
strategy:
fail-fast: false
matrix:
pytorch-version: ['1.13.1', '2.0.1', '2.2.2', '2.3.1', '2.4.1', 'latest']
pytorch-version: ['2.3.1', '2.4.1', '2.5.1', 'latest']
timeout-minutes: 40
steps:
- uses: actions/checkout@v4
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
- if: runner.os == 'windows'
name: Install torch cpu from pytorch.org (Windows only)
run: |
python -m pip install torch==1.13.1+cpu torchvision==0.14.1+cpu -f https://download.pytorch.org/whl/torch_stable.html
python -m pip install torch==2.4.1 torchvision==0.19.1+cpu --index-url https://download.pytorch.org/whl/cpu
- if: runner.os == 'Linux'
name: Install itk pre-release (Linux only)
run: |
Expand All @@ -103,7 +103,7 @@ jobs:
- name: Install the dependencies
run: |
python -m pip install --user --upgrade pip wheel
python -m pip install torch==1.13.1 torchvision==0.14.1
python -m pip install torch==2.4.1 torchvision==0.19.1
cat "requirements-dev.txt"
python -m pip install -r requirements-dev.txt
python -m pip list
Expand Down Expand Up @@ -155,7 +155,7 @@ jobs:
# install the latest pytorch for testing
# however, "pip install monai*.tar.gz" will build cpp/cuda with an isolated
# fresh torch installation according to pyproject.toml
python -m pip install torch>=1.13.1 torchvision
python -m pip install torch>=2.3.0 torchvision
- name: Check packages
run: |
pip uninstall monai
Expand Down
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@

MONAI is a [PyTorch](https://pytorch.org/)-based, [open-source](https://github.com/Project-MONAI/MONAI/blob/dev/LICENSE) framework for deep learning in healthcare imaging, part of the [PyTorch Ecosystem](https://pytorch.org/ecosystem/).
Its ambitions are as follows:

- Developing a community of academic, industrial and clinical researchers collaborating on a common foundation;
- Creating state-of-the-art, end-to-end training workflows for healthcare imaging;
- Providing researchers with the optimized and standardized way to create and evaluate deep learning models.


## Features

> _Please see [the technical highlights](https://docs.monai.io/en/latest/highlights.html) and [What's New](https://docs.monai.io/en/latest/whatsnew.html) of the milestone releases._
- flexible pre-processing for multi-dimensional medical imaging data;
Expand All @@ -32,7 +33,6 @@ Its ambitions are as follows:
- customizable design for varying user expertise;
- multi-GPU multi-node data parallelism support.


## Installation

To install [the current release](https://pypi.org/project/monai/), you can simply run:
Expand All @@ -53,30 +53,34 @@ Technical documentation is available at [docs.monai.io](https://docs.monai.io).

## Citation

If you have used MONAI in your research, please cite us! The citation can be exported from: https://arxiv.org/abs/2211.02701.
If you have used MONAI in your research, please cite us! The citation can be exported from: <https://arxiv.org/abs/2211.02701>.

## Model Zoo

[The MONAI Model Zoo](https://github.com/Project-MONAI/model-zoo) is a place for researchers and data scientists to share the latest and great models from the community.
Utilizing [the MONAI Bundle format](https://docs.monai.io/en/latest/bundle_intro.html) makes it easy to [get started](https://github.com/Project-MONAI/tutorials/tree/main/model_zoo) building workflows with MONAI.

## Contributing

For guidance on making a contribution to MONAI, see the [contributing guidelines](https://github.com/Project-MONAI/MONAI/blob/dev/CONTRIBUTING.md).

## Community

Join the conversation on Twitter/X [@ProjectMONAI](https://twitter.com/ProjectMONAI) or join our [Slack channel](https://forms.gle/QTxJq3hFictp31UM9).

Ask and answer questions over on [MONAI's GitHub Discussions tab](https://github.com/Project-MONAI/MONAI/discussions).

## Links
- Website: https://monai.io/
- API documentation (milestone): https://docs.monai.io/
- API documentation (latest dev): https://docs.monai.io/en/latest/
- Code: https://github.com/Project-MONAI/MONAI
- Project tracker: https://github.com/Project-MONAI/MONAI/projects
- Issue tracker: https://github.com/Project-MONAI/MONAI/issues
- Wiki: https://github.com/Project-MONAI/MONAI/wiki
- Test status: https://github.com/Project-MONAI/MONAI/actions
- PyPI package: https://pypi.org/project/monai/
- conda-forge: https://anaconda.org/conda-forge/monai
- Weekly previews: https://pypi.org/project/monai-weekly/
- Docker Hub: https://hub.docker.com/r/projectmonai/monai

- Website: <https://monai.io/>
- API documentation (milestone): <https://docs.monai.io/>
- API documentation (latest dev): <https://docs.monai.io/en/latest/>
- Code: <https://github.com/Project-MONAI/MONAI>
- Project tracker: <https://github.com/Project-MONAI/MONAI/projects>
- Issue tracker: <https://github.com/Project-MONAI/MONAI/issues>
- Wiki: <https://github.com/Project-MONAI/MONAI/wiki>
- Test status: <https://github.com/Project-MONAI/MONAI/actions>
- PyPI package: <https://pypi.org/project/monai/>
- conda-forge: <https://anaconda.org/conda-forge/monai>
- Weekly previews: <https://pypi.org/project/monai-weekly/>
- Docker Hub: <https://hub.docker.com/r/projectmonai/monai>
4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-f https://download.pytorch.org/whl/cpu/torch-1.13.1%2Bcpu-cp39-cp39-linux_x86_64.whl
torch>=1.13.1
-f https://download.pytorch.org/whl/cpu/torch-2.3.0%2Bcpu-cp39-cp39-linux_x86_64.whl
torch>=2.3.0
pytorch-ignite==0.4.11
numpy>=1.20
itk>=5.2
Expand Down
6 changes: 6 additions & 0 deletions docs/source/handlers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ ROC AUC metrics handler
:members:


Average Precision metric handler
--------------------------------
.. autoclass:: AveragePrecision
:members:


Confusion matrix metrics handler
--------------------------------
.. autoclass:: ConfusionMatrix
Expand Down
7 changes: 7 additions & 0 deletions docs/source/metrics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ Metrics
.. autoclass:: ROCAUCMetric
:members:

`Average Precision`
-------------------
.. autofunction:: compute_average_precision

.. autoclass:: AveragePrecisionMetric
:members:

`Confusion matrix`
------------------
.. autofunction:: get_confusion_matrix
Expand Down
4 changes: 2 additions & 2 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ channels:
- nvidia
- conda-forge
dependencies:
- numpy>=1.24,<2.0
- pytorch>=1.13.1
- numpy>=1.24,<3.0
- pytorch>=2.3.0
- torchio
- torchvision
- pytorch-cuda>=11.6
Expand Down
55 changes: 39 additions & 16 deletions monai/bundle/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import json
import os
import re
import urllib
import warnings
import zipfile
from collections.abc import Mapping, Sequence
Expand Down Expand Up @@ -58,7 +59,7 @@
validate, _ = optional_import("jsonschema", name="validate")
ValidationError, _ = optional_import("jsonschema.exceptions", name="ValidationError")
Checkpoint, has_ignite = optional_import("ignite.handlers", IgniteInfo.OPT_IMPORT_VERSION, min_version, "Checkpoint")
requests_get, has_requests = optional_import("requests", name="get")
requests, has_requests = optional_import("requests")
onnx, _ = optional_import("onnx")
huggingface_hub, _ = optional_import("huggingface_hub")

Expand Down Expand Up @@ -206,6 +207,16 @@ def _download_from_monaihosting(download_path: Path, filename: str, version: str
extractall(filepath=filepath, output_dir=download_path, has_base=True)


def _download_from_bundle_info(download_path: Path, filename: str, version: str, progress: bool) -> None:
bundle_info = get_bundle_info(bundle_name=filename, version=version)
if not bundle_info:
raise ValueError(f"Bundle info not found for {filename} v{version}.")
url = bundle_info["browser_download_url"]
filepath = download_path / f"{filename}_v{version}.zip"
download_url(url=url, filepath=filepath, hash_val=None, progress=progress)
extractall(filepath=filepath, output_dir=download_path, has_base=True)


def _add_ngc_prefix(name: str, prefix: str = "monai_") -> str:
if name.startswith(prefix):
return name
Expand All @@ -222,7 +233,7 @@ def _get_all_download_files(request_url: str, headers: dict | None = None) -> li
if not has_requests:
raise ValueError("requests package is required, please install it.")
headers = {} if headers is None else headers
response = requests_get(request_url, headers=headers)
response = requests.get(request_url, headers=headers)
response.raise_for_status()
model_info = json.loads(response.text)

Expand Down Expand Up @@ -266,7 +277,7 @@ def _download_from_ngc_private(
request_url = _get_ngc_private_bundle_url(model_name=filename, version=version, repo=repo)
if has_requests:
headers = {} if headers is None else headers
response = requests_get(request_url, headers=headers)
response = requests.get(request_url, headers=headers)
response.raise_for_status()
else:
raise ValueError("NGC API requires requests package. Please install it.")
Expand All @@ -289,7 +300,7 @@ def _get_ngc_token(api_key, retry=0):
url = "https://authn.nvidia.com/token?service=ngc"
headers = {"Accept": "application/json", "Authorization": "ApiKey " + api_key}
if has_requests:
response = requests_get(url, headers=headers)
response = requests.get(url, headers=headers)
if not response.ok:
# retry 3 times, if failed, raise an error.
if retry < 3:
Expand All @@ -303,14 +314,17 @@ def _get_ngc_token(api_key, retry=0):

def _get_latest_bundle_version_monaihosting(name):
full_url = f"{MONAI_HOSTING_BASE_URL}/{name.lower()}"
requests_get, has_requests = optional_import("requests", name="get")
if has_requests:
resp = requests_get(full_url)
resp.raise_for_status()
else:
raise ValueError("NGC API requires requests package. Please install it.")
model_info = json.loads(resp.text)
return model_info["model"]["latestVersionIdStr"]
resp = requests.get(full_url)
try:
resp.raise_for_status()
model_info = json.loads(resp.text)
return model_info["model"]["latestVersionIdStr"]
except requests.exceptions.HTTPError:
# for monaihosting bundles, if cannot find the version, get from model zoo model_info.json
return get_bundle_versions(name)["latest_version"]

raise ValueError("NGC API requires requests package. Please install it.")


def _examine_monai_version(monai_version: str) -> tuple[bool, str]:
Expand Down Expand Up @@ -388,14 +402,14 @@ def _get_latest_bundle_version_ngc(name: str, repo: str | None = None, headers:
version_header = {"Accept-Encoding": "gzip, deflate"} # Excluding 'zstd' to fit NGC requirements
if headers:
version_header.update(headers)
resp = requests_get(version_endpoint, headers=version_header)
resp = requests.get(version_endpoint, headers=version_header)
resp.raise_for_status()
model_info = json.loads(resp.text)
latest_versions = _list_latest_versions(model_info)

for version in latest_versions:
file_endpoint = base_url + f"/{name.lower()}/versions/{version}/files/configs/metadata.json"
resp = requests_get(file_endpoint, headers=headers)
resp = requests.get(file_endpoint, headers=headers)
metadata = json.loads(resp.text)
resp.raise_for_status()
# if the package version is not available or the model is compatible with the package version
Expand Down Expand Up @@ -585,7 +599,16 @@ def download(
name_ver = "_v".join([name_, version_]) if version_ is not None else name_
_download_from_github(repo=repo_, download_path=bundle_dir_, filename=name_ver, progress=progress_)
elif source_ == "monaihosting":
_download_from_monaihosting(download_path=bundle_dir_, filename=name_, version=version_, progress=progress_)
try:
_download_from_monaihosting(
download_path=bundle_dir_, filename=name_, version=version_, progress=progress_
)
except urllib.error.HTTPError:
# for monaihosting bundles, if cannot download from default host, download according to bundle_info
_download_from_bundle_info(
download_path=bundle_dir_, filename=name_, version=version_, progress=progress_
)

elif source_ == "ngc":
_download_from_ngc(
download_path=bundle_dir_,
Expand Down Expand Up @@ -792,9 +815,9 @@ def _get_all_bundles_info(

if auth_token is not None:
headers = {"Authorization": f"Bearer {auth_token}"}
resp = requests_get(request_url, headers=headers)
resp = requests.get(request_url, headers=headers)
else:
resp = requests_get(request_url)
resp = requests.get(request_url)
resp.raise_for_status()
else:
raise ValueError("requests package is required, please install it.")
Expand Down
11 changes: 3 additions & 8 deletions monai/engines/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from monai.utils import ForwardMode, IgniteInfo, ensure_tuple, min_version, optional_import
from monai.utils.enums import CommonKeys as Keys
from monai.utils.enums import EngineStatsKeys as ESKeys
from monai.utils.module import look_up_option, pytorch_after
from monai.utils.module import look_up_option

if TYPE_CHECKING:
from ignite.engine import Engine, EventEnum
Expand Down Expand Up @@ -269,13 +269,8 @@ def __init__(
amp_kwargs=amp_kwargs,
)
if compile:
if pytorch_after(2, 1):
compile_kwargs = {} if compile_kwargs is None else compile_kwargs
network = torch.compile(network, **compile_kwargs) # type: ignore[assignment]
else:
warnings.warn(
"Network compilation (compile=True) not supported for Pytorch versions before 2.1, no compilation done"
)
compile_kwargs = {} if compile_kwargs is None else compile_kwargs
network = torch.compile(network, **compile_kwargs) # type: ignore[assignment]
self.network = network
self.compile = compile
self.inferer = SimpleInferer() if inferer is None else inferer
Expand Down
Loading

0 comments on commit 5da7c66

Please sign in to comment.