Skip to content

Introduce itk_infer command#71

Merged
MGAMZ merged 2 commits into
mainfrom
dev/fix-testpypi
Jan 26, 2026
Merged

Introduce itk_infer command#71
MGAMZ merged 2 commits into
mainfrom
dev/fix-testpypi

Conversation

@MGAMZ
Copy link
Copy Markdown
Owner

@MGAMZ MGAMZ commented Jan 26, 2026

itk_infer is a CLI entry to inference samples using OneDL-MMEngine backend or ONNX backend.

Also contains modification on the deployment of pre-release to TestPyPI


📚 Documentation preview 📚: https://ITKIT--71.org.readthedocs.build/en/71/

@MGAMZ MGAMZ self-assigned this Jan 26, 2026
Copilot AI review requested due to automatic review settings January 26, 2026 14:36
@MGAMZ MGAMZ added the process itkit.process module label Jan 26, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 introduces a new CLI command itk_infer for batch inference on 3D medical images using either MMEngine or ONNX backends. The implementation includes sliding window inference support, multi-GPU processing, confidence scoring, and optional logits saving.

Changes:

  • Added new itk_infer CLI command for batch inference with MMEngine and ONNX backend support
  • Incremented package version from 4.0.0rc3 to 4.0.0rc4
  • Added verbose output to TestPyPI publishing workflow for better debugging

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
pyproject.toml Version bump to 4.0.0rc4 and added entry point for itk_infer command
mkdocs.yml Added documentation link for itk_infer in navigation menu
itkit/process/itk_infer.py Complete implementation of batch inference tool with multi-processing support
docs/itk_infer.md Comprehensive documentation covering usage, backends, parameters, and examples
docs/index.md Added itk_infer to command-line tools list in main documentation page
.github/workflows/publish-to-pypi.yml Added verbose flag to TestPyPI publishing step

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

confidence = calc_classwise_pred_confidence(pred_seg_logits) # (N,)
pred_confidences[file.stem] = confidence[0].cpu().item()

# Save segmentation logits as .npz
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect comment. The comment says "Save segmentation logits as .npz" but the code actually saves them as .zarr files (line 177). Update the comment to reflect the actual file format.

Suggested change
# Save segmentation logits as .npz
# Save segmentation logits as Zarr (.zarr)

Copilot uses AI. Check for mistakes.
return tasks


def set_window(image_array:np.ndarray, wl:int, ww:int) -> np.ndarray:
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing spaces after colons in type annotations. Should be wl: int, ww: int instead of wl:int, ww:int to follow PEP 8 style guidelines and be consistent with the rest of the codebase.

Suggested change
def set_window(image_array:np.ndarray, wl:int, ww:int) -> np.ndarray:
def set_window(image_array: np.ndarray, wl: int, ww: int) -> np.ndarray:

Copilot uses AI. Check for mistakes.
Returns:
confidence (Tensor): Tensor with shape (N,) representing the mean confidence across all classes.
"""
assert (C:=seg_logits.size(1)) >= 2, f"Number of classes must be at least 2, got {C}."
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing spaces around walrus operator. Should be C := seg_logits.size(1) instead of C:=seg_logits.size(1) to follow PEP 8 style guidelines and be consistent with the rest of the codebase (e.g., itkit/process/itk_patch.py:186).

Suggested change
assert (C:=seg_logits.size(1)) >= 2, f"Number of classes must be at least 2, got {C}."
assert (C := seg_logits.size(1)) >= 2, f"Number of classes must be at least 2, got {C}."

Copilot uses AI. Check for mistakes.
p = mp.get_context('spawn').Process(
target = process_gpu_task,
args = (process_id, file_list, args, pred_conf_shared_dict),
daemon = True
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting daemon=True for worker processes is problematic because daemon processes are forcibly terminated when the parent exits and cannot spawn child processes. Since the code already calls p.join() on line 265 to wait for all processes to complete, the daemon flag is unnecessary and could lead to incomplete file writes or data corruption if the parent process is interrupted. Remove the daemon=True parameter.

Suggested change
daemon = True

Copilot uses AI. Check for mistakes.
Comment on lines +257 to +259
target = process_gpu_task,
args = (process_id, file_list, args, pred_conf_shared_dict),
daemon = True
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces around = in keyword arguments violate PEP 8 style guidelines. According to PEP 8, keyword arguments should not have spaces around the equals sign. Change target = process_gpu_task to target=process_gpu_task, args = ... to args=..., and daemon = True to daemon=True.

Suggested change
target = process_gpu_task,
args = (process_id, file_list, args, pred_conf_shared_dict),
daemon = True
target=process_gpu_task,
args=(process_id, file_list, args, pred_conf_shared_dict),
daemon=True

Copilot uses AI. Check for mistakes.
Comment thread pyproject.toml
itk_combine = "itkit.process.itk_combine:main"
itkit-app = "itkit.gui.app:main"
itk_slicer = "SlicerITKIT.server.itkit_server:main"
itk_infer = "itkit.inference.itk_infer:main"
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entry point path is incorrect. The file is located at itkit/process/itk_infer.py but the entry point references itkit.inference.itk_infer:main. This will cause the command to fail at runtime with a ModuleNotFoundError. The entry point should be changed to itkit.process.itk_infer:main to match the actual file location and be consistent with other CLI commands in this project.

Suggested change
itk_infer = "itkit.inference.itk_infer:main"
itk_infer = "itkit.process.itk_infer:main"

Copilot uses AI. Check for mistakes.
return tasks


def set_window(image_array:np.ndarray, wl:int, ww:int) -> np.ndarray:
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after colon in type annotation. Should be image_array: np.ndarray instead of image_array:np.ndarray to follow PEP 8 style guidelines and be consistent with the rest of the codebase (e.g., itkit/process/itk_extract.py:18-24).

Suggested change
def set_window(image_array:np.ndarray, wl:int, ww:int) -> np.ndarray:
def set_window(image_array: np.ndarray, wl: int, ww: int) -> np.ndarray:

Copilot uses AI. Check for mistakes.
idx = 0
for i in range(args.num_proc):
cnt = avg + (1 if i < rem else 0)
tasks.append(pending[idx:idx+cnt])
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space around binary operator. Should be idx:idx + cnt instead of idx:idx+cnt to follow PEP 8 style guidelines.

Suggested change
tasks.append(pending[idx:idx+cnt])
tasks.append(pending[idx:idx + cnt])

Copilot uses AI. Check for mistakes.
logits_np = pred_seg_logits[0].cpu().numpy().astype(np.float16)
if args.save_logits:
zarr.save_array(
output_folder / (file.stem+'.zarr'),
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing spaces around binary operator. Should be file.stem + '.zarr' instead of file.stem+'.zarr' to follow PEP 8 style guidelines and be consistent with the rest of the codebase.

Suggested change
output_folder / (file.stem+'.zarr'),
output_folder / (file.stem + '.zarr'),

Copilot uses AI. Check for mistakes.
import multiprocessing as mp
import os
import traceback
from multiprocessing import Manager
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Module 'multiprocessing' is imported with both 'import' and 'import from'.

Suggested change
from multiprocessing import Manager

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@7e666f8). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #71   +/-   ##
=======================================
  Coverage        ?   72.14%           
=======================================
  Files           ?      108           
  Lines           ?    12167           
  Branches        ?     1085           
=======================================
  Hits            ?     8778           
  Misses          ?     3139           
  Partials        ?      250           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@MGAMZ MGAMZ merged commit bfa8dc7 into main Jan 26, 2026
17 checks passed
@MGAMZ MGAMZ deleted the dev/fix-testpypi branch January 26, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

process itkit.process module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants