diff --git a/belka_refactor_30_04_table.md b/belka_refactor_30_04_table.md new file mode 100644 index 0000000..bf7a4df --- /dev/null +++ b/belka_refactor_30_04_table.md @@ -0,0 +1,25 @@ +# Сводная таблица всех 15 пресетов +## Изменения +- scr/conf/*.py конфиги +- presets/*/*.gin (по 5 файлов на пресет: [pipeline, hardware, models, tracking, trainig]) + +## TODO: Сейчас конфиги пресетов разделены, но много дублирующихся общих пресетов файлов: сделать маппинг (Dict) общих файлов [pipeline, hardware, models, tracking, trainig] на свои пресеты +--- + +| Пресет | backbone | baseline_mode | shared_encoder | init_gate | +| ----------------------------------- | --------- | ------------- | -------------- | --------- | +| `gtauav_balanced` | dinov3 | False | True | 0.7 | +| `gtauav_baseline` | dinov3 | True | True | 0.7 | +| `gtauav_balanced_asym` | dinov3 | False | False | 0.7 | +| `gtauav_baseline_asym` | dinov3 | True | False | 0.7 | +| `gtauav_text_heavy` | dinov3 | False | True | **0.3** | +| `gtauav_image_heavy` | dinov3 | False | True | **0.9** | +| `gtauav_balanced_stripnet` | stripnet | False | — | 0.7 | +| `gtauav_balanced_stripnet_unfrozen` | stripnet | False | — | 0.7 | +| `gtauav_baseline_stripnet` | stripnet | True | — | 0.7 | +| `gtauav_baseline_stripnet_unfrozen` | stripnet | True | — | 0.7 | +| `gtauav_balanced_sofia` | sofia_v71 | False | — | 0.7 | +| `gtauav_baseline_sofia` | sofia_v71 | True | — | 0.7 | +| `gtauav_balanced_sofia_v1` | sofia_v1 | False | — | 0.7 | +| `gtauav_baseline_sofia_v1` | sofia_v1 | True | — | 0.7 | +| `preprocess` | — | — | — | — | \ No newline at end of file diff --git a/presets/gtauav_balanced/hardware.gin b/presets/gtauav_balanced/hardware.gin index 8b13789..dfc9be7 100644 --- a/presets/gtauav_balanced/hardware.gin +++ b/presets/gtauav_balanced/hardware.gin @@ -1 +1,9 @@ - +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_balanced/models.gin b/presets/gtauav_balanced/models.gin index 8b13789..f24450b 100644 --- a/presets/gtauav_balanced/models.gin +++ b/presets/gtauav_balanced/models.gin @@ -1 +1,12 @@ +# DINOv3 shared encoder + MONA-12 + DGTRS-CLIP with text. +ModelsCommonConfig.backbone = 'dinov3' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' +DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' +DINOv3ModelsConfig.shared_encoder = True +DINOv3ModelsConfig.mona_bottleneck = 64 +DINOv3ModelsConfig.mona_last_n_blocks = 12 +DINOv3ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_balanced/pipeline.gin b/presets/gtauav_balanced/pipeline.gin index 8b13789..3d5190b 100644 --- a/presets/gtauav_balanced/pipeline.gin +++ b/presets/gtauav_balanced/pipeline.gin @@ -1 +1,14 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/with_text' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_balanced/tracking.gin b/presets/gtauav_balanced/tracking.gin index 8b13789..111a337 100644 --- a/presets/gtauav_balanced/tracking.gin +++ b/presets/gtauav_balanced/tracking.gin @@ -1 +1,15 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_balanced/training.gin b/presets/gtauav_balanced/training.gin index 8b13789..500f55e 100644 --- a/presets/gtauav_balanced/training.gin +++ b/presets/gtauav_balanced/training.gin @@ -1 +1,31 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_balanced_asym/hardware.gin b/presets/gtauav_balanced_asym/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_balanced_asym/hardware.gin +++ b/presets/gtauav_balanced_asym/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_balanced_asym/models.gin b/presets/gtauav_balanced_asym/models.gin index 8b13789..104a467 100644 --- a/presets/gtauav_balanced_asym/models.gin +++ b/presets/gtauav_balanced_asym/models.gin @@ -1 +1,11 @@ +ModelsCommonConfig.backbone = 'dinov3' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' +DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' +DINOv3ModelsConfig.shared_encoder = False +DINOv3ModelsConfig.mona_bottleneck = 64 +DINOv3ModelsConfig.mona_last_n_blocks = 24 +DINOv3ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_balanced_asym/pipeline.gin b/presets/gtauav_balanced_asym/pipeline.gin index 8b13789..a0f65e9 100644 --- a/presets/gtauav_balanced_asym/pipeline.gin +++ b/presets/gtauav_balanced_asym/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/balanced_asym' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_balanced_asym/tracking.gin b/presets/gtauav_balanced_asym/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_balanced_asym/tracking.gin +++ b/presets/gtauav_balanced_asym/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_balanced_asym/training.gin b/presets/gtauav_balanced_asym/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_balanced_asym/training.gin +++ b/presets/gtauav_balanced_asym/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_balanced_sofia/hardware.gin b/presets/gtauav_balanced_sofia/hardware.gin index 8b13789..ab09c0a 100644 --- a/presets/gtauav_balanced_sofia/hardware.gin +++ b/presets/gtauav_balanced_sofia/hardware.gin @@ -1 +1,9 @@ - +# SOFIA v7.1 from-scratch — keep activations live (no gradient checkpointing). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = False +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_balanced_sofia/models.gin b/presets/gtauav_balanced_sofia/models.gin index 8b13789..6d16fa4 100644 --- a/presets/gtauav_balanced_sofia/models.gin +++ b/presets/gtauav_balanced_sofia/models.gin @@ -1 +1,91 @@ +# SOFIA v7.1 Tiny preset (~5M params) with text fusion (Text-FiLM mid-level +# in SAT and UAV heads + GatedFusion late-level on descriptors). +# +# Tiny-specific notes: +# - num_heads_s3/s4 = 4 (channels 176/224 not divisible by 8) +# - mamba_headdim = 16 (channels not divisible by default 64) +# - mamba_variant = 'mamba1' (Mamba-2 torch fallback bug for these dims) +# - d_descriptor = 1024 (override from preset M default 512) +# - text fusion enabled (override from preset M default disabled) +ModelsCommonConfig.backbone = 'sofia_v71' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +# Variant label (informational). +SOFIAv71ModelsConfig.variant_label = 'Tiny' + +# Input. +SOFIAv71ModelsConfig.input_size = 256 +SOFIAv71ModelsConfig.in_channels = 3 + +# Stem (Tiny dims). +SOFIAv71ModelsConfig.stem_mid = 16 +SOFIAv71ModelsConfig.stem_out = 32 + +# Backbone dimensions (Tiny). +SOFIAv71ModelsConfig.embed_dims = [48, 96, 176, 224] +SOFIAv71ModelsConfig.depths = [2, 3, 4, 2] + +# Stage 1-2 block params (default). +SOFIAv71ModelsConfig.mbconv_expand = 4 +SOFIAv71ModelsConfig.se_ratio = 16 +SOFIAv71ModelsConfig.strip_kernel_s1 = 7 +SOFIAv71ModelsConfig.strip_kernel_s2 = 5 +SOFIAv71ModelsConfig.mix_kernels = [3, 5, 7] +SOFIAv71ModelsConfig.use_dcn_strip = True + +# Stage 3-4 (MambaVision). Tiny: mamba1 to bypass torch fallback bug. +SOFIAv71ModelsConfig.mamba_d_state = 16 +SOFIAv71ModelsConfig.mamba_dt_rank = None +SOFIAv71ModelsConfig.mamba_backend = 'auto' +SOFIAv71ModelsConfig.mamba_variant = 'mamba1' + +# Mamba-2 tunables (used when mamba_variant='mamba2'; Tiny would need +# headdim=16 because 176 % 64 != 0 and 224 % 64 != 0). +SOFIAv71ModelsConfig.mamba_d_state_mamba2 = 64 +SOFIAv71ModelsConfig.mamba_headdim = 16 +SOFIAv71ModelsConfig.mamba_expand = 2 +SOFIAv71ModelsConfig.mamba_d_conv = 4 +SOFIAv71ModelsConfig.mamba_n_directions = 2 + +# Heads / attention (Tiny: heads=4). +SOFIAv71ModelsConfig.num_heads_s3 = 4 +SOFIAv71ModelsConfig.num_heads_s4 = 4 +SOFIAv71ModelsConfig.use_strip_branch_s3 = True +SOFIAv71ModelsConfig.use_strip_branch_s4 = False +SOFIAv71ModelsConfig.ffn_expand = 4 + +# EVSS bridge (off by default). +SOFIAv71ModelsConfig.use_evss_bridge = False +SOFIAv71ModelsConfig.evss_bridge_locations = ['pre_stage3'] + +# Neck (Tiny). +SOFIAv71ModelsConfig.neck_channels = 128 + +# CVGL Head. +SOFIAv71ModelsConfig.d_descriptor = 1024 +SOFIAv71ModelsConfig.use_asymmetric_heads = True +SOFIAv71ModelsConfig.chp_rings = 8 +SOFIAv71ModelsConfig.chp_angles = 16 +SOFIAv71ModelsConfig.chp_harmonics = 4 +SOFIAv71ModelsConfig.use_film_altitude = True +SOFIAv71ModelsConfig.altitude_norm = 500.0 +SOFIAv71ModelsConfig.ring_count = 4 +SOFIAv71ModelsConfig.use_ring_aux = True + +# Text fusion enabled. +SOFIAv71ModelsConfig.return_normalized = True +SOFIAv71ModelsConfig.use_text_film_sat = True +SOFIAv71ModelsConfig.use_text_film_uav = True +SOFIAv71ModelsConfig.text_film_dim = 1024 +SOFIAv71ModelsConfig.text_film_hidden = 256 + +# Sharing / KD / deploy. +SOFIAv71ModelsConfig.share_stages_1_2 = True +SOFIAv71ModelsConfig.enable_kd_taps = True +SOFIAv71ModelsConfig.precision = 'fp16' + +# LoRA. +SOFIAv71ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_balanced_sofia/pipeline.gin b/presets/gtauav_balanced_sofia/pipeline.gin index 8b13789..90f28d9 100644 --- a/presets/gtauav_balanced_sofia/pipeline.gin +++ b/presets/gtauav_balanced_sofia/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/with_text_sofia' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_balanced_sofia/tracking.gin b/presets/gtauav_balanced_sofia/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_balanced_sofia/tracking.gin +++ b/presets/gtauav_balanced_sofia/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_balanced_sofia/training.gin b/presets/gtauav_balanced_sofia/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_balanced_sofia/training.gin +++ b/presets/gtauav_balanced_sofia/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_balanced_sofia_v1/hardware.gin b/presets/gtauav_balanced_sofia_v1/hardware.gin index 8b13789..7fac8b0 100644 --- a/presets/gtauav_balanced_sofia_v1/hardware.gin +++ b/presets/gtauav_balanced_sofia_v1/hardware.gin @@ -1 +1,8 @@ - +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = False +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_balanced_sofia_v1/models.gin b/presets/gtauav_balanced_sofia_v1/models.gin index 8b13789..746c8d5 100644 --- a/presets/gtauav_balanced_sofia_v1/models.gin +++ b/presets/gtauav_balanced_sofia_v1/models.gin @@ -1 +1,30 @@ +# SOFIA v1 'tiny' variant (~1M params) with text fusion (Text-FiLM mid-level +# in SAT and UAV heads + AltitudeFiLM in UAV head + GatedFusion late-level). +ModelsCommonConfig.backbone = 'sofia_v1' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +# Backbone. +SOFIAv1ModelsConfig.variant_label = 'tiny' +SOFIAv1ModelsConfig.in_channels = 3 +SOFIAv1ModelsConfig.input_size = 256 +SOFIAv1ModelsConfig.dcn_variant = 'v2' + +# Heads. +SOFIAv1ModelsConfig.d_descriptor = 1024 +SOFIAv1ModelsConfig.return_normalized = False + +# Altitude-FiLM. +SOFIAv1ModelsConfig.use_film_altitude = True +SOFIAv1ModelsConfig.altitude_norm = 500.0 + +# Text-FiLM. +SOFIAv1ModelsConfig.use_text_film_uav = True +SOFIAv1ModelsConfig.use_text_film_sat = True +SOFIAv1ModelsConfig.text_film_dim = 1024 +SOFIAv1ModelsConfig.text_film_hidden = 256 + +# LoRA on DGTRS-CLIP. +SOFIAv1ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_balanced_sofia_v1/pipeline.gin b/presets/gtauav_balanced_sofia_v1/pipeline.gin index 8b13789..d92a5d5 100644 --- a/presets/gtauav_balanced_sofia_v1/pipeline.gin +++ b/presets/gtauav_balanced_sofia_v1/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/with_text_sofia_v1' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_balanced_sofia_v1/tracking.gin b/presets/gtauav_balanced_sofia_v1/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_balanced_sofia_v1/tracking.gin +++ b/presets/gtauav_balanced_sofia_v1/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_balanced_sofia_v1/training.gin b/presets/gtauav_balanced_sofia_v1/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_balanced_sofia_v1/training.gin +++ b/presets/gtauav_balanced_sofia_v1/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_balanced_stripnet/hardware.gin b/presets/gtauav_balanced_stripnet/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_balanced_stripnet/hardware.gin +++ b/presets/gtauav_balanced_stripnet/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_balanced_stripnet/models.gin b/presets/gtauav_balanced_stripnet/models.gin index 8b13789..0cdc726 100644 --- a/presets/gtauav_balanced_stripnet/models.gin +++ b/presets/gtauav_balanced_stripnet/models.gin @@ -1 +1,11 @@ +# StripNet small backbone (frozen) + Conv-MONA on last 2 stages. +ModelsCommonConfig.backbone = 'stripnet' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +StripNetModelsConfig.stripnet_path = 'nn_models/STRIPNET/stripnet_s.pth' +StripNetModelsConfig.stripnet_freeze = True +StripNetModelsConfig.stripnet_mona_last_n_stages = 2 +StripNetModelsConfig.stripnet_backbone_lr_factor = 0.1 +StripNetModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_balanced_stripnet/pipeline.gin b/presets/gtauav_balanced_stripnet/pipeline.gin index 8b13789..d51c699 100644 --- a/presets/gtauav_balanced_stripnet/pipeline.gin +++ b/presets/gtauav_balanced_stripnet/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/balanced_stripnet' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_balanced_stripnet/tracking.gin b/presets/gtauav_balanced_stripnet/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_balanced_stripnet/tracking.gin +++ b/presets/gtauav_balanced_stripnet/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_balanced_stripnet/training.gin b/presets/gtauav_balanced_stripnet/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_balanced_stripnet/training.gin +++ b/presets/gtauav_balanced_stripnet/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_balanced_stripnet_unfrozen/hardware.gin b/presets/gtauav_balanced_stripnet_unfrozen/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_balanced_stripnet_unfrozen/hardware.gin +++ b/presets/gtauav_balanced_stripnet_unfrozen/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_balanced_stripnet_unfrozen/models.gin b/presets/gtauav_balanced_stripnet_unfrozen/models.gin index 8b13789..2d9fe78 100644 --- a/presets/gtauav_balanced_stripnet_unfrozen/models.gin +++ b/presets/gtauav_balanced_stripnet_unfrozen/models.gin @@ -1 +1,11 @@ +# StripNet small backbone (frozen) + Conv-MONA on last 2 stages. +ModelsCommonConfig.backbone = 'stripnet' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +StripNetModelsConfig.stripnet_path = 'nn_models/STRIPNET/stripnet_s.pth' +StripNetModelsConfig.stripnet_freeze = False +StripNetModelsConfig.stripnet_mona_last_n_stages = 2 +StripNetModelsConfig.stripnet_backbone_lr_factor = 0.1 +StripNetModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_balanced_stripnet_unfrozen/pipeline.gin b/presets/gtauav_balanced_stripnet_unfrozen/pipeline.gin index 8b13789..c96c8e8 100644 --- a/presets/gtauav_balanced_stripnet_unfrozen/pipeline.gin +++ b/presets/gtauav_balanced_stripnet_unfrozen/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/balanced_stripnet_unfrozen' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_balanced_stripnet_unfrozen/tracking.gin b/presets/gtauav_balanced_stripnet_unfrozen/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_balanced_stripnet_unfrozen/tracking.gin +++ b/presets/gtauav_balanced_stripnet_unfrozen/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_balanced_stripnet_unfrozen/training.gin b/presets/gtauav_balanced_stripnet_unfrozen/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_balanced_stripnet_unfrozen/training.gin +++ b/presets/gtauav_balanced_stripnet_unfrozen/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_baseline/hardware.gin b/presets/gtauav_baseline/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_baseline/hardware.gin +++ b/presets/gtauav_baseline/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_baseline/models.gin b/presets/gtauav_baseline/models.gin index 8b13789..3d15595 100644 --- a/presets/gtauav_baseline/models.gin +++ b/presets/gtauav_baseline/models.gin @@ -1 +1,12 @@ +# DINOv3 shared encoder + MONA-12 + DGTRS-CLIP with text. +ModelsCommonConfig.backbone = 'dinov3' +ModelsCommonConfig.baseline_mode = True +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' +DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' +DINOv3ModelsConfig.shared_encoder = True +DINOv3ModelsConfig.mona_bottleneck = 64 +DINOv3ModelsConfig.mona_last_n_blocks = 12 +DINOv3ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_baseline/pipeline.gin b/presets/gtauav_baseline/pipeline.gin index 8b13789..50f53ed 100644 --- a/presets/gtauav_baseline/pipeline.gin +++ b/presets/gtauav_baseline/pipeline.gin @@ -1 +1,14 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/baseline_inbatch' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_baseline/tracking.gin b/presets/gtauav_baseline/tracking.gin index 8b13789..111a337 100644 --- a/presets/gtauav_baseline/tracking.gin +++ b/presets/gtauav_baseline/tracking.gin @@ -1 +1,15 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_baseline/training.gin b/presets/gtauav_baseline/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_baseline/training.gin +++ b/presets/gtauav_baseline/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_baseline_asym/hardware.gin b/presets/gtauav_baseline_asym/hardware.gin index 8b13789..dfc9be7 100644 --- a/presets/gtauav_baseline_asym/hardware.gin +++ b/presets/gtauav_baseline_asym/hardware.gin @@ -1 +1,9 @@ - +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_baseline_asym/models.gin b/presets/gtauav_baseline_asym/models.gin index 8b13789..60eb364 100644 --- a/presets/gtauav_baseline_asym/models.gin +++ b/presets/gtauav_baseline_asym/models.gin @@ -1 +1,12 @@ +# DINOv3 shared encoder + MONA-12 + DGTRS-CLIP with text. +ModelsCommonConfig.backbone = 'dinov3' +ModelsCommonConfig.baseline_mode = True +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' +DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' +DINOv3ModelsConfig.shared_encoder = False +DINOv3ModelsConfig.mona_bottleneck = 64 +DINOv3ModelsConfig.mona_last_n_blocks = 24 +DINOv3ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_baseline_asym/pipeline.gin b/presets/gtauav_baseline_asym/pipeline.gin index 8b13789..2017a42 100644 --- a/presets/gtauav_baseline_asym/pipeline.gin +++ b/presets/gtauav_baseline_asym/pipeline.gin @@ -1 +1,14 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/baseline_asym' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_baseline_asym/tracking.gin b/presets/gtauav_baseline_asym/tracking.gin index 8b13789..111a337 100644 --- a/presets/gtauav_baseline_asym/tracking.gin +++ b/presets/gtauav_baseline_asym/tracking.gin @@ -1 +1,15 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_baseline_asym/training.gin b/presets/gtauav_baseline_asym/training.gin index 8b13789..500f55e 100644 --- a/presets/gtauav_baseline_asym/training.gin +++ b/presets/gtauav_baseline_asym/training.gin @@ -1 +1,31 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_baseline_sofia/hardware.gin b/presets/gtauav_baseline_sofia/hardware.gin index 8b13789..51dd286 100644 --- a/presets/gtauav_baseline_sofia/hardware.gin +++ b/presets/gtauav_baseline_sofia/hardware.gin @@ -1 +1,10 @@ +# SOFIA v7.1 from-scratch — keep activations live (no gradient checkpointing). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = False +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_baseline_sofia/models.gin b/presets/gtauav_baseline_sofia/models.gin index 8b13789..5aa4334 100644 --- a/presets/gtauav_baseline_sofia/models.gin +++ b/presets/gtauav_baseline_sofia/models.gin @@ -1 +1,92 @@ +# SOFIA v7.1 Tiny preset (~5M params) with text fusion (Text-FiLM mid-level +# in SAT and UAV heads + GatedFusion late-level on descriptors). +# +# Tiny-specific notes: +# - num_heads_s3/s4 = 4 (channels 176/224 not divisible by 8) +# - mamba_headdim = 16 (channels not divisible by default 64) +# - mamba_variant = 'mamba1' (Mamba-2 torch fallback bug for these dims) +# - d_descriptor = 1024 (override from preset M default 512) +# - text fusion enabled (override from preset M default disabled) + +ModelsCommonConfig.backbone = 'sofia_v71' +ModelsCommonConfig.baseline_mode = True +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +# Variant label (informational). +SOFIAv71ModelsConfig.variant_label = 'Tiny' + +# Input. +SOFIAv71ModelsConfig.input_size = 256 +SOFIAv71ModelsConfig.in_channels = 3 + +# Stem (Tiny dims). +SOFIAv71ModelsConfig.stem_mid = 16 +SOFIAv71ModelsConfig.stem_out = 32 + +# Backbone dimensions (Tiny). +SOFIAv71ModelsConfig.embed_dims = [48, 96, 176, 224] +SOFIAv71ModelsConfig.depths = [2, 3, 4, 2] + +# Stage 1-2 block params (default). +SOFIAv71ModelsConfig.mbconv_expand = 4 +SOFIAv71ModelsConfig.se_ratio = 16 +SOFIAv71ModelsConfig.strip_kernel_s1 = 7 +SOFIAv71ModelsConfig.strip_kernel_s2 = 5 +SOFIAv71ModelsConfig.mix_kernels = [3, 5, 7] +SOFIAv71ModelsConfig.use_dcn_strip = True + +# Stage 3-4 (MambaVision). Tiny: mamba1 to bypass torch fallback bug. +SOFIAv71ModelsConfig.mamba_d_state = 16 +SOFIAv71ModelsConfig.mamba_dt_rank = None +SOFIAv71ModelsConfig.mamba_backend = 'auto' +SOFIAv71ModelsConfig.mamba_variant = 'mamba1' + +# Mamba-2 tunables (used when mamba_variant='mamba2'; Tiny would need +# headdim=16 because 176 % 64 != 0 and 224 % 64 != 0). +SOFIAv71ModelsConfig.mamba_d_state_mamba2 = 64 +SOFIAv71ModelsConfig.mamba_headdim = 16 +SOFIAv71ModelsConfig.mamba_expand = 2 +SOFIAv71ModelsConfig.mamba_d_conv = 4 +SOFIAv71ModelsConfig.mamba_n_directions = 2 + +# Heads / attention (Tiny: heads=4). +SOFIAv71ModelsConfig.num_heads_s3 = 4 +SOFIAv71ModelsConfig.num_heads_s4 = 4 +SOFIAv71ModelsConfig.use_strip_branch_s3 = True +SOFIAv71ModelsConfig.use_strip_branch_s4 = False +SOFIAv71ModelsConfig.ffn_expand = 4 + +# EVSS bridge (off by default). +SOFIAv71ModelsConfig.use_evss_bridge = False +SOFIAv71ModelsConfig.evss_bridge_locations = ['pre_stage3'] + +# Neck (Tiny). +SOFIAv71ModelsConfig.neck_channels = 128 + +# CVGL Head. +SOFIAv71ModelsConfig.d_descriptor = 1024 +SOFIAv71ModelsConfig.use_asymmetric_heads = True +SOFIAv71ModelsConfig.chp_rings = 8 +SOFIAv71ModelsConfig.chp_angles = 16 +SOFIAv71ModelsConfig.chp_harmonics = 4 +SOFIAv71ModelsConfig.use_film_altitude = True +SOFIAv71ModelsConfig.altitude_norm = 500.0 +SOFIAv71ModelsConfig.ring_count = 4 +SOFIAv71ModelsConfig.use_ring_aux = True + +# Text fusion enabled. +SOFIAv71ModelsConfig.return_normalized = True +SOFIAv71ModelsConfig.use_text_film_sat = True +SOFIAv71ModelsConfig.use_text_film_uav = True +SOFIAv71ModelsConfig.text_film_dim = 1024 +SOFIAv71ModelsConfig.text_film_hidden = 256 + +# Sharing / KD / deploy. +SOFIAv71ModelsConfig.share_stages_1_2 = True +SOFIAv71ModelsConfig.enable_kd_taps = True +SOFIAv71ModelsConfig.precision = 'fp16' + +# LoRA. +SOFIAv71ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_baseline_sofia/pipeline.gin b/presets/gtauav_baseline_sofia/pipeline.gin index 8b13789..227e5d2 100644 --- a/presets/gtauav_baseline_sofia/pipeline.gin +++ b/presets/gtauav_baseline_sofia/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/baseline_sofia' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_baseline_sofia/tracking.gin b/presets/gtauav_baseline_sofia/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_baseline_sofia/tracking.gin +++ b/presets/gtauav_baseline_sofia/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_baseline_sofia/training.gin b/presets/gtauav_baseline_sofia/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_baseline_sofia/training.gin +++ b/presets/gtauav_baseline_sofia/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_baseline_sofia_v1/hardware.gin b/presets/gtauav_baseline_sofia_v1/hardware.gin index 8b13789..1a58885 100644 --- a/presets/gtauav_baseline_sofia_v1/hardware.gin +++ b/presets/gtauav_baseline_sofia_v1/hardware.gin @@ -1 +1,9 @@ +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = False +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_baseline_sofia_v1/models.gin b/presets/gtauav_baseline_sofia_v1/models.gin index 8b13789..45049f9 100644 --- a/presets/gtauav_baseline_sofia_v1/models.gin +++ b/presets/gtauav_baseline_sofia_v1/models.gin @@ -1 +1,31 @@ +# SOFIA v1 'tiny' variant (~1M params) with text fusion (Text-FiLM mid-level +# in SAT and UAV heads + AltitudeFiLM in UAV head + GatedFusion late-level). + +ModelsCommonConfig.backbone = 'sofia_v1' +ModelsCommonConfig.baseline_mode = True +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +# Backbone. +SOFIAv1ModelsConfig.variant_label = 'tiny' +SOFIAv1ModelsConfig.in_channels = 3 +SOFIAv1ModelsConfig.input_size = 256 +SOFIAv1ModelsConfig.dcn_variant = 'v2' + +# Heads. +SOFIAv1ModelsConfig.d_descriptor = 1024 +SOFIAv1ModelsConfig.return_normalized = False + +# Altitude-FiLM. +SOFIAv1ModelsConfig.use_film_altitude = True +SOFIAv1ModelsConfig.altitude_norm = 500.0 + +# Text-FiLM. +SOFIAv1ModelsConfig.use_text_film_uav = True +SOFIAv1ModelsConfig.use_text_film_sat = True +SOFIAv1ModelsConfig.text_film_dim = 1024 +SOFIAv1ModelsConfig.text_film_hidden = 256 + +# LoRA on DGTRS-CLIP. +SOFIAv1ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_baseline_sofia_v1/pipeline.gin b/presets/gtauav_baseline_sofia_v1/pipeline.gin index 8b13789..dfcca01 100644 --- a/presets/gtauav_baseline_sofia_v1/pipeline.gin +++ b/presets/gtauav_baseline_sofia_v1/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/baseline_sofia_v1' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_baseline_sofia_v1/tracking.gin b/presets/gtauav_baseline_sofia_v1/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_baseline_sofia_v1/tracking.gin +++ b/presets/gtauav_baseline_sofia_v1/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_baseline_sofia_v1/training.gin b/presets/gtauav_baseline_sofia_v1/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_baseline_sofia_v1/training.gin +++ b/presets/gtauav_baseline_sofia_v1/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_baseline_stripnet/hardware.gin b/presets/gtauav_baseline_stripnet/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_baseline_stripnet/hardware.gin +++ b/presets/gtauav_baseline_stripnet/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_baseline_stripnet/models.gin b/presets/gtauav_baseline_stripnet/models.gin index 8b13789..f4ff726 100644 --- a/presets/gtauav_baseline_stripnet/models.gin +++ b/presets/gtauav_baseline_stripnet/models.gin @@ -1 +1,12 @@ +# StripNet small backbone (frozen) + Conv-MONA on last 2 stages. +ModelsCommonConfig.backbone = 'stripnet' +ModelsCommonConfig.baseline_mode = True +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +StripNetModelsConfig.stripnet_path = 'nn_models/STRIPNET/stripnet_s.pth' +StripNetModelsConfig.stripnet_freeze = True +StripNetModelsConfig.stripnet_mona_last_n_stages = 2 +StripNetModelsConfig.stripnet_backbone_lr_factor = 0.1 +StripNetModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_baseline_stripnet/pipeline.gin b/presets/gtauav_baseline_stripnet/pipeline.gin index 8b13789..6e878be 100644 --- a/presets/gtauav_baseline_stripnet/pipeline.gin +++ b/presets/gtauav_baseline_stripnet/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/baseline_stripnet' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_baseline_stripnet/tracking.gin b/presets/gtauav_baseline_stripnet/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_baseline_stripnet/tracking.gin +++ b/presets/gtauav_baseline_stripnet/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_baseline_stripnet/training.gin b/presets/gtauav_baseline_stripnet/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_baseline_stripnet/training.gin +++ b/presets/gtauav_baseline_stripnet/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_baseline_stripnet_unfrozen/hardware.gin b/presets/gtauav_baseline_stripnet_unfrozen/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_baseline_stripnet_unfrozen/hardware.gin +++ b/presets/gtauav_baseline_stripnet_unfrozen/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_baseline_stripnet_unfrozen/models.gin b/presets/gtauav_baseline_stripnet_unfrozen/models.gin index 8b13789..946cd69 100644 --- a/presets/gtauav_baseline_stripnet_unfrozen/models.gin +++ b/presets/gtauav_baseline_stripnet_unfrozen/models.gin @@ -1 +1,11 @@ +# StripNet small backbone (unfrozen) + Conv-MONA on last 2 stages. +ModelsCommonConfig.backbone = 'stripnet' +ModelsCommonConfig.baseline_mode = True +ModelsCommonConfig.init_gate = 0.7 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' +StripNetModelsConfig.stripnet_path = 'nn_models/STRIPNET/stripnet_s.pth' +StripNetModelsConfig.stripnet_freeze = False +StripNetModelsConfig.stripnet_mona_last_n_stages = 2 +StripNetModelsConfig.stripnet_backbone_lr_factor = 0.1 +StripNetModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_baseline_stripnet_unfrozen/pipeline.gin b/presets/gtauav_baseline_stripnet_unfrozen/pipeline.gin index 8b13789..1eb0d5c 100644 --- a/presets/gtauav_baseline_stripnet_unfrozen/pipeline.gin +++ b/presets/gtauav_baseline_stripnet_unfrozen/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/baseline_stripnet_unfrozen' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_baseline_stripnet_unfrozen/tracking.gin b/presets/gtauav_baseline_stripnet_unfrozen/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_baseline_stripnet_unfrozen/tracking.gin +++ b/presets/gtauav_baseline_stripnet_unfrozen/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_baseline_stripnet_unfrozen/training.gin b/presets/gtauav_baseline_stripnet_unfrozen/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_baseline_stripnet_unfrozen/training.gin +++ b/presets/gtauav_baseline_stripnet_unfrozen/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_image_heavy/hardware.gin b/presets/gtauav_image_heavy/hardware.gin index 8b13789..ab351a2 100644 --- a/presets/gtauav_image_heavy/hardware.gin +++ b/presets/gtauav_image_heavy/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_image_heavy/models.gin b/presets/gtauav_image_heavy/models.gin index 8b13789..439ebf8 100644 --- a/presets/gtauav_image_heavy/models.gin +++ b/presets/gtauav_image_heavy/models.gin @@ -1 +1,13 @@ +# DINOv3 shared encoder + MONA-12 + DGTRS-CLIP with text. +ModelsCommonConfig.backbone = 'dinov3' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.9 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' +DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' +DINOv3ModelsConfig.shared_encoder = True +DINOv3ModelsConfig.mona_bottleneck = 64 +DINOv3ModelsConfig.mona_last_n_blocks = 12 +DINOv3ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_image_heavy/pipeline.gin b/presets/gtauav_image_heavy/pipeline.gin index 8b13789..5745058 100644 --- a/presets/gtauav_image_heavy/pipeline.gin +++ b/presets/gtauav_image_heavy/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/image_heavy' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_image_heavy/tracking.gin b/presets/gtauav_image_heavy/tracking.gin index 8b13789..1442120 100644 --- a/presets/gtauav_image_heavy/tracking.gin +++ b/presets/gtauav_image_heavy/tracking.gin @@ -1 +1,16 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None + +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_image_heavy/training.gin b/presets/gtauav_image_heavy/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_image_heavy/training.gin +++ b/presets/gtauav_image_heavy/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/gtauav_text_heavy/hardware.gin b/presets/gtauav_text_heavy/hardware.gin index 8b13789..6ea808e 100644 --- a/presets/gtauav_text_heavy/hardware.gin +++ b/presets/gtauav_text_heavy/hardware.gin @@ -1 +1,10 @@ +# RTX 4090 profile, shared encoder (DINOv3). +HardwareConfig.device = 'cuda' +HardwareConfig.batch_size = 8 +HardwareConfig.grad_accum_steps = 8 +HardwareConfig.num_workers = 4 +HardwareConfig.use_amp = True +HardwareConfig.gradient_checkpointing = True +HardwareConfig.reserve_gb = 2.0 +HardwareConfig.total_vram_gb = 24.0 diff --git a/presets/gtauav_text_heavy/models.gin b/presets/gtauav_text_heavy/models.gin index 8b13789..b6d8c4f 100644 --- a/presets/gtauav_text_heavy/models.gin +++ b/presets/gtauav_text_heavy/models.gin @@ -1 +1,13 @@ +# DINOv3 shared encoder + MONA-12 + DGTRS-CLIP with text. +ModelsCommonConfig.backbone = 'dinov3' +ModelsCommonConfig.baseline_mode = False +ModelsCommonConfig.init_gate = 0.3 +ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' + +DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' +DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' +DINOv3ModelsConfig.shared_encoder = True +DINOv3ModelsConfig.mona_bottleneck = 64 +DINOv3ModelsConfig.mona_last_n_blocks = 12 +DINOv3ModelsConfig.lora_rank = 4 diff --git a/presets/gtauav_text_heavy/pipeline.gin b/presets/gtauav_text_heavy/pipeline.gin index 8b13789..5cc13c8 100644 --- a/presets/gtauav_text_heavy/pipeline.gin +++ b/presets/gtauav_text_heavy/pipeline.gin @@ -1 +1,15 @@ +# Pipeline: GTA-UAV-LR with text captions, servml workstation paths. +PipelineConfig.train_json = 'meta/train_80.json' +PipelineConfig.test_json = 'meta/test_20.json' +PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' +PipelineConfig.filter_meta = 'meta/seg_filter.json' + +PipelineConfig.epochs = 10 +PipelineConfig.warmup_epochs = 2 +PipelineConfig.eval_every = 1 +PipelineConfig.seed = 42 + +PipelineConfig.output_dir = 'out/gtauav/text_heavy' +PipelineConfig.resume_from = None diff --git a/presets/gtauav_text_heavy/tracking.gin b/presets/gtauav_text_heavy/tracking.gin index 8b13789..111a337 100644 --- a/presets/gtauav_text_heavy/tracking.gin +++ b/presets/gtauav_text_heavy/tracking.gin @@ -1 +1,15 @@ +# Default tracking: TensorBoard on, W&B off, no Grad-CAM, no profiler. +TrackingConfig.use_wandb = False +TrackingConfig.use_tb = True +TrackingConfig.wandb_project = 'caption-test-gtauav' +TrackingConfig.wandb_run_name = None +TrackingConfig.wandb_entity = None +TrackingConfig.log_grad_norms = True +TrackingConfig.use_gradcam = False +TrackingConfig.gradcam_every = 5 +TrackingConfig.gradcam_samples = 8 + +TrackingConfig.use_profiler = False +TrackingConfig.profiler_warmup = 3 +TrackingConfig.profiler_active = 5 diff --git a/presets/gtauav_text_heavy/training.gin b/presets/gtauav_text_heavy/training.gin index 8b13789..ffb8c32 100644 --- a/presets/gtauav_text_heavy/training.gin +++ b/presets/gtauav_text_heavy/training.gin @@ -1 +1,32 @@ +# Loss + optimizer + sampler — symmetric InfoNCE, AdamW, mutex sampler. +TrainingConfig.loss_type = 'symmetric' +TrainingConfig.tau_init = 0.07 +TrainingConfig.tau_min = 0.01 +TrainingConfig.tau_max = 0.1 +TrainingConfig.learnable_temperature = True +TrainingConfig.label_smoothing = 0.1 + +TrainingConfig.tau_final = 0.01 +TrainingConfig.weight_q2g = 0.6 +TrainingConfig.weight_g2q = 0.4 +TrainingConfig.hard_mining_k = 0 +TrainingConfig.neg_bank_size = 0 + +# WeightedInfoNCE-only (unused when loss_type='symmetric'). +TrainingConfig.weighted_loss_k = 5.0 + +TrainingConfig.learning_rate = 1e-4 +TrainingConfig.text_lr_factor = 0.1 +TrainingConfig.weight_decay = 1e-4 +TrainingConfig.grad_clip = 1.0 + +TrainingConfig.sampler_type = 'mutex' +TrainingConfig.dss_warmup_epochs = 1 +TrainingConfig.dss_reembed_every = 1 +TrainingConfig.dss_knn_device = 'cuda' +TrainingConfig.dss_use_lsh = False +TrainingConfig.dss_lsh_num_tables = 8 +TrainingConfig.dss_lsh_num_bits = 14 +TrainingConfig.dss_cache_dir = None +TrainingConfig.use_mutex_sampler = True diff --git a/presets/preprocess/preprocess.gin b/presets/preprocess/preprocess.gin index 8b13789..b42c8bf 100644 --- a/presets/preprocess/preprocess.gin +++ b/presets/preprocess/preprocess.gin @@ -1 +1,20 @@ +# Preprocessing config used by scripts/make_split.py and +# scripts/filter_segmentation.py. Independent from training pipeline. +# Inputs. +PreprocessConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' +PreprocessConfig.segm_root = '/home/servml/Документы/datasets/GTA-UAV-LR-aug/segm' + +# make_split.py — 80/20 split with seed=42. +PreprocessConfig.split_ratio = 0.8 +PreprocessConfig.split_seed = 42 +PreprocessConfig.split_input_train = 'cross-area-drone2sate-train.json' +PreprocessConfig.split_input_test = 'cross-area-drone2sate-test.json' +PreprocessConfig.split_output_dir = 'meta' +PreprocessConfig.split_output_train = 'train_80.json' +PreprocessConfig.split_output_test = 'test_20.json' + +# filter_segmentation.py — exclude images with >=90% background+water. +PreprocessConfig.seg_threshold = 0.90 +PreprocessConfig.seg_exclude_classes = [0, 4] +PreprocessConfig.seg_filter_output = 'meta/seg_filter.json' diff --git a/refactor_v3_plan.md b/refactor_v3_plan.md deleted file mode 100644 index a571fe3..0000000 --- a/refactor_v3_plan.md +++ /dev/null @@ -1,942 +0,0 @@ -# Шаг 2 — План разделения с диффами - -> Решения, на которых строится этот план: -> 1. **Плоские `.gin`** без `include` — каждый эксперимент = самодостаточный набор файлов -> 2. **`TrainConfigGTAUAV` разделяем сразу** -> 3. **Отдельные `ModelsConfig`-классы на каждый бэкбон** (DINOv3, StripNet, SOFIAv1, SOFIAv71) -> 4. **Скрипты переводим на gin** -> -> Этот документ — **план**, не финальный полный набор диффов. Он отвечает на вопрос «какие конфиг-классы будут, какие гин-файлы, какая иерархия пресетов». Для каждого нового файла — содержимое. Для каждого правимого файла — diff. Это ответ на вопрос «что делать с конфигом», без переписывания `Trainer` (это будет следующим шагом). - ---- - -## Часть A — Раскладка `TrainConfigGTAUAV` по 4 «универсальным» конфигам - -`TrainConfigGTAUAV` содержит 50+ полей. Разделяю их по принципу из «Рекомендуемые_gin-config_категории.md» (одна ось изменчивости = один конфиг): - -| Поле текущего `TrainConfigGTAUAV` | Куда едет | -|---|---| -| `train_json`, `test_json`, `rgb_root`, `caption_root`, `filter_meta`, `output_dir`, `resume_from`, `epochs`, `eval_every`, `warmup_epochs`, `seed` | **`PipelineConfig`** | -| `batch_size`, `num_workers`, `grad_accum_steps`, `use_amp`, `gradient_checkpointing`, `device` | **`HardwareConfig`** | -| `loss_type`, `tau_init`, `label_smoothing`, `learnable_temperature`, `weight_q2g`, `weight_g2q`, `neg_bank_size`, `learning_rate`, `text_lr_factor`, `weight_decay`, `grad_clip`, `sampler_type`, `dss_*`, `use_mutex_sampler` | **`TrainingConfig`** | -| `use_wandb`, `use_tb`, `wandb_project`, `wandb_run_name`, `wandb_entity`, `log_grad_norms`, `use_gradcam`, `gradcam_every`, `gradcam_samples`, `use_profiler`, `profiler_warmup`, `profiler_active` | **`TrackingConfig`** | -| `dino_web_path`, `dino_sat_path`, `lrsclip_path`, `init_gate`, `baseline_mode`, `shared_encoder`, `mona_bottleneck`, `mona_last_n_blocks`, `backbone`, `stripnet_path`, `stripnet_mona_last_n_stages`, `stripnet_freeze`, `stripnet_backbone_lr_factor` | **`Models*Config`** (см. Часть B) | - -**Итого 4 «универсальных» конфига** (Pipeline / Hardware / Training / Tracking) + плюс семейство Models-классов из Части B. - ---- - -## Часть B — Семейство `Models*Config` (по бэкбону) - -Каждый бэкбон → собственный gin-configurable класс. **Один на эксперимент** — какой именно загружается, определяется тем, какой `models_*.gin` положен в директорию пресета. - -### `ModelsCommonConfig` — общие поля - -Поля, нужные **всем** бэкбонам: - -```python -@gin.configurable -class ModelsCommonConfig: - """Common architecture switches shared by all backbones.""" - def __init__( - self, - backbone: str = "dinov3", # 'dinov3' | 'stripnet' | 'sofia_v1' | 'sofia_v71' - baseline_mode: bool = False, # text disabled, gate forced 1.0 - init_gate: float = 0.7, - lrsclip_path: str = "nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt", - ) -> None: - self.backbone = backbone - self.baseline_mode = baseline_mode - self.init_gate = init_gate - self.lrsclip_path = lrsclip_path -``` - -### `DINOv3ModelsConfig` - -```python -@gin.configurable -class DINOv3ModelsConfig: - def __init__( - self, - dino_web_path: str = "nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth", - dino_sat_path: str = "nn_models/DINO_SAT/model.safetensors", - shared_encoder: bool = True, - mona_bottleneck: int = 64, - mona_last_n_blocks: int = 12, - ) -> None: - self.dino_web_path = dino_web_path - self.dino_sat_path = dino_sat_path - self.shared_encoder = shared_encoder - self.mona_bottleneck = mona_bottleneck - self.mona_last_n_blocks = mona_last_n_blocks -``` - -### `StripNetModelsConfig` - -```python -@gin.configurable -class StripNetModelsConfig: - def __init__( - self, - stripnet_path: str = "nn_models/STRIPNET/stripnet_s.pth", - stripnet_freeze: bool = True, - stripnet_mona_last_n_stages: int = 2, - stripnet_backbone_lr_factor: float = 0.1, - ) -> None: - self.stripnet_path = stripnet_path - self.stripnet_freeze = stripnet_freeze - self.stripnet_mona_last_n_stages = stripnet_mona_last_n_stages - self.stripnet_backbone_lr_factor = stripnet_backbone_lr_factor -``` - -### `SOFIAv1ModelsConfig` - -Покрывает всё, что сейчас в `src/models/sofia_v1/config.py::SOFIAv1Config`: - -```python -@gin.configurable -class SOFIAv1ModelsConfig: - def __init__( - self, - # Backbone. - variant: str = "small", # 'tiny_tiny' | 'tiny' | 'small' | 'small_v2' - in_channels: int = 3, - input_size: int = 256, - dcn_variant: str = "v2", # 'v2' (stable) | 'v4' (faster, leaks) - # Heads. - d_descriptor: int = 1024, - return_normalized: bool = False, - # Altitude-FiLM. - use_film_altitude: bool = True, - altitude_norm: float = 500.0, - # Text-FiLM. - use_text_film_uav: bool = True, - use_text_film_sat: bool = True, - text_film_dim: int = 1024, - text_film_hidden: int = 256, - ) -> None: - self.variant = variant - self.in_channels = in_channels - self.input_size = input_size - self.dcn_variant = dcn_variant - self.d_descriptor = d_descriptor - self.return_normalized = return_normalized - self.use_film_altitude = use_film_altitude - self.altitude_norm = altitude_norm - self.use_text_film_uav = use_text_film_uav - self.use_text_film_sat = use_text_film_sat - self.text_film_dim = text_film_dim - self.text_film_hidden = text_film_hidden -``` - -> **`SOFIAv1Config` (`@dataclass`) в `src/models/sofia_v1/config.py` остаётся** — это внутренняя структура для модели. В `Trainer._build_model` создаём `SOFIAv1Config(...)` из полей `models_cfg` (где `models_cfg: SOFIAv1ModelsConfig`). Один источник правды — gin, а dataclass это просто адаптер на границе модельного слоя. - -### `SOFIAv71ModelsConfig` - -Покрывает поля из `src/models/sofia_v71/config.py`. По README вижу: - -```python -@gin.configurable -class SOFIAv71ModelsConfig: - def __init__( - self, - # Preset. - preset: str = "M", # 'M' | 'L' | 'Tiny' - # Mamba backend. - mamba_variant: str = "mamba2", # 'mamba1' | 'mamba2' | 'efficient_vmamba' - mamba_backend: str = "auto", # 'auto' | 'torch' - # Heads. - d_descriptor: int = 512, - # Altitude-FiLM. - use_film_altitude: bool = True, - altitude_norm: float = 500.0, - # KD taps. - return_features: bool = False, - # Quantization (PTQ/QAT — for production deploy, not training). - # Not adding here unless an experiment toggles them; can be added later. - ) -> None: - self.preset = preset - self.mamba_variant = mamba_variant - self.mamba_backend = mamba_backend - self.d_descriptor = d_descriptor - self.use_film_altitude = use_film_altitude - self.altitude_norm = altitude_norm - self.return_features = return_features -``` - -> ⚠️ Точные поля `SOFIAv71` нужно сверить с `src/models/sofia_v71/config.py` (я его не открыл целиком). Это **открытый пункт** — заполняется при создании файла. - -### Как загружать «правильный» Models config? - -Ровно один `models.gin` лежит в директории пресета и определяет один из 4 классов. `config_loader` ветвится: - -```python -def load_all_configs(path2cfg: str) -> dict[str, Any]: - cfg_dir = Path(path2cfg) - gin.clear_config() - gin.parse_config_files_and_bindings( - config_files=[str(f) for f in sorted(cfg_dir.glob("*.gin"))], - bindings=[], - ) - - # Build common first to learn which backbone to use. - common = ModelsCommonConfig() - backbone_to_cls = { - "dinov3": DINOv3ModelsConfig, - "stripnet": StripNetModelsConfig, - "sofia_v1": SOFIAv1ModelsConfig, - "sofia_v71": SOFIAv71ModelsConfig, - } - if common.backbone not in backbone_to_cls: - raise ValueError( - f"Unknown backbone={common.backbone!r}; expected one of {list(backbone_to_cls)}", - ) - models_specific = backbone_to_cls[common.backbone]() # gin fills it - - return { - "pipeline": PipelineConfig(), - "hardware": HardwareConfig(), - "models_common": common, - "models": models_specific, # one of 4 classes - "training": TrainingConfig(), - "tracking": TrackingConfig(), - } -``` - -**В `models.gin` пресета** прописаны биндинги **только** для активного бэкбона + `ModelsCommonConfig`. Биндинги для других бэкбонов в этот файл не попадают (плоский стиль). - ---- - -## Часть C — Конфиг для скриптов препроцессинга (Часть 4 ваших ответов) - -Скрипты `make_split.py` и `filter_segmentation.py` переводятся на gin. Возникает **5-й универсальный конфиг**: - -### `PreprocessConfig` - -```python -@gin.configurable -class PreprocessConfig: - """Preprocessing utilities: train/test split + segmentation filter. - - Used only by scripts/make_split.py and scripts/filter_segmentation.py. - Not consumed by the training pipeline directly. - """ - def __init__( - self, - # Inputs (read from PipelineConfig if you want consistency, but having - # them here lets preprocess run independently). - rgb_root: str = "/home/servml/Документы/datasets/GTA-UAV-LR", - segm_root: str = "/home/servml/Документы/datasets/GTA-UAV-LR-aug/segm", - # make_split params. - split_ratio: float = 0.8, - split_seed: int = 42, - split_input_train: str = "cross-area-drone2sate-train.json", - split_input_test: str = "cross-area-drone2sate-test.json", - split_output_dir: str = "meta", - split_output_train: str = "train_80.json", - split_output_test: str = "test_20.json", - # filter_segmentation params. - seg_threshold: float = 0.90, - seg_exclude_classes: list[int] | None = None, # default [0, 4] - seg_filter_output: str = "meta/seg_filter.json", - ) -> None: - self.rgb_root = rgb_root - self.segm_root = segm_root - self.split_ratio = split_ratio - self.split_seed = split_seed - self.split_input_train = split_input_train - self.split_input_test = split_input_test - self.split_output_dir = split_output_dir - self.split_output_train = split_output_train - self.split_output_test = split_output_test - self.seg_threshold = seg_threshold - self.seg_exclude_classes = seg_exclude_classes or [0, 4] - self.seg_filter_output = seg_filter_output -``` - -> **Вопрос дизайна:** держать `rgb_root` отдельно в `PreprocessConfig` (как выше) или брать из `PipelineConfig.rgb_root`? -> -> **Решение:** держать **отдельно**, потому что `PreprocessConfig` живёт в **другом** наборе .gin (отдельный пресет `preprocess/`). Это согласуется с принципом плоских конфигов без ссылок между файлами. Дублирование одного пути на 2 файла — приемлемая цена за изоляцию. - ---- - -## Часть D — Что и где будет лежать (структура каталогов) - -``` -caption-test/ -├── in/ -│ └── config_files/ # АКТИВНЫЙ пресет, копируется из presets/ -│ ├── pipeline.gin -│ ├── hardware.gin -│ ├── models.gin # биндинги ModelsCommonConfig + одного из Models*Config -│ ├── training.gin -│ └── tracking.gin -├── presets/ -│ ├── gtauav_balanced/ # все 5 файлов, БЕЗ include -│ │ ├── pipeline.gin -│ │ ├── hardware.gin -│ │ ├── models.gin # backbone='dinov3', shared, mona_12 -│ │ ├── training.gin -│ │ └── tracking.gin -│ ├── gtauav_baseline/ # 5 файлов, baseline_mode=True -│ ├── gtauav_balanced_asym/ # shared_encoder=False, mona_24 -│ ├── gtauav_baseline_asym/ -│ ├── gtauav_balanced_stripnet/ # backbone='stripnet' -│ ├── gtauav_balanced_stripnet_unfrozen/ -│ ├── gtauav_baseline_stripnet/ -│ ├── gtauav_baseline_stripnet_unfrozen/ -│ ├── gtauav_text_heavy/ # init_gate=0.3 -│ ├── gtauav_image_heavy/ # init_gate=0.9 -│ ├── gtauav_balanced_sofia/ # backbone='sofia_v71' -│ ├── gtauav_balanced_sofia_v1/ # backbone='sofia_v1' -│ ├── gtauav_baseline_sofia/ -│ ├── gtauav_baseline_sofia_v1/ -│ └── preprocess/ # отдельный пресет для скриптов -│ └── preprocess.gin # PreprocessConfig.* — одиночный файл достаточен -├── src/ -│ └── conf/ -│ ├── __init__.py -│ ├── pipeline_conf.py # PipelineConfig + get_pipeline_cfg -│ ├── hardware_conf.py # HardwareConfig + get_hardware_cfg -│ ├── training_conf.py # TrainingConfig + get_training_cfg -│ ├── tracking_conf.py # TrackingConfig + get_tracking_cfg -│ ├── models_common_conf.py # ModelsCommonConfig + get_models_common_cfg -│ ├── models_dinov3_conf.py # DINOv3ModelsConfig + get_models_dinov3_cfg -│ ├── models_stripnet_conf.py # StripNetModelsConfig + get_models_stripnet_cfg -│ ├── models_sofia_v1_conf.py # SOFIAv1ModelsConfig + get_models_sofia_v1_cfg -│ ├── models_sofia_v71_conf.py # SOFIAv71ModelsConfig + get_models_sofia_v71_cfg -│ ├── preprocess_conf.py # PreprocessConfig + get_preprocess_cfg -│ └── config_loader.py # load_all_configs() с разводкой по backbone -``` - ---- - -## Часть E — Содержимое `presets/gtauav_balanced/` (точно) - -Это эталонный пресет — остальные диффятся от него. - -### `presets/gtauav_balanced/pipeline.gin` - -```gin -# What to train on, where to save, schedule. -PipelineConfig.train_json = 'meta/train_80.json' -PipelineConfig.test_json = 'meta/test_20.json' -PipelineConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' -PipelineConfig.caption_root = '/home/servml/Документы/datasets/GTA-UAV-LR-captions' -PipelineConfig.filter_meta = None -PipelineConfig.output_dir = 'out/gtauav/with_text' -PipelineConfig.resume_from = None -PipelineConfig.epochs = 10 -PipelineConfig.warmup_epochs = 2 -PipelineConfig.eval_every = 1 -PipelineConfig.seed = 42 -``` - -### `presets/gtauav_balanced/hardware.gin` - -```gin -# RTX 4090 profile. -HardwareConfig.device = 'cuda' -HardwareConfig.batch_size = 8 -HardwareConfig.grad_accum_steps = 8 -HardwareConfig.num_workers = 4 -HardwareConfig.use_amp = True -HardwareConfig.gradient_checkpointing = True -HardwareConfig.reserve_gb = 2.0 -``` - -### `presets/gtauav_balanced/models.gin` - -```gin -# DINOv3 shared encoder + MONA in last 12 of 24 blocks + DGTRS-CLIP text. -ModelsCommonConfig.backbone = 'dinov3' -ModelsCommonConfig.baseline_mode = False -ModelsCommonConfig.init_gate = 0.7 -ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' - -DINOv3ModelsConfig.dino_web_path = 'nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth' -DINOv3ModelsConfig.dino_sat_path = 'nn_models/DINO_SAT/model.safetensors' -DINOv3ModelsConfig.shared_encoder = True -DINOv3ModelsConfig.mona_bottleneck = 64 -DINOv3ModelsConfig.mona_last_n_blocks = 12 -``` - -### `presets/gtauav_balanced/training.gin` - -```gin -# Loss + optimizer + sampler. -TrainingConfig.loss_type = 'symmetric' -TrainingConfig.tau_init = 0.07 -TrainingConfig.label_smoothing = 0.1 -TrainingConfig.learnable_temperature = True -TrainingConfig.weight_q2g = 0.6 -TrainingConfig.weight_g2q = 0.4 -TrainingConfig.neg_bank_size = 0 - -TrainingConfig.learning_rate = 1e-4 -TrainingConfig.text_lr_factor = 0.1 -TrainingConfig.weight_decay = 1e-4 -TrainingConfig.grad_clip = 1.0 - -TrainingConfig.sampler_type = 'mutex' -TrainingConfig.dss_warmup_epochs = 1 -TrainingConfig.dss_reembed_every = 1 -TrainingConfig.dss_knn_device = 'cuda' -TrainingConfig.dss_use_lsh = False -TrainingConfig.dss_lsh_num_tables = 8 -TrainingConfig.dss_lsh_num_bits = 14 -TrainingConfig.dss_cache_dir = None -TrainingConfig.use_mutex_sampler = True -``` - -### `presets/gtauav_balanced/tracking.gin` - -```gin -TrackingConfig.use_wandb = False -TrackingConfig.use_tb = True -TrackingConfig.wandb_project = 'caption-test-gtauav' -TrackingConfig.wandb_run_name = None -TrackingConfig.wandb_entity = None -TrackingConfig.log_grad_norms = True -TrackingConfig.use_gradcam = False -TrackingConfig.gradcam_every = 5 -TrackingConfig.gradcam_samples = 8 -TrackingConfig.use_profiler = False -TrackingConfig.profiler_warmup = 3 -TrackingConfig.profiler_active = 5 -``` - ---- - -## Часть F — Дельты остальных пресетов от `gtauav_balanced/` - -Каждый пресет — **полная копия** `gtauav_balanced/` с точечными изменениями в указанных файлах. Никакого `include`. - -### `gtauav_baseline/` - -**Дельта от `gtauav_balanced/`:** - -`pipeline.gin`: -```gin -PipelineConfig.output_dir = 'out/gtauav/baseline_inbatch' -``` - -`models.gin`: -```gin -ModelsCommonConfig.baseline_mode = True -``` - -`training.gin`: -```gin -TrainingConfig.sampler_type = 'mutex' # was already, kept explicit per diagnostic notes in old conf/gtauav_baseline.gin -TrainingConfig.neg_bank_size = 0 # explicitly disabled (no MoCo queue) -``` - -(Остальные 3 файла — побайтовая копия из `gtauav_balanced/`.) - -### `gtauav_balanced_asym/` - -`pipeline.gin`: -```gin -PipelineConfig.output_dir = 'out/gtauav/balanced_asym' -``` - -`models.gin`: -```gin -DINOv3ModelsConfig.shared_encoder = False -DINOv3ModelsConfig.mona_last_n_blocks = 24 -``` - -### `gtauav_baseline_asym/` - -Объединяет дельту `gtauav_baseline/` и `gtauav_balanced_asym/`: - -`pipeline.gin`: `output_dir = 'out/gtauav/baseline_asym'` -`models.gin`: `baseline_mode = True`, `shared_encoder = False`, `mona_last_n_blocks = 24` - -### `gtauav_balanced_stripnet/` - -`pipeline.gin`: `output_dir = 'out/gtauav/balanced_stripnet'` - -`models.gin` (полностью): -```gin -ModelsCommonConfig.backbone = 'stripnet' -ModelsCommonConfig.baseline_mode = False -ModelsCommonConfig.init_gate = 0.7 -ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' - -StripNetModelsConfig.stripnet_path = 'nn_models/STRIPNET/stripnet_s.pth' -StripNetModelsConfig.stripnet_freeze = True -StripNetModelsConfig.stripnet_mona_last_n_stages = 2 -StripNetModelsConfig.stripnet_backbone_lr_factor = 0.1 -``` - -(Биндинги `DINOv3ModelsConfig.*` НЕ попадают в этот файл — другой бэкбон.) - -### `gtauav_balanced_stripnet_unfrozen/` - -Дельта от `gtauav_balanced_stripnet/`: - -`pipeline.gin`: `output_dir = 'out/gtauav/balanced_stripnet_unfrozen'` -`models.gin`: `StripNetModelsConfig.stripnet_freeze = False` - -### `gtauav_baseline_stripnet/`, `gtauav_baseline_stripnet_unfrozen/` - -Аналогично — `baseline_mode = True` поверх stripnet-вариантов. - -### `gtauav_text_heavy/`, `gtauav_image_heavy/` - -`pipeline.gin`: соответствующие `output_dir` -`models.gin`: `ModelsCommonConfig.init_gate = 0.3` (text-heavy) или `0.9` (image-heavy) - -### `gtauav_balanced_sofia_v1/` - -`pipeline.gin`: `output_dir = 'out/gtauav/balanced_sofia_v1'` - -`models.gin` (полностью): -```gin -ModelsCommonConfig.backbone = 'sofia_v1' -ModelsCommonConfig.baseline_mode = False -ModelsCommonConfig.init_gate = 0.7 -ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' - -SOFIAv1ModelsConfig.variant = 'small' -SOFIAv1ModelsConfig.in_channels = 3 -SOFIAv1ModelsConfig.input_size = 256 -SOFIAv1ModelsConfig.dcn_variant = 'v2' -SOFIAv1ModelsConfig.d_descriptor = 1024 -SOFIAv1ModelsConfig.return_normalized = False -SOFIAv1ModelsConfig.use_film_altitude = True -SOFIAv1ModelsConfig.altitude_norm = 500.0 -SOFIAv1ModelsConfig.use_text_film_uav = True -SOFIAv1ModelsConfig.use_text_film_sat = True -SOFIAv1ModelsConfig.text_film_dim = 1024 -SOFIAv1ModelsConfig.text_film_hidden = 256 -``` - -### `gtauav_balanced_sofia/` (= sofia_v71) - -`pipeline.gin`: `output_dir = 'out/gtauav/balanced_sofia'` - -`models.gin`: -```gin -ModelsCommonConfig.backbone = 'sofia_v71' -ModelsCommonConfig.baseline_mode = False -ModelsCommonConfig.init_gate = 0.7 -ModelsCommonConfig.lrsclip_path = 'nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt' - -SOFIAv71ModelsConfig.preset = 'M' -SOFIAv71ModelsConfig.mamba_variant = 'mamba2' -SOFIAv71ModelsConfig.mamba_backend = 'auto' -SOFIAv71ModelsConfig.d_descriptor = 512 -SOFIAv71ModelsConfig.use_film_altitude = True -SOFIAv71ModelsConfig.altitude_norm = 500.0 -SOFIAv71ModelsConfig.return_features = False -``` - -> ⚠️ Точные дефолты для sofia_v71 пресета зависят от того, как сейчас выглядит `gtauav_balanced_sofia.gin` в локальной копии. **Нужны сами файлы**, чтобы воспроизвести один-в-один. - -### `gtauav_baseline_sofia/`, `gtauav_baseline_sofia_v1/` - -`baseline_mode = True` поверх sofia-вариантов. - ---- - -## Часть G — `presets/preprocess/preprocess.gin` - -Один файл (одиночный, потому что один класс): - -```gin -PreprocessConfig.rgb_root = '/home/servml/Документы/datasets/GTA-UAV-LR' -PreprocessConfig.segm_root = '/home/servml/Документы/datasets/GTA-UAV-LR-aug/segm' - -PreprocessConfig.split_ratio = 0.8 -PreprocessConfig.split_seed = 42 -PreprocessConfig.split_input_train = 'cross-area-drone2sate-train.json' -PreprocessConfig.split_input_test = 'cross-area-drone2sate-test.json' -PreprocessConfig.split_output_dir = 'meta' -PreprocessConfig.split_output_train = 'train_80.json' -PreprocessConfig.split_output_test = 'test_20.json' - -PreprocessConfig.seg_threshold = 0.90 -PreprocessConfig.seg_exclude_classes = [0, 4] -PreprocessConfig.seg_filter_output = 'meta/seg_filter.json' -``` - ---- - -## Часть H — Диффы для существующих файлов - -> Здесь только то, что нужно поменять **в конфигурационной части**. Внутренности `Trainer`, `_evaluate`, `CSVLogger` — не трогаются на этом шаге. - -### Файл: `src/training/train_gtauav.py` - -**Полностью убрать `TrainConfigGTAUAV` и module-level path constants.** Функция `train()` получает не `cfg: TrainConfigGTAUAV`, а пять config-объектов. - -```diff - from __future__ import annotations - ... -- import argparse - ... -- from dataclasses import dataclass, field -- from pathlib import Path -+ from pathlib import Path - -- import gin - ... -- # Default paths. -- _RGB_ROOT = "/home/servml/Документы/datasets/GTA-UAV-LR" -- _CAPTION_ROOT = "/home/servml/Документы/datasets/GTA-UAV-LR-captions" -- _TRAIN_JSON = "meta/train_80.json" -- _TEST_JSON = "meta/test_20.json" -- -- _DINO_WEB = "nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth" -- _DINO_SAT = "nn_models/DINO_SAT/model.safetensors" -- _LRSCLIP = "nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt" -- -- -- @gin.configurable(module="src.training.train_gtauav") -- @dataclass -- class TrainConfigGTAUAV: -- """Training configuration for GTA-UAV experiment.""" -- # Data. -- train_json: str = _TRAIN_JSON -- test_json: str = _TEST_JSON -- rgb_root: str = _RGB_ROOT -- # ... ВСЕ 50+ полей удаляются ... -- profiler_active: int = 5 -- -- -- def train(cfg: TrainConfigGTAUAV) -> None: -+ def train( -+ pipeline_cfg: "PipelineConfig", -+ hardware_cfg: "HardwareConfig", -+ models_common_cfg: "ModelsCommonConfig", -+ models_cfg: "DINOv3ModelsConfig | StripNetModelsConfig | SOFIAv1ModelsConfig | SOFIAv71ModelsConfig", -+ training_cfg: "TrainingConfig", -+ tracking_cfg: "TrackingConfig", -+ ) -> None: - """Run full training loop.""" - # Inside the function body, every `cfg.` reference is rewritten to - # the appropriate _cfg.. Mapping: - # cfg.train_json → pipeline_cfg.train_json - # cfg.batch_size → hardware_cfg.batch_size - # cfg.tau_init → training_cfg.tau_init - # cfg.use_wandb → tracking_cfg.use_wandb - # cfg.dino_web_path → models_cfg.dino_web_path (when DINOv3) - # cfg.stripnet_path → models_cfg.stripnet_path (when StripNet) - # cfg.backbone → models_common_cfg.backbone - # cfg.baseline_mode → models_common_cfg.baseline_mode - # cfg.init_gate → models_common_cfg.init_gate - # cfg.lrsclip_path → models_common_cfg.lrsclip_path - ... - -- def main() -> None: -- parser = argparse.ArgumentParser(description="GTA-UAV caption test training.") -- parser.add_argument("--config", type=str, default=None, ...) -- parser.add_argument("--baseline", action="store_true", ...) -- # ... все 15 argparse флагов удаляются ... -- args = parser.parse_args() -- -- if args.config is not None: -- gin.parse_config_file(args.config) -- if args.gin_param: -- gin.parse_config(args.gin_param) -- -- cfg = TrainConfigGTAUAV() -- -- if args.baseline: -- cfg.baseline_mode = True -- # ... все CLI overrides удаляются ... -- train(cfg) -+ def main() -> None: -+ """Entry point: read configs from in/config_files/ and run training.""" -+ from src.conf.config_loader import load_all_configs -+ from src.utils.path_utils import get_proj_dir -+ -+ proj_dir = get_proj_dir() -+ path2cfg = f"{proj_dir}in/config_files/" -+ configs = load_all_configs(path2cfg) -+ -+ train( -+ pipeline_cfg=configs["pipeline"], -+ hardware_cfg=configs["hardware"], -+ models_common_cfg=configs["models_common"], -+ models_cfg=configs["models"], -+ training_cfg=configs["training"], -+ tracking_cfg=configs["tracking"], -+ ) -``` - -### Файл: `src/losses/multi_infonce.py` - -Снять `@gin.configurable` (см. Шаг 1, Нарушение #2). Параметры будут приходить из `TrainingConfig` через явный вызов в `train()`: - -```diff - from __future__ import annotations - ... - import math - -- import gin - import torch - ... - -- @gin.configurable - class InfoNCELoss(nn.Module): - """Symmetric InfoNCE with learnable or scheduled temperature. -+ -+ Note: NOT @gin.configurable. Parameters arrive explicitly from -+ train() via TrainingConfig.* — single source of truth. - ... - """ -``` - -### Файл: `src/losses/weighted_infonce.py` - -Аналогично: - -```diff - ... -- import gin - import torch - ... - -- @gin.configurable - class WeightedInfoNCELoss(nn.Module): - """Weighted InfoNCE with adaptive per-sample label smoothing. -+ -+ Note: NOT @gin.configurable. Parameters arrive explicitly from -+ train() via TrainingConfig.* — single source of truth. - ... - """ -``` - -### Файл: `src/datasets/visloc_with_captions.py` (legacy v2) - -Аналогично — снять `@gin.configurable` с `GeoLocCaptionDataset`. Если v2 удаляется как ветка — этот файл удаляется целиком, дифф не нужен. - -```diff -- import gin - ... - -- @gin.configurable - class GeoLocCaptionDataset(Dataset): - ... -``` - -### Файл: `src/datasets/gtauav_dataset.py` - -Убрать module-level пути. `rgb_root` и `caption_root` становятся обязательными в `__init__` — они придут из `pipeline_cfg.rgb_root` / `pipeline_cfg.caption_root` в `train()`. - -```diff - ... -- # Default paths. -- _RGB_ROOT = Path("/home/servml/Документы/datasets/GTA-UAV-LR") -- _CAPTION_ROOT = Path("/home/servml/Документы/datasets/GTA-UAV-LR-captions") - _EMPTY_CAPTION = "" - ... - class GTAUAVDataset(Dataset): - def __init__( - self, - pair_json: str, -- rgb_root: str = str(_RGB_ROOT), -- caption_root: str = str(_CAPTION_ROOT), -+ rgb_root: str, -+ caption_root: str, - drone_transform: Callable | None = None, - ... - ) -> None: -``` - -### Файл: `scripts/make_split.py` - -Полностью переписывается на gin: argparse → `get_preprocess_cfg`, module-level пути → поля конфига. - -```diff - from __future__ import annotations - ... -- import argparse - import json - import logging - import random - from pathlib import Path - - import coloredlogs - -+ from src.conf.preprocess_conf import get_preprocess_cfg -+ from src.utils.path_utils import get_proj_dir - - LOGGER = logging.getLogger("caption_test.make_split") - -- _RGB_ROOT = Path("/home/servml/Документы/datasets/GTA-UAV-LR") -- -- - def main() -> None: -- parser = argparse.ArgumentParser(description="Create 80/20 split for GTA-UAV-LR.") -- parser.add_argument("--ratio", type=float, default=0.8, help="Train ratio (default 0.8).") -- parser.add_argument("--seed", type=int, default=42, help="Random seed.") -- parser.add_argument("--output-dir", type=str, default="meta", help="Output directory.") -- args = parser.parse_args() -- -- coloredlogs.install(level="INFO", logger=LOGGER, ...) -+ coloredlogs.install(level="INFO", logger=LOGGER, ...) -+ -+ # Load config from a separate preprocess preset directory. -+ proj_dir = get_proj_dir() -+ cfg = get_preprocess_cfg(f"{proj_dir}presets/preprocess/") -+ -+ rgb_root = Path(cfg.rgb_root) -+ train_path = rgb_root / cfg.split_input_train -+ test_path = rgb_root / cfg.split_input_test - -- train_path = _RGB_ROOT / "cross-area-drone2sate-train.json" -- test_path = _RGB_ROOT / "cross-area-drone2sate-test.json" -- - LOGGER.info("📂 Loading %s", train_path.name) - with open(train_path) as f: - part1 = json.load(f) - ... - -- rng = random.Random(args.seed) -+ rng = random.Random(cfg.split_seed) - rng.shuffle(all_pairs) - -- n_train = int(len(all_pairs) * args.ratio) -+ n_train = int(len(all_pairs) * cfg.split_ratio) - ... - -- out_dir = Path(args.output_dir) -+ out_dir = Path(cfg.split_output_dir) - out_dir.mkdir(parents=True, exist_ok=True) -- train_out = out_dir / "train_80.json" -- test_out = out_dir / "test_20.json" -+ train_out = out_dir / cfg.split_output_train -+ test_out = out_dir / cfg.split_output_test - ... -``` - -### Файл: `scripts/filter_segmentation.py` - -Аналогично: - -```diff - from __future__ import annotations - ... -- import argparse - import json - import logging - from pathlib import Path - - import coloredlogs - import numpy as np - from PIL import Image - from tqdm import tqdm - -+ from src.conf.preprocess_conf import get_preprocess_cfg -+ from src.utils.path_utils import get_proj_dir - - LOGGER = logging.getLogger("caption_test.filter_seg") - -- SEGM_ROOT = Path("/home/servml/Документы/datasets/GTA-UAV-LR-aug/segm") -- EXCLUDE_CLASSES = {0, 4} # background, water -- DEFAULT_THRESHOLD = 0.90 -- - ... - - def main() -> None: -- parser = argparse.ArgumentParser(...) -- parser.add_argument("--segm-root", ...) -- parser.add_argument("--threshold", ...) -- parser.add_argument("--output", ...) -- args = parser.parse_args() -+ coloredlogs.install(level="INFO", logger=LOGGER, ...) -+ -+ proj_dir = get_proj_dir() -+ cfg = get_preprocess_cfg(f"{proj_dir}presets/preprocess/") -+ -+ segm_root = Path(cfg.segm_root) -+ exclude_classes = set(cfg.seg_exclude_classes) -+ threshold = cfg.seg_threshold -+ output_path = Path(cfg.seg_filter_output) - -- coloredlogs.install(level="INFO", logger=LOGGER, ...) -- LOGGER.info("🚀 Starting segmentation filter (threshold=%.2f)", args.threshold) -- segm_root = Path(args.segm_root) -- results = scan_masks(segm_root, EXCLUDE_CLASSES, args.threshold) -+ LOGGER.info("🚀 Starting segmentation filter (threshold=%.2f)", threshold) -+ results = scan_masks(segm_root, exclude_classes, threshold) - ... -- output_path = Path(args.output) - output_path.parent.mkdir(parents=True, exist_ok=True) - - out = { -- "threshold": args.threshold, -- "exclude_classes": sorted(EXCLUDE_CLASSES), -+ "threshold": threshold, -+ "exclude_classes": sorted(exclude_classes), - ... - } - ... -``` - -### Файл: `src/training/train.py` (legacy v2) - -Если v2 оставляем — снять `@gin.configurable` с `TrainConfig` и переписать на 5 конфигов аналогично `train_gtauav.py`. -Если удаляем — файл уходит вместе с веткой. - -> **Я бы советовал удалить v2** — он создаёт двойную работу при каждом изменении. Но это **отдельный** разговор, не блокер для текущего шага. - -### Файл: `conf/` (старые .gin) — удаляются после миграции - -После того как **все 14 пресетов в `presets/`** созданы и проверены — старая директория `conf/` удаляется целиком: - -```diff -- conf/balanced.gin -- conf/baseline_no_text.gin -- conf/text_heavy.gin -- conf/gtauav_balanced.gin -- conf/gtauav_baseline.gin -- conf/gtauav_balanced_asym.gin -- conf/gtauav_baseline_asym.gin -- conf/gtauav_balanced_stripnet.gin -- conf/gtauav_balanced_stripnet_unfrozen.gin -- conf/gtauav_baseline_stripnet.gin -- conf/gtauav_baseline_stripnet_unfrozen.gin -- conf/gtauav_text_heavy.gin -- conf/gtauav_image_heavy.gin -- conf/gtauav_balanced_sofia.gin # из локальной копии -- conf/gtauav_balanced_sofia_v1.gin # из локальной копии -- conf/gtauav_baseline_sofia.gin # из локальной копии -- conf/gtauav_baseline_sofia_v1.gin # из локальной копии -``` - ---- - -## Часть I — Что НЕ делаем на этом шаге - -Чтобы шаг был обозримым, **не трогаем**: - -- ❌ Декомпозиция `train()` (1296 строк) на `Trainer.run()` + методы — **отдельный шаг** -- ❌ Перенос `_evaluate` в `src/eval/evaluator.py` — **отдельный шаг** -- ❌ Перенос `CSVLogger` в `src/training/csv_logger.py` — **отдельный шаг** -- ❌ Замена `@torch.no_grad()` на `@torch.inference_mode()` — **отдельный шаг (косметика)** -- ❌ `_atomic_save` cleanup на ошибке — **отдельный шаг (косметика)** -- ❌ Логика sofia_v1/v71 моделей и их `dataclass`-конфиги — **внутренний слой не трогаем** - -После этого шага получаем: **гин-конфиг разделён, никаких `@gin.configurable + @dataclass`, никаких `@gin.configurable` на бизнес-классах, никаких argparse, плоские пресеты с дублированием полных биндингов вместо `include`**. Структура `train()` остаётся прежней (одна большая функция), но получает 6 объектов конфига вместо одного `cfg`. - ---- - -## Часть J — Открытые вопросы для уточнения - -1. **SOFIAv71 fields** — точный список полей `SOFIAv71Config` (`@dataclass` в `src/models/sofia_v71/config.py`) для построения `SOFIAv71ModelsConfig`. Я выписал поля по README, но в `config.py` могут быть ещё (mamba `headdim`, `d_state`, `kernel_size`, `num_bins` для квантизации). Нужно открыть файл и составить полный список. - -2. **`gtauav_*_sofia*.gin` локальные пресеты** — содержимое 4 sofia-гинов из локальной копии (на скриншоте видны, в репо ещё нет). Нужны как эталон для воспроизведения дефолтов один-в-один. - -3. **`use_mutex_sampler`** в `TrainingConfig` — текущий код помечает поле как «legacy alias». Сохранить ли его на этапе разделения, или сразу убрать (тогда `effective_sampler_type` берётся напрямую из `sampler_type`)? - -4. **Legacy v2** (`train.py`, `visloc_with_captions.py`, `conf/balanced.gin`/`baseline_no_text.gin`/`text_heavy.gin`) — удаляем или приводим к новому стилю? Я склоняюсь к удалению. Если оставлять — добавляется ещё 3 пресета и переписывание `TrainConfig` на 5 конфигов. - -5. **Расположение `presets/`** — в корне проекта или внутри `in/` (как `in/presets/`)? У вас сейчас лежит в корне (`presets/gtauav_balanced/` рядом с `src/`). Оставляем там же. - -После ответов на эти 5 вопросов план становится готов к реализации без новых развилок. \ No newline at end of file diff --git a/src/conf/__init__.py b/src/conf/__init__.py index 8b13789..f05572c 100644 --- a/src/conf/__init__.py +++ b/src/conf/__init__.py @@ -1 +1,54 @@ +"""Gin-configurable settings for the caption-test project. +Five universal axes of variability: + - PipelineConfig — paths, training schedule, output, resume + - HardwareConfig — batch size, accumulation, AMP, gradient checkpointing + - TrainingConfig — loss + optimizer + sampler (the recipe) + - TrackingConfig — wandb / tensorboard / gradcam / profiler + +Plus a model-family config: ModelsCommonConfig describes the active backbone, +and one of {DINOv3, StripNet, SOFIAv1, SOFIAv71} ModelsConfig classes +parameterises it. + +Plus PreprocessConfig used only by scripts/make_split.py and +scripts/filter_segmentation.py. + +All configs are loaded together via load_all_configs(path2cfg) — see +config_loader.py. +""" + +from src.conf.config_loader import load_all_configs +from src.conf.hardware_conf import HardwareConfig, get_hardware_cfg +from src.conf.models_common_conf import ModelsCommonConfig, get_models_common_cfg +from src.conf.models_dinov3_conf import DINOv3ModelsConfig, get_models_dinov3_cfg +from src.conf.models_sofia_v1_conf import SOFIAv1ModelsConfig, get_models_sofia_v1_cfg +from src.conf.models_sofia_v71_conf import SOFIAv71ModelsConfig, get_models_sofia_v71_cfg +from src.conf.models_stripnet_conf import StripNetModelsConfig, get_models_stripnet_cfg +from src.conf.pipeline_conf import PipelineConfig, get_pipeline_cfg +from src.conf.preprocess_conf import PreprocessConfig, get_preprocess_cfg +from src.conf.tracking_conf import TrackingConfig, get_tracking_cfg +from src.conf.training_conf import TrainingConfig, get_training_cfg + +__all__ = [ + "DINOv3ModelsConfig", + "HardwareConfig", + "ModelsCommonConfig", + "PipelineConfig", + "PreprocessConfig", + "SOFIAv1ModelsConfig", + "SOFIAv71ModelsConfig", + "StripNetModelsConfig", + "TrackingConfig", + "TrainingConfig", + "get_hardware_cfg", + "get_models_common_cfg", + "get_models_dinov3_cfg", + "get_models_sofia_v1_cfg", + "get_models_sofia_v71_cfg", + "get_models_stripnet_cfg", + "get_pipeline_cfg", + "get_preprocess_cfg", + "get_tracking_cfg", + "get_training_cfg", + "load_all_configs", +] diff --git a/src/conf/config_loader.py b/src/conf/config_loader.py index 8b13789..a453a8f 100644 --- a/src/conf/config_loader.py +++ b/src/conf/config_loader.py @@ -1 +1,90 @@ +"""Single entry point for loading all configs in a training run. + +Reads every .gin file in path2cfg (one preset directory) and instantiates +the 4 universal configs + ModelsCommonConfig + the family-specific Models +config selected by ModelsCommonConfig.backbone. +""" + +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_common_conf import ModelsCommonConfig +from src.conf.models_dinov3_conf import DINOv3ModelsConfig +from src.conf.models_sofia_v1_conf import SOFIAv1ModelsConfig +from src.conf.models_sofia_v71_conf import SOFIAv71ModelsConfig +from src.conf.models_stripnet_conf import StripNetModelsConfig +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__) + +# Maps ModelsCommonConfig.backbone → family-specific config class. +_BACKBONE_TO_MODELS_CLS = { + "dinov3": DINOv3ModelsConfig, + "stripnet": StripNetModelsConfig, + "sofia_v1": SOFIAv1ModelsConfig, + "sofia_v71": SOFIAv71ModelsConfig, +} + + +def load_all_configs(path2cfg: str) -> dict[str, Any]: + """Parse every .gin in path2cfg and instantiate all configs. + + Args: + path2cfg: Path to a preset directory ending with '/', e.g. + '/home/user/caption-test/in/config_files/'. + + Returns: + Dict with keys: + 'pipeline' → PipelineConfig + 'hardware' → HardwareConfig + 'training' → TrainingConfig + 'tracking' → TrackingConfig + 'models_common' → ModelsCommonConfig + 'models' → DINOv3 | StripNet | SOFIAv1 | SOFIAv71 ModelsConfig + (selected by models_common.backbone) + + Raises: + FileNotFoundError: If path2cfg contains no .gin files. + ValueError: If models_common.backbone is not one of the known values. + """ + 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 — without clear_config(), bindings + # from previous parses accumulate. + 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) + + # Build common first to learn which backbone to use. + models_common = ModelsCommonConfig() + if models_common.backbone not in _BACKBONE_TO_MODELS_CLS: + raise ValueError( + f"Unknown backbone={models_common.backbone!r}; " + f"expected one of {sorted(_BACKBONE_TO_MODELS_CLS)}", + ) + models_specific = _BACKBONE_TO_MODELS_CLS[models_common.backbone]() + + return { + "pipeline": PipelineConfig(), + "hardware": HardwareConfig(), + "training": TrainingConfig(), + "tracking": TrackingConfig(), + "models_common": models_common, + "models": models_specific, + } + diff --git a/src/conf/hardware_conf.py b/src/conf/hardware_conf.py index 8b13789..538ec22 100644 --- a/src/conf/hardware_conf.py +++ b/src/conf/hardware_conf.py @@ -1 +1,46 @@ +"""GPU profile + memory/compute optimisation flags.""" + +from __future__ import annotations + +import gin + + +@gin.configurable +class HardwareConfig: + """Hardware-bound parameters: VRAM footprint and throughput. + + These do not change the training recipe (loss/optimizer/sampler), only + how many samples fit on the device. + """ + + def __init__( + self, + device: str = "cuda", + batch_size: int = 8, + grad_accum_steps: int = 8, + num_workers: int = 4, + use_amp: bool = True, + gradient_checkpointing: bool = True, + reserve_gb: float = 2.0, + total_vram_gb: float = 24.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 + self.total_vram_gb = total_vram_gb + # Derived. + 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 — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}hardware.gin") + return HardwareConfig() + diff --git a/src/conf/models_common_conf.py b/src/conf/models_common_conf.py index 6121cd8..3d7ed1b 100644 --- a/src/conf/models_common_conf.py +++ b/src/conf/models_common_conf.py @@ -1,12 +1,38 @@ +"""Backbone-agnostic model parameters. + +`backbone` selects which family-specific Models config is loaded by +config_loader.load_all_configs. +""" + +from __future__ import annotations + import gin + @gin.configurable class ModelsCommonConfig: - """Common architecture switches shared by all backbones.""" + """Shared model fields across all backbones. + + `backbone` is the dispatch key — one of: + - 'dinov3' → DINOv3ModelsConfig + - 'stripnet' → StripNetModelsConfig + - 'sofia_v1' → SOFIAv1ModelsConfig + - 'sofia_v71' → SOFIAv71ModelsConfig + + `baseline_mode=True` disables text fusion entirely (gates locked at 1.0, + DGTRS-CLIP not loaded, TextFusionMLP not built). Used for Δ R@1 baselines. + + `init_gate` controls the initial sigmoid value of GatedFusion gates + (0.7 = 70% image, 30% text by default; 0.3 = text-heavy; 0.9 = image-heavy). + + `lrsclip_path` is the path to the DGTRS-CLIP checkpoint (only loaded when + text fusion is active). + """ + def __init__( self, - backbone: str = "dinov3", # 'dinov3' | 'stripnet' | 'sofia_v1' | 'sofia_v71' - baseline_mode: bool = False, # text disabled, gate forced 1.0 + backbone: str = "dinov3", + baseline_mode: bool = False, init_gate: float = 0.7, lrsclip_path: str = "nn_models/LRSCLIP/DGTRS-CLIP-ViT-L-14.pt", ) -> None: @@ -16,3 +42,9 @@ class ModelsCommonConfig: self.lrsclip_path = lrsclip_path +def get_models_common_cfg(path2cfg: str) -> ModelsCommonConfig: + """Load ONLY models_common config (TESTING ONLY — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}models.gin") + return ModelsCommonConfig() + diff --git a/src/conf/models_dinov3_conf.py b/src/conf/models_dinov3_conf.py index 816f7fb..bf492c3 100644 --- a/src/conf/models_dinov3_conf.py +++ b/src/conf/models_dinov3_conf.py @@ -1,7 +1,24 @@ +"""DINOv3 backbone configuration: encoders + MONA adapters.""" + +from __future__ import annotations + import gin + @gin.configurable class DINOv3ModelsConfig: + """DINOv3 ViT-L/16 with MONA adapters (CVPR 2025). + + `shared_encoder=True` uses a single DINOv3 WEB encoder for both drone and + satellite branches (default; ~432M params total). When False, separate WEB + (drone) + SAT (satellite) encoders are built (~733M params total, +4-5GB + VRAM). + + MONA adapters are injected in the LAST `mona_last_n_blocks` of the 24 + ViT blocks (default: 12 = top half). Set to 24 for full-capacity asymmetric + setup. + """ + def __init__( self, dino_web_path: str = "nn_models/DINO_WEB/dinov3-vitl16-pretrain-lvd1689m.pth", @@ -9,11 +26,19 @@ class DINOv3ModelsConfig: shared_encoder: bool = True, mona_bottleneck: int = 64, mona_last_n_blocks: int = 12, + lora_rank: int = 4, ) -> None: self.dino_web_path = dino_web_path self.dino_sat_path = dino_sat_path self.shared_encoder = shared_encoder self.mona_bottleneck = mona_bottleneck self.mona_last_n_blocks = mona_last_n_blocks + self.lora_rank = lora_rank + + +def get_models_dinov3_cfg(path2cfg: str) -> DINOv3ModelsConfig: + """Load ONLY DINOv3 models config (TESTING ONLY — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}models.gin") + return DINOv3ModelsConfig() - diff --git a/src/conf/models_sofia_v1_conf.py b/src/conf/models_sofia_v1_conf.py index 658ae79..ff49e4e 100644 --- a/src/conf/models_sofia_v1_conf.py +++ b/src/conf/models_sofia_v1_conf.py @@ -1,37 +1,69 @@ -# import gin +"""SOFIA v1 backbone configuration: 4-stage StripNet+DCNv4 + GGeM heads.""" -# @gin.configurable -# class SOFIAv1ModelsConfig: -# def __init__( -# self, -# # Backbone. -# variant: str = "small", # 'tiny_tiny' | 'tiny' | 'small' | 'small_v2' -# in_channels: int = 3, -# input_size: int = 256, -# dcn_variant: str = "v2", # 'v2' (stable) | 'v4' (faster, leaks) -# # Heads. -# d_descriptor: int = 1024, -# return_normalized: bool = False, -# # Altitude-FiLM. -# use_film_altitude: bool = True, -# altitude_norm: float = 500.0, -# # Text-FiLM. -# use_text_film_uav: bool = True, -# use_text_film_sat: bool = True, -# text_film_dim: int = 1024, -# text_film_hidden: int = 256, -# ) -> None: -# self.variant = variant -# self.in_channels = in_channels -# self.input_size = input_size -# self.dcn_variant = dcn_variant -# self.d_descriptor = d_descriptor -# self.return_normalized = return_normalized -# self.use_film_altitude = use_film_altitude -# self.altitude_norm = altitude_norm -# self.use_text_film_uav = use_text_film_uav -# self.use_text_film_sat = use_text_film_sat -# self.text_film_dim = text_film_dim -# self.text_film_hidden = text_film_hidden +from __future__ import annotations + +import gin +@gin.configurable +class SOFIAv1ModelsConfig: + """SOFIA v1: lightweight StripNet+DCNv4 backbone + heads. + + `variant_label` chooses backbone size (architecture dimensions are + resolved inside the model code from this label): + tiny_tiny: dims [16, 32, 80, 128] (~0.4M) + tiny : dims [32, 64, 128, 256] (~1M) + small : dims [64, 128, 320, 512] (~3M, default in code) + small_v2 : dims [64, 128, 256, 384] (~2M) + + `dcn_variant`: 'v2' = torchvision DeformConv2d (stable). 'v4' = OpenGVLab + DCNv4 (faster but ~9 MB / forward leak from C++ extension). + + Text fusion is two-level: + - Mid-level: Text-FiLM modulates feature maps before GGeM (when + use_text_film_uav / use_text_film_sat = True). + - Late-level: GatedFusion on descriptors (handled outside this config). + """ + + def __init__( + self, + # ---- Backbone ---- + variant_label: str = "small", # 'tiny_tiny' | 'tiny' | 'small' | 'small_v2' + in_channels: int = 3, + input_size: int = 256, + dcn_variant: str = "v2", # 'v2' | 'v4' + # ---- Heads ---- + d_descriptor: int = 1024, + return_normalized: bool = False, + # ---- Altitude-FiLM (UAV head) ---- + use_film_altitude: bool = True, + altitude_norm: float = 500.0, + # ---- Text-FiLM (mid-level fusion) ---- + use_text_film_uav: bool = True, + use_text_film_sat: bool = True, + text_film_dim: int = 1024, + text_film_hidden: int = 256, + # ---- LoRA on DGTRS-CLIP text encoder ---- + lora_rank: int = 4, + ) -> None: + self.variant_label = variant_label + self.in_channels = in_channels + self.input_size = input_size + self.dcn_variant = dcn_variant + self.d_descriptor = d_descriptor + self.return_normalized = return_normalized + self.use_film_altitude = use_film_altitude + self.altitude_norm = altitude_norm + self.use_text_film_uav = use_text_film_uav + self.use_text_film_sat = use_text_film_sat + self.text_film_dim = text_film_dim + self.text_film_hidden = text_film_hidden + self.lora_rank = lora_rank + + +def get_models_sofia_v1_cfg(path2cfg: str) -> SOFIAv1ModelsConfig: + """Load ONLY SOFIA v1 models config (TESTING ONLY — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}models.gin") + return SOFIAv1ModelsConfig() + diff --git a/src/conf/models_sofia_v71_conf.py b/src/conf/models_sofia_v71_conf.py index e69de29..38ca70c 100644 --- a/src/conf/models_sofia_v71_conf.py +++ b/src/conf/models_sofia_v71_conf.py @@ -0,0 +1,178 @@ +"""SOFIA v7.1 backbone: 4-stage StripDCN + MambaVision + CVGL-Aware Head.""" + +from __future__ import annotations + +import gin + + +@gin.configurable +class SOFIAv71ModelsConfig: + """SOFIA v7.1 student model. + + Mirrors src/models/sofia_v71/config.py::SOFIAConfig with one + difference: `mamba_extra_kwargs` (a dict in the dataclass) is flattened + into 5 explicit fields here, and reassembled into a dict for downstream + code. + + Variant scale presets (see model code): + Tiny: stem=16/32, dims=[48, 96, 176, 224], depths=[2, 3, 4, 2] (~5M) + M : stem=64/128, dims=[256, 512, 1280, 1536], depths=[3, 4, 15, 3] (~500M, default) + L : stem=64/128, dims=[256, 512, 1536, 2048], depths=[3, 4, 20, 3] (~1B) + + For the active experiment (Tiny preset, see `presets/gtauav_balanced_sofia/`) + you can override individual fields directly without resorting to a + 'preset' string parameter — every architectural dimension is bindable. + + Tiny needs `num_heads_*=4` (channels 176/224 not divisible by 8) and + `mamba_headdim=16` (channels not divisible by 64). + """ + + def __init__( + self, + # ---- Variant label (informational, used in logs/checkpoints) ---- + variant_label: str = "M", # 'M' | 'L' | 'Tiny' + # ---- Input ---- + input_size: int = 256, + in_channels: int = 3, + # ---- Stem ---- + stem_mid: int = 64, + stem_out: int = 128, + # ---- Backbone dimensions (per stage s1..s4) ---- + # Lists default to None; concrete defaults are filled in __init__ to + # avoid the def f(x=[]) anti-pattern. + embed_dims: list[int] | None = None, # default [256, 512, 1280, 1536] (M) + depths: list[int] | None = None, # default [3, 4, 15, 3] (M) + # ---- Stage 1-2 block params ---- + mbconv_expand: int = 4, + se_ratio: int = 16, + strip_kernel_s1: int = 7, + strip_kernel_s2: int = 5, + mix_kernels: list[int] | None = None, # default [3, 5, 7] + use_dcn_strip: bool = True, + # ---- Stage 3-4 (MambaVision) ---- + mamba_d_state: int = 16, + mamba_dt_rank: int | None = None, # auto = max(1, C // 16) + mamba_backend: str = "auto", # 'auto' | 'torch' | 'mamba_ssm' + mamba_variant: str = "mamba2", # 'mamba1' | 'mamba2' | 'efficient_vmamba' + # mamba_extra_kwargs flattened (assembled back into a dict in __init__): + mamba_d_state_mamba2: int = 64, + mamba_headdim: int = 64, + mamba_expand: int = 2, + mamba_d_conv: int = 4, + mamba_n_directions: int = 2, + # ---- Heads / attention ---- + num_heads_s3: int = 8, + num_heads_s4: int = 8, + use_strip_branch_s3: bool = True, + use_strip_branch_s4: bool = False, + ffn_expand: int = 4, + # ---- EVSS bridge ---- + use_evss_bridge: bool = False, + evss_bridge_locations: list[str] | None = None, # default ['pre_stage3'] + # ---- Neck ---- + neck_channels: int = 192, + # ---- CVGL-Aware Head v7.1-α ---- + d_descriptor: int = 512, + use_asymmetric_heads: bool = True, + chp_rings: int = 8, + chp_angles: int = 16, + chp_harmonics: int = 4, + use_film_altitude: bool = True, + altitude_norm: float = 500.0, + ring_count: int = 4, + use_ring_aux: bool = True, + # ---- Text fusion ---- + return_normalized: bool = True, + use_text_film_sat: bool = False, + use_text_film_uav: bool = False, + text_film_dim: int = 1024, + text_film_hidden: int = 256, + # ---- Weight-sharing ---- + share_stages_1_2: bool = True, + # ---- KD taps ---- + enable_kd_taps: bool = True, + # ---- Deployment ---- + precision: str = "fp16", # 'fp32' | 'fp16' | 'int8_mixed' + # ---- LoRA on DGTRS-CLIP text encoder ---- + lora_rank: int = 4, + ) -> None: + # Variant label. + self.variant_label = variant_label + # Input. + self.input_size = input_size + self.in_channels = in_channels + # Stem. + self.stem_mid = stem_mid + self.stem_out = stem_out + # Backbone dimensions. + self.embed_dims = embed_dims if embed_dims is not None else [256, 512, 1280, 1536] + self.depths = depths if depths is not None else [3, 4, 15, 3] + # Stage 1-2. + self.mbconv_expand = mbconv_expand + self.se_ratio = se_ratio + self.strip_kernel_s1 = strip_kernel_s1 + self.strip_kernel_s2 = strip_kernel_s2 + self.mix_kernels = mix_kernels if mix_kernels is not None else [3, 5, 7] + self.use_dcn_strip = use_dcn_strip + # Stage 3-4. + self.mamba_d_state = mamba_d_state + self.mamba_dt_rank = mamba_dt_rank + self.mamba_backend = mamba_backend + self.mamba_variant = mamba_variant + self.mamba_d_state_mamba2 = mamba_d_state_mamba2 + self.mamba_headdim = mamba_headdim + self.mamba_expand = mamba_expand + self.mamba_d_conv = mamba_d_conv + self.mamba_n_directions = mamba_n_directions + # Heads. + self.num_heads_s3 = num_heads_s3 + self.num_heads_s4 = num_heads_s4 + self.use_strip_branch_s3 = use_strip_branch_s3 + self.use_strip_branch_s4 = use_strip_branch_s4 + self.ffn_expand = ffn_expand + # EVSS. + self.use_evss_bridge = use_evss_bridge + self.evss_bridge_locations = ( + evss_bridge_locations if evss_bridge_locations is not None else ["pre_stage3"] + ) + # Neck. + self.neck_channels = neck_channels + # CVGL Head. + self.d_descriptor = d_descriptor + self.use_asymmetric_heads = use_asymmetric_heads + self.chp_rings = chp_rings + self.chp_angles = chp_angles + self.chp_harmonics = chp_harmonics + self.use_film_altitude = use_film_altitude + self.altitude_norm = altitude_norm + self.ring_count = ring_count + self.use_ring_aux = use_ring_aux + # Text fusion. + self.return_normalized = return_normalized + self.use_text_film_sat = use_text_film_sat + self.use_text_film_uav = use_text_film_uav + self.text_film_dim = text_film_dim + self.text_film_hidden = text_film_hidden + # Sharing / KD / deploy. + self.share_stages_1_2 = share_stages_1_2 + self.enable_kd_taps = enable_kd_taps + self.precision = precision + # LoRA. + self.lora_rank = lora_rank + # Derived: assemble mamba_extra_kwargs back for downstream consumers. + self.mamba_extra_kwargs = { + "d_state_mamba2": self.mamba_d_state_mamba2, + "headdim": self.mamba_headdim, + "expand": self.mamba_expand, + "d_conv": self.mamba_d_conv, + "n_directions": self.mamba_n_directions, + } + + +def get_models_sofia_v71_cfg(path2cfg: str) -> SOFIAv71ModelsConfig: + """Load ONLY SOFIA v71 models config (TESTING ONLY — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}models.gin") + return SOFIAv71ModelsConfig() + + diff --git a/src/conf/models_stripnet_conf.py b/src/conf/models_stripnet_conf.py index 56bcf50..08cf32c 100644 --- a/src/conf/models_stripnet_conf.py +++ b/src/conf/models_stripnet_conf.py @@ -1,16 +1,40 @@ +"""StripNet backbone configuration.""" + +from __future__ import annotations + import gin + @gin.configurable class StripNetModelsConfig: + """StripNet-small encoder with Conv-MONA adaptation. + + `stripnet_freeze=True` keeps the backbone frozen and only trains MONA on + the last `stripnet_mona_last_n_stages` of 4 stages. + + `stripnet_freeze=False` (full fine-tune) makes the backbone trainable; in + that case backbone params get a separate LR group at + `learning_rate * stripnet_backbone_lr_factor` (typically 0.1). + """ + def __init__( self, stripnet_path: str = "nn_models/STRIPNET/stripnet_s.pth", stripnet_freeze: bool = True, stripnet_mona_last_n_stages: int = 2, stripnet_backbone_lr_factor: float = 0.1, + lora_rank: int = 4, ) -> None: self.stripnet_path = stripnet_path self.stripnet_freeze = stripnet_freeze self.stripnet_mona_last_n_stages = stripnet_mona_last_n_stages self.stripnet_backbone_lr_factor = stripnet_backbone_lr_factor - + self.lora_rank = lora_rank + + +def get_models_stripnet_cfg(path2cfg: str) -> StripNetModelsConfig: + """Load ONLY StripNet models config (TESTING ONLY — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}models.gin") + return StripNetModelsConfig() + diff --git a/src/conf/pipeline_conf.py b/src/conf/pipeline_conf.py index 8b13789..5845519 100644 --- a/src/conf/pipeline_conf.py +++ b/src/conf/pipeline_conf.py @@ -1 +1,53 @@ +"""Pipeline orchestration: data IO, training schedule, output, resume.""" + +from __future__ import annotations + +import gin + + +@gin.configurable +class PipelineConfig: + """What to train on, where to save, and how long. + + All paths are absolute or relative to the project root. Defaults match + the servml workstation; override in pipeline.gin for other machines. + """ + + def __init__( + self, + # Data inputs. + 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 — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}pipeline.gin") + return PipelineConfig() + + \ No newline at end of file diff --git a/src/conf/preprocess_conf.py b/src/conf/preprocess_conf.py index 8b13789..7102e39 100644 --- a/src/conf/preprocess_conf.py +++ b/src/conf/preprocess_conf.py @@ -1 +1,56 @@ +"""Preprocessing configuration: train/test split + segmentation filter.""" + +from __future__ import annotations + +import gin + + +@gin.configurable +class PreprocessConfig: + """Used only by scripts/make_split.py and scripts/filter_segmentation.py. + + Lives in a separate preset (presets/preprocess/preprocess.gin) — it is + not consumed by the training pipeline. Held independently from + PipelineConfig so that preprocess can run without a training preset + being active. + """ + + def __init__( + self, + # Inputs. + rgb_root: str = "/home/servml/Документы/datasets/GTA-UAV-LR", + segm_root: str = "/home/servml/Документы/datasets/GTA-UAV-LR-aug/segm", + # make_split.py params. + split_ratio: float = 0.8, + split_seed: int = 42, + split_input_train: str = "cross-area-drone2sate-train.json", + split_input_test: str = "cross-area-drone2sate-test.json", + split_output_dir: str = "meta", + split_output_train: str = "train_80.json", + split_output_test: str = "test_20.json", + # filter_segmentation.py params. + seg_threshold: float = 0.90, + seg_exclude_classes: list[int] | None = None, # default [0, 4]: background + water + seg_filter_output: str = "meta/seg_filter.json", + ) -> None: + self.rgb_root = rgb_root + self.segm_root = segm_root + self.split_ratio = split_ratio + self.split_seed = split_seed + self.split_input_train = split_input_train + self.split_input_test = split_input_test + self.split_output_dir = split_output_dir + self.split_output_train = split_output_train + self.split_output_test = split_output_test + self.seg_threshold = seg_threshold + self.seg_exclude_classes = seg_exclude_classes if seg_exclude_classes is not None else [0, 4] + self.seg_filter_output = seg_filter_output + + +def get_preprocess_cfg(path2cfg: str) -> PreprocessConfig: + """Load preprocess config from the preprocess preset directory.""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}preprocess.gin") + return PreprocessConfig() + diff --git a/src/conf/tracking_conf.py b/src/conf/tracking_conf.py index 8b13789..a578054 100644 --- a/src/conf/tracking_conf.py +++ b/src/conf/tracking_conf.py @@ -1 +1,51 @@ +"""Experiment tracking + diagnostics. + +Independent axis: changing these flags does not affect training results, +only what is observed/recorded. +""" + +from __future__ import annotations + +import gin + + +@gin.configurable +class TrackingConfig: + """Wandb / TensorBoard / Grad-CAM / profiler / gradient norms.""" + + 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 — production uses load_all_configs).""" + 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 index 8b13789..20fd432 100644 --- a/src/conf/training_conf.py +++ b/src/conf/training_conf.py @@ -1 +1,93 @@ +"""Training recipe: loss + optimizer + sampler. + +Three concerns kept together because they form one coherent recipe — they +co-vary across experiments. Splitting Loss vs Optimizer vs Sampler can be +done later if a need emerges. +""" + +from __future__ import annotations + +import gin + + +@gin.configurable +class TrainingConfig: + """Loss + optimizer + sampler. + + Selects between InfoNCELoss and WeightedInfoNCELoss via `loss_type`. + Selects between DSS / mutex / plain shuffle via `sampler_type`. + """ + + def __init__( + self, + # ---- Loss: shared between InfoNCELoss and WeightedInfoNCELoss ---- + loss_type: str = "symmetric", # 'symmetric' | 'weighted' + tau_init: float = 0.07, + tau_min: float = 0.01, + tau_max: float = 0.1, + learnable_temperature: bool = True, + label_smoothing: float = 0.1, + # ---- Loss: InfoNCELoss-only ---- + tau_final: float = 0.01, # cosine-schedule final tau (when not learnable) + weight_q2g: float = 0.6, + weight_g2q: float = 0.4, + hard_mining_k: int = 0, + neg_bank_size: int = 0, + # ---- Loss: WeightedInfoNCELoss-only ---- + weighted_loss_k: float = 5.0, # sigmoid steepness for weight→eps mapping + # ---- Optimizer ---- + learning_rate: float = 1e-4, + text_lr_factor: float = 0.1, # lr * factor for DGTRS-CLIP/LoRA params + weight_decay: float = 1e-4, + grad_clip: float = 1.0, + # ---- Sampler ---- + sampler_type: str = "mutex", # 'mutex' | 'dss' | 'none' + 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, + # Legacy alias (kept until train_gtauav.py is rewritten in step 4). + use_mutex_sampler: bool = True, + ) -> None: + # Loss (shared). + 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 + # Loss (InfoNCE-specific). + self.tau_final = tau_final + self.weight_q2g = weight_q2g + self.weight_g2q = weight_g2q + self.hard_mining_k = hard_mining_k + self.neg_bank_size = neg_bank_size + # Loss (WeightedInfoNCE-specific). + self.weighted_loss_k = weighted_loss_k + # Optimizer. + self.learning_rate = learning_rate + self.text_lr_factor = text_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 + self.use_mutex_sampler = use_mutex_sampler + + +def get_training_cfg(path2cfg: str) -> TrainingConfig: + """Load ONLY training config (TESTING ONLY — production uses load_all_configs).""" + gin.clear_config() + gin.parse_config_file(f"{path2cfg}training.gin") + return TrainingConfig() +