Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cffa170
Created TilingDatasets
A-Artemis Jul 1, 2026
9b048b0
Added tiling configs for detection and instance segmentation algorith…
A-Artemis Jul 1, 2026
57d27a9
Enabled tiling for the newly supported algorithms
A-Artemis Jul 1, 2026
dec5930
Removed redundant block
A-Artemis Jul 1, 2026
a519f44
Updated tests to handle new tiling models
A-Artemis Jul 1, 2026
a678544
Added more detailed logging
A-Artemis Jul 2, 2026
2b03282
Added more logging
A-Artemis Jul 2, 2026
0f809b3
Handled tiling compatibility with other augmentations
A-Artemis Jul 2, 2026
a660227
Updated test
A-Artemis Jul 2, 2026
8f1ba6b
Implemented tile-based inference for detection and instance segmentat…
A-Artemis Jul 3, 2026
ff22960
Ensured scores are cast to float32 to prevent dtype mismatch during t…
A-Artemis Jul 3, 2026
d0040a5
Merge branch 'develop' of https://github.com/open-edge-platform/train…
A-Artemis Jul 3, 2026
9ee8a6c
Supported tile-based augmentation in GPU pipeline for validation step
A-Artemis Jul 6, 2026
3043130
Benchmark manifest update for testing tiling enabled/disabled for bot…
A-Artemis Jul 6, 2026
51c26df
Merge branch 'develop' into aurelien/support-tiling
A-Artemis Jul 6, 2026
fc370d3
propagate datamodule tiling configuration to model during predictions
A-Artemis Jul 7, 2026
f711a66
Merge branch 'develop' into aurelien/support-tiling
A-Artemis Jul 7, 2026
95b9c2e
implement annotation alignment for mismatched counts in training batches
A-Artemis Jul 8, 2026
11a15d1
Further fixes for aligning boxes and masks
A-Artemis Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions application/backend/app/execution/training/getitune_trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

if TYPE_CHECKING:
from getitune import TaskType
from getitune.config.data import SubsetConfig
from getitune.config.data import SubsetConfig, TileConfig
from getitune.data.dataset.base import VisionDataset
from getitune.engine.engine import Engine

Expand Down Expand Up @@ -90,6 +90,7 @@ class DatasetInfo:
getitune_validation_subset_config: SubsetConfig
getitune_testing_subset_config: SubsetConfig
revision_id: UUID
tile_config: TileConfig


