From d42ef94821832d7e8373a445f521e5c70b038934 Mon Sep 17 00:00:00 2001 From: pikaliov Date: Wed, 29 Apr 2026 14:45:31 +0300 Subject: [PATCH] clean up to baseline --- src/conf/config_loader.py | 62 ------------------------------ src/conf/hardware_conf.py | 43 --------------------- src/conf/models_conf.py | 54 -------------------------- src/conf/pipeline_conf.py | 57 ---------------------------- src/conf/tracking_conf.py | 48 ------------------------ src/conf/training_conf.py | 79 --------------------------------------- 6 files changed, 343 deletions(-) delete mode 100644 src/conf/config_loader.py delete mode 100644 src/conf/hardware_conf.py delete mode 100644 src/conf/models_conf.py delete mode 100644 src/conf/pipeline_conf.py delete mode 100644 src/conf/tracking_conf.py delete mode 100644 src/conf/training_conf.py diff --git a/src/conf/config_loader.py b/src/conf/config_loader.py deleted file mode 100644 index 0125d74..0000000 --- a/src/conf/config_loader.py +++ /dev/null @@ -1,62 +0,0 @@ -from __future__ import annotations - -import logging -from pathlib import Path -from typing import Any - -import gin - -from src.conf.hardware_conf import HardwareConfig -from src.conf.models_conf import ModelsConfig -from src.conf.pipeline_conf import PipelineConfig -from src.conf.tracking_conf import TrackingConfig -from src.conf.training_conf import TrainingConfig - -logger = logging.getLogger(__name__) - - -def load_all_configs(path2cfg: str) -> dict[str, Any]: - """Parse ALL .gin files in path2cfg and return all config objects. - - This is the PRODUCTION entry point — main() calls this once. Individual - get_*_cfg() loaders exist only for unit tests / notebooks. - - Args: - path2cfg: Path to config directory (WITH trailing slash). - - Returns: - Dict with config objects keyed by name: - { - "pipeline": PipelineConfig, - "hardware": HardwareConfig, - "models": ModelsConfig, - "training": TrainingConfig, - "tracking": TrackingConfig, - } - - Raises: - FileNotFoundError: If path2cfg contains no .gin files. - """ - cfg_dir = Path(path2cfg) - gin_files = sorted(cfg_dir.glob("*.gin")) - if not gin_files: - raise FileNotFoundError(f"No .gin files found in {cfg_dir}") - - # MANDATORY: reset gin global state before parsing — without clear_config(), - # parameters from previous parses accumulate (gin holds global bindings). - gin.clear_config() - gin.parse_config_files_and_bindings( - config_files=[str(f) for f in gin_files], - bindings=[], - ) - logger.info("Loaded %d gin files from %s", len(gin_files), cfg_dir) - - # Instantiate AFTER all bindings are parsed. - return { - "pipeline": PipelineConfig(), - "hardware": HardwareConfig(), - "models": ModelsConfig(), - "training": TrainingConfig(), - "tracking": TrackingConfig(), - } - diff --git a/src/conf/hardware_conf.py b/src/conf/hardware_conf.py deleted file mode 100644 index 0d0e7b9..0000000 --- a/src/conf/hardware_conf.py +++ /dev/null @@ -1,43 +0,0 @@ -from __future__ import annotations - -import gin - - -@gin.configurable -class HardwareConfig: - """GPU profile + memory/compute optimisation flags. - - Everything that changes when you switch hardware (4090 → A100 → Jetson) - lives here. batch_size and grad_accum_steps are hardware-bound: they - determine VRAM footprint, not the training recipe. - """ - - def __init__( - self, - device: str = "cuda", - batch_size: int = 8, - grad_accum_steps: int = 1, - num_workers: int = 4, - use_amp: bool = True, - gradient_checkpointing: bool = True, - reserve_gb: float = 2.0, - ) -> None: - self.device = device - self.batch_size = batch_size - self.grad_accum_steps = grad_accum_steps - self.num_workers = num_workers - self.use_amp = use_amp - self.gradient_checkpointing = gradient_checkpointing - self.reserve_gb = reserve_gb - # Derived (RTX 4090 default; override per profile): - self.total_vram_gb = 24.0 - self.available_vram_gb = self.total_vram_gb - self.reserve_gb - self.effective_batch_size = self.batch_size * self.grad_accum_steps - - -def get_hardware_cfg(path2cfg: str) -> HardwareConfig: - """Load ONLY hardware config (TESTING ONLY — use load_all_configs in production).""" - gin.clear_config() - gin.parse_config_file(f"{path2cfg}hardware.gin") - return HardwareConfig() - diff --git a/src/conf/models_conf.py b/src/conf/models_conf.py deleted file mode 100644 index 448ac0b..0000000 --- a/src/conf/models_conf.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import annotations - -import gin - - -@gin.configurable -class ModelsConfig: - """Model checkpoints + architecture switches. - - Default checkpoint paths are relative to the project root (matching the - repository layout: nn_models/DINO_WEB/, nn_models/DINO_SAT/, etc.). - These are gitignored and must be downloaded separately — see README. - """ - - def __init__( - self, - # Checkpoints — relative to project root, defaults match repo layout. - dino_web_path: str = "nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth", - dino_sat_path: str = "nn_models/DINO_SAT/model.safetensors", - lrsclip_path: str = "nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt", - stripnet_path: str = "nn_models/STRIPNET/stripnet_s.pth", - # Backbone selection. - backbone: str = "dinov3", - shared_encoder: bool = True, - baseline_mode: bool = False, - # Fusion. - init_gate: float = 0.7, - # MONA (DINOv3). - mona_bottleneck: int = 64, - mona_last_n_blocks: int = 12, - # StripNet-specific. - stripnet_freeze: bool = True, - stripnet_mona_last_n_stages: int = 2, - ) -> None: - self.dino_web_path = dino_web_path - self.dino_sat_path = dino_sat_path - self.lrsclip_path = lrsclip_path - self.stripnet_path = stripnet_path - self.backbone = backbone - self.shared_encoder = shared_encoder - self.baseline_mode = baseline_mode - self.init_gate = init_gate - self.mona_bottleneck = mona_bottleneck - self.mona_last_n_blocks = mona_last_n_blocks - self.stripnet_freeze = stripnet_freeze - self.stripnet_mona_last_n_stages = stripnet_mona_last_n_stages - - -def get_models_cfg(path2cfg: str) -> ModelsConfig: - """Load ONLY models config (TESTING ONLY — use load_all_configs in production).""" - gin.clear_config() - gin.parse_config_file(f"{path2cfg}models.gin") - return ModelsConfig() - diff --git a/src/conf/pipeline_conf.py b/src/conf/pipeline_conf.py deleted file mode 100644 index a2f41ea..0000000 --- a/src/conf/pipeline_conf.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import annotations - -import gin - - -@gin.configurable -class PipelineConfig: - """Pipeline orchestration: data IO, training schedule, output, resume. - - Defaults match the current `belka_refactor` HEAD: hardcoded servml paths - are preserved verbatim. To switch to a different machine, override in - pipeline.gin — never edit defaults here. - """ - - def __init__( - self, - # Data paths (defaults match servml workstation). - train_json: str = "meta/train_80.json", - test_json: str = "meta/test_20.json", - rgb_root: str = "/home/servml/Документы/datasets/GTA-UAV-LR", - caption_root: str = "/home/servml/Документы/datasets/GTA-UAV-LR-captions", - filter_meta: str | None = None, - # Training schedule. - epochs: int = 10, - warmup_epochs: int = 2, - eval_every: int = 1, - # Reproducibility & output. - seed: int = 42, - output_dir: str = "out/gtauav/with_text", - resume_from: str | None = None, - ) -> None: - self.train_json = train_json - self.test_json = test_json - self.rgb_root = rgb_root - self.caption_root = caption_root - self.filter_meta = filter_meta - self.epochs = epochs - self.warmup_epochs = warmup_epochs - self.eval_every = eval_every - self.seed = seed - self.output_dir = output_dir - self.resume_from = resume_from - - -def get_pipeline_cfg(path2cfg: str) -> PipelineConfig: - """Load ONLY pipeline config (TESTING ONLY — use load_all_configs in production). - - Args: - path2cfg: Path to config directory (with trailing slash). - - Returns: - Instantiated PipelineConfig. - """ - gin.clear_config() - gin.parse_config_file(f"{path2cfg}pipeline.gin") - return PipelineConfig() - diff --git a/src/conf/tracking_conf.py b/src/conf/tracking_conf.py deleted file mode 100644 index d4974a6..0000000 --- a/src/conf/tracking_conf.py +++ /dev/null @@ -1,48 +0,0 @@ -from __future__ import annotations - -import gin - - -@gin.configurable -class TrackingConfig: - """Experiment tracking + diagnostics. - - Independent axis: changing these flags does not affect training results, - only what is observed/recorded. - """ - - def __init__( - self, - use_wandb: bool = False, - use_tb: bool = True, - wandb_project: str = "caption-test-gtauav", - wandb_run_name: str | None = None, - wandb_entity: str | None = None, - log_grad_norms: bool = True, - use_gradcam: bool = False, - gradcam_every: int = 5, - gradcam_samples: int = 8, - use_profiler: bool = False, - profiler_warmup: int = 3, - profiler_active: int = 5, - ) -> None: - self.use_wandb = use_wandb - self.use_tb = use_tb - self.wandb_project = wandb_project - self.wandb_run_name = wandb_run_name - self.wandb_entity = wandb_entity - self.log_grad_norms = log_grad_norms - self.use_gradcam = use_gradcam - self.gradcam_every = gradcam_every - self.gradcam_samples = gradcam_samples - self.use_profiler = use_profiler - self.profiler_warmup = profiler_warmup - self.profiler_active = profiler_active - - -def get_tracking_cfg(path2cfg: str) -> TrackingConfig: - """Load ONLY tracking config (TESTING ONLY — use load_all_configs in production).""" - gin.clear_config() - gin.parse_config_file(f"{path2cfg}tracking.gin") - return TrackingConfig() - diff --git a/src/conf/training_conf.py b/src/conf/training_conf.py deleted file mode 100644 index 264c450..0000000 --- a/src/conf/training_conf.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import annotations - -import gin - - -@gin.configurable -class TrainingConfig: - """Training recipe: loss + optimizer + sampler. - - These three move together when you tune learning. Changing tau usually - pairs with changing lr; switching sampler_type usually pairs with - re-tuning loss weights. Keeping them in one config matches the actual - workflow of running ablations. - """ - - def __init__( - self, - # --- Loss --- - loss_type: str = "symmetric", - tau_init: float = 0.07, - tau_min: float = 0.01, - tau_max: float = 0.1, - learnable_temperature: bool = True, - label_smoothing: float = 0.1, - weight_q2g: float = 0.6, - weight_g2q: float = 0.4, - hard_mining_k: int = 0, - neg_bank_size: int = 0, - # --- Optimizer --- - learning_rate: float = 1e-4, - text_lr_factor: float = 0.1, - stripnet_backbone_lr_factor: float = 0.1, - weight_decay: float = 1e-4, - grad_clip: float = 1.0, - # --- Sampler --- - sampler_type: str = "mutex", - dss_warmup_epochs: int = 1, - dss_reembed_every: int = 1, - dss_knn_device: str = "cuda", - dss_use_lsh: bool = False, - dss_lsh_num_tables: int = 8, - dss_lsh_num_bits: int = 14, - dss_cache_dir: str | None = None, - ) -> None: - # Loss. - self.loss_type = loss_type - self.tau_init = tau_init - self.tau_min = tau_min - self.tau_max = tau_max - self.learnable_temperature = learnable_temperature - self.label_smoothing = label_smoothing - self.weight_q2g = weight_q2g - self.weight_g2q = weight_g2q - self.hard_mining_k = hard_mining_k - self.neg_bank_size = neg_bank_size - # Optimizer. - self.learning_rate = learning_rate - self.text_lr_factor = text_lr_factor - self.stripnet_backbone_lr_factor = stripnet_backbone_lr_factor - self.weight_decay = weight_decay - self.grad_clip = grad_clip - # Sampler. - self.sampler_type = sampler_type - self.dss_warmup_epochs = dss_warmup_epochs - self.dss_reembed_every = dss_reembed_every - self.dss_knn_device = dss_knn_device - self.dss_use_lsh = dss_use_lsh - self.dss_lsh_num_tables = dss_lsh_num_tables - self.dss_lsh_num_bits = dss_lsh_num_bits - self.dss_cache_dir = dss_cache_dir - - -def get_training_cfg(path2cfg: str) -> TrainingConfig: - """Load ONLY training config (TESTING ONLY — use load_all_configs in production).""" - gin.clear_config() - gin.parse_config_file(f"{path2cfg}training.gin") - return TrainingConfig() - -