Inference artifact saving#453
Conversation
- Add onnx>=1.20.0 to project dependencies - Update uv.lock with onnx and ml-dtypes packages - Update filelock from 3.19.1 to 3.20.1
- Remove trailing whitespace - Fix inconsistent indentation - Adjust line spacing - Format quotes to double quotes - Add missing blank line at end of file
Dependency ReviewThe following issues were found:
Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Vulnerabilitiesuv.lockOpenSSF Scorecard
Scanned Files
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds end-to-end inference artifact saving and ONNX export support by logging the best checkpoint (plus label map) to W&B, introducing a segmentation-style wrapper for classifiers, and adding a standalone inference script.
Changes:
- Added
SegmentationWrapperto convert classifier logits into a dense per-pixel mask for ONNX/segmentation-like outputs. - Updated training flow to select/log the best checkpoint as a W&B artifact and persist a
.label_map.jsonnext to it. - Added an inference entrypoint with optional W&B artifact download + ONNX export, plus configurable train-time augmentation.
Reviewed changes
Copilot reviewed 9 out of 588 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/models/segmentation_wrapper.py | New wrapper module that normalizes inputs and expands class probabilities into a (B, C, H, W) mask. |
| src/models/model_factory.py | Passes freeze through to FineGrainedModel. |
| src/models/diversified_model.py | Stabilizes top-k selection and pooling behavior; adds optional freezing of backbone. |
| src/models/classifier_module.py | Splits accuracy metrics by stage and aligns fine-grained training behavior with self.training. |
| src/main.py | Logs best checkpoint + label map as explicit W&B artifact; makes checkpoint monitor configurable; prints split summary. |
| src/inference.py | New inference script: load checkpoint (local or W&B artifact), run inference, optionally export/upload ONNX. |
| src/dataset.py | Adds configurable train augmentation pipeline and improves pin_memory device detection. |
| src/config.yaml | Adds inference config and augmentation config; changes defaults (e.g., batch size, device). |
| pyproject.toml | Adds onnx dependency required for export/metadata writing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def _wandb_safe_metadata_value(value): | ||
| if isinstance(value, float) and not math.isfinite(value): | ||
| return None | ||
| if isinstance(value, torch.Tensor): | ||
| if value.numel() == 1: | ||
| scalar = value.item() | ||
| return None if isinstance(scalar, float) and not math.isfinite(scalar) else scalar | ||
| return value.tolist() | ||
| return value |
There was a problem hiding this comment.
math.isfinite is used but math is not imported in the shown imports at the top of main.py, which will raise NameError at runtime. Add import math near the top of the file (or replace math.isfinite with an equivalent already-imported utility).
|
|
||
| training: | ||
| batch_size: 32 | ||
| batch_size: 1 |
There was a problem hiding this comment.
The committed defaults make the repo configuration brittle/non-portable: (1) raw_images_path is an absolute, user-specific filesystem path; (2) wandb_artifact points to a specific run artifact; (3) export_onnx: true enables export by default; and (4) training.batch_size changed from 32 to 1. Recommend reverting these to safe, portable defaults (e.g., comment out run-specific values, use relative example paths, set export_onnx: false by default, and restore a reasonable default batch_size).
| inference: | ||
| mask_size: 224 | ||
| export_onnx: true | ||
| checkpoint_path: "checkpoints/model.ckpt" | ||
| # wandb_artifact: "ghost-irim/ghost-irim/model-kx2co2o3:v0" | ||
| wandb_artifact: "ghost-irim/ghost-irim/best-model-inference-artifact-saving-vft1nd:v0" | ||
| wandb_project: "ghost-irim" | ||
| # Set to true to run inference on raw images (ONNX-style testing) | ||
| # Set to false to run inference on test dataset split | ||
| use_raw_images: false | ||
| # Path to directory containing raw images (relative to project root) | ||
| # raw_images_path: "test_images_qgis/10122025_193353" | ||
| # raw_images_path: "/home/adam/Documents/programming/tree-classification-irim/src/data/Abies_alba/train" | ||
| raw_images_path: "/home/adam/Documents/programming/tree-classification-irim/src/data/Robinia_pseudoacacia/train" | ||
| device: "cuda" |
There was a problem hiding this comment.
The committed defaults make the repo configuration brittle/non-portable: (1) raw_images_path is an absolute, user-specific filesystem path; (2) wandb_artifact points to a specific run artifact; (3) export_onnx: true enables export by default; and (4) training.batch_size changed from 32 to 1. Recommend reverting these to safe, portable defaults (e.g., comment out run-specific values, use relative example paths, set export_onnx: false by default, and restore a reasonable default batch_size).
| run = wandb.init(project=project_name, job_type="inference") | ||
|
|
||
| artifact = run.use_artifact(artifact_path, type="model") | ||
| artifact_dir = artifact.download() | ||
|
|
There was a problem hiding this comment.
download_checkpoint_from_wandb() creates and finishes a W&B run immediately. As a result, later sections guarded by if wandb.run is not None: (ONNX artifact upload and metric logging) will never execute in the common 'download-from-artifact' path. Consider either (a) keeping the run open and finishing at the end of main(), or (b) moving W&B initialization to main() (optionally behind a config flag like inference.log_to_wandb), and having download_checkpoint_from_wandb() reuse the active run.
| run.finish() | ||
|
|
||
| return checkpoint_path |
There was a problem hiding this comment.
download_checkpoint_from_wandb() creates and finishes a W&B run immediately. As a result, later sections guarded by if wandb.run is not None: (ONNX artifact upload and metric logging) will never execute in the common 'download-from-artifact' path. Consider either (a) keeping the run open and finishing at the end of main(), or (b) moving W&B initialization to main() (optionally behind a config flag like inference.log_to_wandb), and having download_checkpoint_from_wandb() reuse the active run.
|
|
||
| def __init__(self, classifier: nn.Module, mask_size: int = 224, mean=None, std=None, input_rescale=False): | ||
| super().__init__() | ||
| self.classifier = classifier.eval() |
There was a problem hiding this comment.
Calling .eval() on the passed-in classifier mutates external state as a side effect of constructing SegmentationWrapper. This can be surprising if the caller expects to control train/eval mode (or reuses the classifier elsewhere). Prefer storing self.classifier = classifier and letting the caller set .eval() (as is already done in inference.py), or documenting clearly that the wrapper forces eval mode.
| import wandb | ||
| from omegaconf import OmegaConf | ||
| from tqdm import tqdm | ||
| from torchvision.utils import save_image |
There was a problem hiding this comment.
save_image is imported but never used anywhere in this file. Removing it avoids dead imports and reduces lint noise.
This pull request introduces several improvements and new features across the codebase, focusing on data augmentation, configuration flexibility, training/inference workflow, and code robustness. The most significant changes include adding configurable data augmentation, improving model checkpointing and artifact logging, and refactoring accuracy tracking and model freezing logic.
Data pipeline and augmentation improvements:
src/config.yaml, enabling options such as random flips, rotation, brightness, contrast, saturation, and hue adjustments. The augmentation pipeline is implemented inget_train_transform()insrc/dataset.pyand applied during training dataset setup. [1] [2] [3]pyproject.tomlto support ONNX model export during inference.Training and inference workflow enhancements:
inferencesection insrc/config.yamlto control mask size, ONNX export, checkpoint paths, artifact tracking, and device selection. Device handling in dataloader parameters is now more robust to "cuda"/"gpu" string variants. [1] [2]SegmentationWrappermodule for wrapping classifiers to produce segmentation-style outputs, supporting normalization and optional input rescaling.Model and metrics tracking improvements:
src/models/classifier_module.pyto maintain separate accuracy metrics for training, validation, and test phases, and improved logging granularity. [1] [2]Experiment tracking and artifact logging:
Miscellaneous:
These changes collectively improve the flexibility, robustness, and traceability of the training and inference pipeline.