@dataclass(frozen=True)
Expand Down Expand Up @@ -243,7 +244,7 @@ def prepare_training_configuration(
return training_config, getitune_training_config

@step("Prepare Training Dataset", 10)
def prepare_training_dataset(
def prepare_training_dataset( # noqa: PLR0915
self,
project_id: UUID,
task: Task,
Expand All @@ -258,7 +259,9 @@ def prepare_training_dataset(
Otherwise, it creates a new dataset from the current items in the database with user-verified annotations.
"""

from getitune.config.data import SamplerConfig, SubsetConfig
from getitune import TaskType
from getitune.config.data import SamplerConfig, SubsetConfig, TileConfig
from getitune.data.dataset.tile import TileDatasetFactory
from getitune.data.entity.utils import detect_storage_dtype
Comment thread
A-Artemis marked this conversation as resolved.
from getitune.data.factory import TransformLibFactory

Expand Down Expand Up @@ -349,6 +352,21 @@ def build_subset_config(subset_name: str) -> SubsetConfig:
transforms=test_subset_config.transforms, # pyrefly: ignore[missing-attribute,bad-argument-type]
)

# Build a TileConfig, and wrap each subset dataset with the tiling factory (if tiling is enabled).
tile_cfg_data = getitune_training_config["data"].get("tile_config", {})
tile_config = TileConfig(**tile_cfg_data)
if tile_config.enable_tiler and getitune_task_type in (TaskType.DETECTION, TaskType.INSTANCE_SEGMENTATION):
logger.info("Tiling is enabled - wrapping subset datasets with TileDatasetFactory")
getitune_training_dataset = TileDatasetFactory.create(
dataset=getitune_training_dataset, tile_config=tile_config
)
getitune_validation_dataset = TileDatasetFactory.create(
dataset=getitune_validation_dataset, tile_config=tile_config
)
getitune_testing_dataset = TileDatasetFactory.create(
dataset=getitune_testing_dataset, tile_config=tile_config
)
Comment thread
A-Artemis marked this conversation as resolved.

return DatasetInfo(
getitune_training_dataset=getitune_training_dataset,
getitune_validation_dataset=getitune_validation_dataset,
Expand All @@ -357,6 +375,7 @@ def build_subset_config(subset_name: str) -> SubsetConfig:
getitune_validation_subset_config=val_subset_config,
getitune_testing_subset_config=test_subset_config,
revision_id=dataset_revision_id,
tile_config=tile_config,
)

@step("Prepare Model")
Expand Down Expand Up @@ -416,6 +435,8 @@ def train_model(
val_subset=dataset_info.getitune_validation_subset_config,
test_subset=dataset_info.getitune_testing_subset_config,
)
# Ensure the datamodule (and downstream model) uses the resolved tiling configuration.
datamodule.tile_config = dataset_info.tile_config

logger.info("Instantiating model for training (model_id={})", model_id)
model_cfg = training_config["model"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 54.7
coco_map_50: 72.4

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0005
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ stats:
benchmark_metrics:
coco_map_50_95: 52.7

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0004
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 56.5
coco_map_50: 74.0

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0005
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ stats:
benchmark_metrics:
coco_map_50_95: 56.0

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0005
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ stats:
benchmark_metrics:
coco_map_50_95: 53.0

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0004
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ stats:
benchmark_metrics:
coco_map_50_95: 50.9

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0004
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 56.5
coco_map_50: 75.1

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 54.7
coco_map_50: 73.6

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.00021
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 48.4
coco_map_50: 67.6

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.00021
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 53.0
coco_map_50: 72.1

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.00021
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 49.9
coco_map_50: 73.1

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 47.1
coco_map_50: 70.5

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 45.3
coco_map_50: 68.4

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 40.3
coco_map_50: 63.0

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 43.1
coco_map_50: 66.2

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ stats:
coco_map_50_95: 48.8
coco_map_50: 72.2

capabilities:
tiling: false

hyperparameters:
training:
learning_rate: 0.0001
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ def test_get_default_by_model_architecture_strips_tiling_when_unsupported(
"""Tiling parameters should be removed from the default config when the architecture doesn't support tiling."""
TrainingConfigurationService.get_default_by_model_architecture.cache_clear()

# D-FINE-M does not support tiling (capabilities.tiling: false in its manifest)
# YOLO11-N does not support tiling (capabilities.tiling: false in its manifest)
result = TrainingConfigurationService.get_default_by_model_architecture(
model_architecture_id="object-detection-dfine-m",
model_architecture_id="object-detection-yolo11-n",
)

assert result.algo_level_parameters.dataset_preparation.augmentation.tiling is None
Expand Down Expand Up @@ -183,15 +183,15 @@ def test_get_by_model_architecture_strips_tiling_when_unsupported(
algo_level_config = TrainingConfigurationDB(
id=str(uuid4()),
project_id=fxt_project.id,
model_architecture_id="object-detection-dfine-m",
model_architecture_id="object-detection-yolo11-n",
configuration_data=algo_level_data,
)
db_session.add(algo_level_config)
db_session.flush()

result = fxt_training_configuration_service.get_by_model_architecture(
project_id=UUID(fxt_project.id),
model_architecture_id="object-detection-dfine-m",
model_architecture_id="object-detection-yolo11-n",
)

assert result.algo_level_parameters.dataset_preparation.augmentation.tiling is None
Expand Down
115 changes: 115 additions & 0 deletions library/src/getitune/recipe/detection/deim_dfine_l_tile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
task: DETECTION
model:
class_path: getitune.backend.lightning.models.detection.DEIMDFine
init_args:
model_name: deim_dfine_hgnetv2_l
label_info: 80
multi_scale: false

optimizer:
class_path: torch.optim.AdamW
init_args:
lr: 0.0005
betas: [0.9, 0.999]
weight_decay: 0.000125

scheduler:
class_path: getitune.backend.lightning.schedulers.LinearWarmupSchedulerCallable
init_args:
num_warmup_steps: 30
main_scheduler_callable:
class_path: lightning.pytorch.cli.ReduceLROnPlateau
init_args:
mode: max
factor: 0.5
patience: 10
monitor: val/map_50

engine:
device: auto

callback_monitor: val/map_50

# NOTE: Tiling is incompatible with mosaic/mixup based augmentation scheduling,
Comment thread
A-Artemis marked this conversation as resolved.
# so the AugmentationSchedulerCallback used by the non-tiling recipe is omitted here
# and a static tiling-friendly augmentation pipeline is defined in overrides.
data: ../_base_/data/detection_tile.yaml

callbacks:
- class_path: getitune.backend.lightning.callbacks.adaptive_train_scheduling.AdaptiveTrainScheduling
init_args:
max_interval: 1
min_lrschedule_patience: 3
- class_path: getitune.backend.lightning.callbacks.adaptive_early_stopping.EarlyStoppingWithWarmup
init_args:
mode: max
patience: 15
min_delta: 0.001
warmup_iters: 30
warmup_epochs: 3
- class_path: lightning.pytorch.callbacks.ModelCheckpoint
init_args:
dirpath: "" # use engine.work_dir
monitor: val/map_50
mode: max
save_top_k: 1
save_last: true
auto_insert_metric_name: false
filename: "checkpoints/epoch_{epoch:03d}"

overrides:
callbacks:
- class_path: getitune.backend.lightning.callbacks.adaptive_train_scheduling.AdaptiveTrainScheduling
init_args:
max_interval: 1
min_lrschedule_patience: 3
- class_path: getitune.backend.lightning.callbacks.adaptive_early_stopping.EarlyStoppingWithWarmup
init_args:
warmup_iters: 100
warmup_epochs: 7

data:
input_size:
- 640
- 640
task: DETECTION
train_subset:
batch_size: 8
augmentations_cpu:
- class_path: torchvision.transforms.v2.RandomZoomOut
init_args:
fill: 0
p: 0.5
- class_path: getitune.data.augmentation.transforms.RandomIoUCrop
- class_path: torchvision.transforms.v2.SanitizeBoundingBoxes
init_args:
min_size: 1
- class_path: getitune.data.augmentation.transforms.Resize
init_args:
size: $(input_size)
keep_aspect_ratio: false
augmentations_gpu:
- class_path: kornia.augmentation.RandomHorizontalFlip
init_args:
p: 0.5
sampler:
class_path: getitune.data.samplers.balanced_sampler.BalancedSampler

val_subset:
batch_size: 8
augmentations_cpu:
- class_path: getitune.data.augmentation.transforms.Resize
init_args:
size: $(input_size)
keep_aspect_ratio: false
resize_targets: false
augmentations_gpu: []
test_subset:
batch_size: 8
augmentations_cpu:
- class_path: getitune.data.augmentation.transforms.Resize
init_args:
size: $(input_size)
keep_aspect_ratio: false
resize_targets: false
augmentations_gpu: []
Loading
Loading