Skip to content

Commit b415ca9

Browse files
KumoLiuericspod
andauthored
Update base image to 25.12 (#8738)
Fixes #8585. ### Description Update base image to nvcr.io/nvidia/pytorch:25.12-py3 ### 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: Yun Liu <yunl@nvidia.com> Signed-off-by: YunLiu <55491388+KumoLiu@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
1 parent b106a4c commit b415ca9

File tree

19 files changed

+101
-50
lines changed

19 files changed

+101
-50
lines changed

.github/workflows/pythonapp.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
run: |
3939
find /opt/hostedtoolcache/* -maxdepth 0 ! -name 'Python' -exec rm -rf {} \;
4040
python -m pip install --upgrade pip wheel
41-
python -m pip install -r requirements-dev.txt
41+
python -m pip install --no-build-isolation -r requirements-dev.txt
4242
- name: Lint and type check
4343
run: |
4444
# clean up temporary files
@@ -85,7 +85,7 @@ jobs:
8585
python -m pip install --user --upgrade pip wheel
8686
python -m pip install torch==2.5.1 torchvision==0.20.1
8787
cat "requirements-dev.txt"
88-
python -m pip install -r requirements-dev.txt
88+
python -m pip install --no-build-isolation -r requirements-dev.txt
8989
python -m pip list
9090
python setup.py develop # test no compile installation
9191
shell: bash
@@ -174,7 +174,7 @@ jobs:
174174
cp ${{ steps.root.outputs.pwd }}/requirements*.txt .
175175
cp -r ${{ steps.root.outputs.pwd }}/tests .
176176
ls -al
177-
python -m pip install -r requirements-dev.txt --extra-index-url https://download.pytorch.org/whl/cpu
177+
python -m pip install --no-build-isolation -r requirements-dev.txt --extra-index-url https://download.pytorch.org/whl/cpu
178178
python -m unittest -v
179179
env:
180180
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION: python # https://github.com/Project-MONAI/MONAI/issues/4354

Dockerfile

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
# To build with a different base image
1313
# please run `docker build` using the `--build-arg PYTORCH_IMAGE=...` flag.
14-
ARG PYTORCH_IMAGE=nvcr.io/nvidia/pytorch:24.10-py3
14+
ARG PYTORCH_IMAGE=nvcr.io/nvidia/pytorch:25.12-py3
1515
FROM ${PYTORCH_IMAGE}
1616

1717
LABEL maintainer="monai.contact@gmail.com"
@@ -42,9 +42,6 @@ COPY LICENSE CHANGELOG.md CODE_OF_CONDUCT.md CONTRIBUTING.md README.md versionee
4242
COPY tests ./tests
4343
COPY monai ./monai
4444

45-
# TODO: remove this line and torch.patch for 24.11
46-
RUN patch -R -d /usr/local/lib/python3.10/dist-packages/torch/onnx/ < ./monai/torch.patch
47-
4845
RUN BUILD_MONAI=1 FORCE_CUDA=1 python setup.py develop \
4946
&& rm -rf build __pycache__
5047

monai/apps/detection/networks/retinanet_network.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ def forward(self, x: list[Tensor]) -> list[Tensor]:
125125

126126
cls_logits_maps.append(cls_logits)
127127

128-
if torch.isnan(cls_logits).any() or torch.isinf(cls_logits).any():
129-
if torch.is_grad_enabled():
130-
raise ValueError("cls_logits is NaN or Inf.")
131-
else:
132-
warnings.warn("cls_logits is NaN or Inf.")
128+
if not torch.compiler.is_compiling():
129+
if torch.isnan(cls_logits).any() or torch.isinf(cls_logits).any():
130+
if torch.is_grad_enabled():
131+
raise ValueError("cls_logits is NaN or Inf.")
132+
else:
133+
warnings.warn("cls_logits is NaN or Inf.")
133134

134135
return cls_logits_maps
135136

@@ -197,11 +198,12 @@ def forward(self, x: list[Tensor]) -> list[Tensor]:
197198

198199
box_regression_maps.append(box_regression)
199200

200-
if torch.isnan(box_regression).any() or torch.isinf(box_regression).any():
201-
if torch.is_grad_enabled():
202-
raise ValueError("box_regression is NaN or Inf.")
203-
else:
204-
warnings.warn("box_regression is NaN or Inf.")
201+
if not torch.compiler.is_compiling():
202+
if torch.isnan(box_regression).any() or torch.isinf(box_regression).any():
203+
if torch.is_grad_enabled():
204+
raise ValueError("box_regression is NaN or Inf.")
205+
else:
206+
warnings.warn("box_regression is NaN or Inf.")
205207

206208
return box_regression_maps
207209

monai/networks/nets/transchex.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,23 @@ def __init__(
226226
self.mixed_encoder = nn.ModuleList([BertMixedLayer(self.config) for _ in range(num_mixed_layers)])
227227
self.apply(self.init_bert_weights)
228228

229+
@staticmethod
230+
def _get_hidden_states(layer_output):
231+
"""Extract hidden states from BertLayer output.
232+
233+
Compatible with both older transformers (returns a tuple) and
234+
newer transformers >=5.0 (may return a tensor directly).
235+
"""
236+
if isinstance(layer_output, torch.Tensor):
237+
return layer_output
238+
return layer_output[0]
239+
229240
def forward(self, input_ids, token_type_ids=None, vision_feats=None, attention_mask=None):
230241
language_features = self.embeddings(input_ids, token_type_ids)
231242
for layer in self.vision_encoder:
232-
vision_feats = layer(vision_feats, None)[0]
243+
vision_feats = self._get_hidden_states(layer(vision_feats, None))
233244
for layer in self.language_encoder:
234-
language_features = layer(language_features, attention_mask)[0]
245+
language_features = self._get_hidden_states(layer(language_features, attention_mask))
235246
for layer in self.mixed_encoder:
236247
language_features, vision_feats = layer(language_features, vision_feats)
237248
return language_features, vision_feats

monai/networks/trt_compiler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939

4040
trt, trt_imported = optional_import("tensorrt")
4141
torch_tensorrt, _ = optional_import("torch_tensorrt", "1.4.0")
42-
cudart, _ = optional_import("cuda.cudart")
42+
cudart, _cudart_imported = optional_import("cuda.bindings.runtime")
43+
if not _cudart_imported:
44+
cudart, _cudart_imported = optional_import("cuda.cudart")
4345

4446

4547
lock_sm = threading.Lock()

monai/networks/utils.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,16 @@ def convert_to_onnx(
719719
torch_versioned_kwargs["verify"] = verify
720720
verify = False
721721
else:
722-
mode_to_export = torch.jit.script(model, **kwargs)
722+
# The dynamo-based ONNX exporter (torch.export) does not support ScriptModule.
723+
# PyTorch 2.6–2.8: dynamo is available but NOT the default; TorchScript exporter
724+
# remains the default, so we must still script the model here.
725+
# PyTorch 2.9+: dynamo became the default exporter for torch.onnx.export;
726+
# pass the raw nn.Module directly—the exporter handles it via torch.export.
727+
_pt_major_minor = tuple(int(x) for x in torch.__version__.split("+")[0].split(".")[:2])
728+
if _pt_major_minor >= (2, 9):
729+
mode_to_export = model
730+
else:
731+
mode_to_export = torch.jit.script(model, **kwargs)
723732

724733
if torch.is_tensor(inputs) or isinstance(inputs, dict):
725734
onnx_inputs = (inputs,)
@@ -731,7 +740,6 @@ def convert_to_onnx(
731740
f = temp_file.name
732741
else:
733742
f = filename
734-
print(f"torch_versioned_kwargs={torch_versioned_kwargs}")
735743
torch.onnx.export(
736744
mode_to_export,
737745
onnx_inputs,

monai/transforms/signal/array.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def __call__(self, signal: np.ndarray) -> Any:
414414
b_notch, a_notch = convert_to_tensor(
415415
iirnotch(self.frequency, self.quality_factor, self.sampling_freq), dtype=torch.float
416416
)
417-
y_notched = filtfilt(convert_to_tensor(signal), a_notch, b_notch)
417+
y_notched = filtfilt(convert_to_tensor(signal, dtype=torch.float), a_notch, b_notch)
418418

419419
return y_notched
420420

monai/utils/misc.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,12 @@ def run_cmd(cmd_list: list[str], **kwargs: Any) -> subprocess.CompletedProcess:
879879
a CompletedProcess instance after the command completes.
880880
"""
881881
debug = MONAIEnvVars.debug()
882-
kwargs["capture_output"] = kwargs.get("capture_output", debug)
882+
# Always capture output when check=True so that error details are available
883+
# in the CalledProcessError exception for debugging subprocess failures.
884+
if kwargs.get("check", False):
885+
kwargs.setdefault("capture_output", True)
886+
else:
887+
kwargs["capture_output"] = kwargs.get("capture_output", debug)
883888

884889
if kwargs.pop("run_cmd_verbose", False):
885890
import monai
@@ -888,11 +893,9 @@ def run_cmd(cmd_list: list[str], **kwargs: Any) -> subprocess.CompletedProcess:
888893
try:
889894
return subprocess.run(cmd_list, **kwargs)
890895
except subprocess.CalledProcessError as e:
891-
if not debug:
892-
raise
893-
output = str(e.stdout.decode(errors="replace"))
894-
errors = str(e.stderr.decode(errors="replace"))
895-
raise RuntimeError(f"subprocess call error {e.returncode}: {errors}, {output}.") from e
896+
output = str(e.stdout.decode(errors="replace")) if e.stdout else ""
897+
errors = str(e.stderr.decode(errors="replace")) if e.stderr else ""
898+
raise RuntimeError(f"subprocess call error {e.returncode}: {errors}, {output}") from e
896899

897900

898901
def is_sqrt(num: Sequence[int] | int) -> bool:

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ optuna
5353
git+https://github.com/Project-MONAI/MetricsReloaded@monai-support#egg=MetricsReloaded
5454
onnx>=1.13.0
5555
onnxscript
56-
onnxruntime; python_version <= '3.10'
56+
onnxruntime
5757
typeguard<3 # https://github.com/microsoft/nni/issues/5457
5858
filelock<3.12.0 # https://github.com/microsoft/nni/issues/5523
5959
zarr

runtests.sh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function print_usage {
7373
echo "./runtests.sh -f # run coding style and static type checking."
7474
echo "./runtests.sh --quick --unittests # run minimal unit tests, for quick verification during code developments."
7575
echo "./runtests.sh --autofix # run automatic code formatting using \"isort\" and \"black\"."
76-
echo "./runtests.sh --clean # clean up temporary files and run \"${PY_EXE} setup.py develop --uninstall\"."
76+
echo "./runtests.sh --clean # clean up temporary files and run \"${PY_EXE} -m pip uninstall -y monai\"."
7777
echo "./runtests.sh --formatfix -p /my/code # run automatic code formatting using \"isort\" and \"black\" in specified path."
7878
echo ""
7979
echo "Code style check options:"
@@ -143,7 +143,7 @@ function compile_cpp {
143143
echo "Compiling and installing MONAI cpp extensions..."
144144
# depends on setup.py behaviour for building
145145
# currently setup.py uses environment variables: BUILD_MONAI and FORCE_CUDA
146-
${cmdPrefix}"${PY_EXE}" setup.py develop --user --uninstall
146+
${cmdPrefix}"${PY_EXE}" -m pip uninstall -y monai
147147
if [[ "$OSTYPE" == "darwin"* ]];
148148
then # clang for mac os
149149
CC=clang CXX=clang++ ${cmdPrefix}"${PY_EXE}" setup.py develop --user
@@ -179,7 +179,7 @@ function clean_py {
179179

180180
# uninstall the development package
181181
echo "Uninstalling MONAI development files..."
182-
${cmdPrefix}"${PY_EXE}" setup.py develop --user --uninstall
182+
${cmdPrefix}"${PY_EXE}" -m pip uninstall -y monai
183183

184184
# remove temporary files (in the directory of this script)
185185
TO_CLEAN="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
@@ -716,11 +716,13 @@ fi
716716
# fi
717717

718718
# unit tests
719+
# TODO: temp skip test_perceptual_loss, revert after #8652 merged
720+
# TODO: temp skip test_auto3dseg_ensemble, revert after #8737 resolved
719721
if [ $doUnitTests = true ]
720722
then
721723
echo "${separator}${blue}unittests${noColor}"
722724
torch_validate
723-
${cmdPrefix}${cmd} ./tests/runner.py -p "^(?!test_integration).*(?<!_dist)$" # excluding integration/dist tests
725+
${cmdPrefix}${cmd} ./tests/runner.py -p "^(?!test_integration|test_perceptual_loss|test_auto3dseg_ensemble).*(?<!_dist)$" # excluding integration/dist/perceptual_loss tests
724726
fi
725727

726728
# distributed test only

0 commit comments

Comments
 (0)