| """Single-source-of-truth configuration for WiSER CIR. |
| |
| Every runtime knob lives here. Submodules (`models/detr_head.py`, |
| `models/backbone.py`, `engine/checkpoint_selector.py`, `engine/orchestrate.py`, |
| `engine/losses.py`) expose configs that MUST be constructed from these |
| top-level dataclasses so a single edit here propagates. |
| |
| Defaults carry PROVISIONAL flags where task9 / histogram evidence has not |
| yet replaced them (pending Round-2 real-data execution). |
| """ |
|
|
| from __future__ import annotations |
|
|
| from dataclasses import dataclass, field |
|
|
|
|
| @dataclass |
| class ModelConfig: |
| |
| |
| |
| query_budget: int = 8 |
| |
| |
| |
| |
| db_low: float = -115.0 |
| db_high: float = -7.5 |
| |
| backbone_channels: int = 256 |
| backbone_tx_emb_channels: int = 128 |
| backbone_downsample_stages: int = 2 |
| backbone_blocks_per_stage: int = 2 |
| backbone_num_heads: int = 8 |
| backbone_mlp_ratio: float = 4.0 |
| |
| |
| |
| |
| backbone_kind: str = "trellis2" |
| |
| head_num_decoder_layers: int = 2 |
| head_num_heads: int = 8 |
| head_dropout: float = 0.0 |
| |
| |
| |
| |
| peak_db_head_arch: str = "flat" |
| peak_db_hidden: int = 512 |
| peak_db_init_mean_db: float = -55.0 |
| |
| delay_head_arch: str = "flat" |
| delay_hidden: int = 512 |
| delay_init_mean_ns: float = 4.0 |
| |
| exists_head_arch: str = "flat" |
| exists_hidden: int = 512 |
| exists_init_prob: float = 0.2 |
|
|
|
|
| @dataclass |
| class LossConfig: |
| match_exists: float = 1.0 |
| match_delay_ns: float = 1.0 |
| match_peak_db: float = 1.0 |
| no_object_exists: float = 1.0 |
| |
| enable_pair_gap_losses: bool = False |
| pair_gap_delay: float = 0.0 |
| pair_gap_db: float = 0.0 |
| delay_huber_beta_ns: float = 0.5 |
| peak_db_huber_beta: float = 2.0 |
|
|
|
|
| @dataclass |
| class CheckpointSelectorConfig: |
| peak_db_bias_abs_max: float = 3.0 |
| zero_path_fpr_max: float = 0.10 |
| count_acc_min: float = 0.5 |
| delay_mae_ns_max: float = 1.0 |
| primary_tie_tol: float = 1e-3 |
|
|
|
|
| @dataclass |
| class ScaleUpGateConfig: |
| count_acc_min: float = 0.9 |
| delay_mae_ns_max: float = 0.3 |
| peak_db_bias_abs_max: float = 3.0 |
|
|
|
|
| @dataclass |
| class TargetContractConfig: |
| mode: str = "merged_delay_bin" |
| delay_max_ns: float = 15.0 |
| num_bins: int = 128 |
| max_paths: int = 8 |
| |
| floor_db: float = -250.0 |
| use_bin_center_delay: bool = True |
|
|
|
|
| @dataclass |
| class ThroughputBenchConfig: |
| |
| |
| manifest_path: str = "benchmarks/tiny10_triples_manifest.json" |
| warmup_steps: int = 20 |
| measured_steps: int = 100 |
|
|
|
|
| @dataclass |
| class ManifestPaths: |
| single_scene: str = "manifests/task_a069_single_scene.json" |
| tiny10: str = "benchmarks/tiny10_triples_manifest.json" |
| tiny30: str = "manifests/task_a069_tiny30.json" |
| tiny50: str = "manifests/task_a069_tiny50.json" |
| tiny100: str = "manifests/task_a069_tiny100.json" |
|
|
|
|
| @dataclass |
| class TrainConfig: |
| model: ModelConfig = field(default_factory=ModelConfig) |
| loss: LossConfig = field(default_factory=LossConfig) |
| selector: CheckpointSelectorConfig = field(default_factory=CheckpointSelectorConfig) |
| scale_up_gate: ScaleUpGateConfig = field(default_factory=ScaleUpGateConfig) |
| target_contract: TargetContractConfig = field(default_factory=TargetContractConfig) |
| benchmark: ThroughputBenchConfig = field(default_factory=ThroughputBenchConfig) |
| manifests: ManifestPaths = field(default_factory=ManifestPaths) |
| radiomap_head_forbidden: bool = True |
|
|
|
|
| def reject_radiomap_artifacts(manifest_path: str, weights_name: str | None = None) -> None: |
| """Hard guard: refuse radiomap manifests or weights. |
| |
| Round 7 fix (Codex R6 finding 2): the guard only inspects the |
| BASENAME / STEM of the manifest path, not the full absolute path. The |
| branch's own ancestor directory is `.../WiSER/...`, so |
| a naive substring match over the full path incorrectly rejected every |
| WiSER CIR manifest. We now match patterns that a genuine radiomap artifact |
| filename would exhibit (`radiomap_*`, `*_radiomap_*`, `*radiomap_tag*`), |
| not any ancestor-directory occurrence of the word. |
| |
| Called by dataset loader, manifest builder, benchmark script, and |
| training orchestrators so the CIR-only guarantee holds at runtime. |
| """ |
| import os |
|
|
| basename = os.path.basename(str(manifest_path)).lower() |
| stem = basename.rsplit(".", 1)[0] if "." in basename else basename |
|
|
| if "radiomap" in stem: |
| raise RuntimeError( |
| f"Refusing radiomap manifest in WiSER CIR (CIR-only branch): {manifest_path}" |
| ) |
| if weights_name is not None and str(weights_name).lower().startswith("radiomap_"): |
| raise RuntimeError( |
| f"Refusing radiomap weights in WiSER CIR (CIR-only branch): {weights_name}" |
| ) |
|
|