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