Spaces:
Running on Zero
Running on Zero
Download src/config.py from saminv81/aigc-detector: direct link, hf CLI and curl.
- Browser
- Download file 6.72 kB
-
https://huggingface.co/spaces/saminv81/aigc-detector/resolve/main/src/config.py
- Command line
-
hf download hf://spaces/saminv81/aigc-detector/src/config.py
-
curl -L -o config.py https://huggingface.co/spaces/saminv81/aigc-detector/resolve/main/src/config.py
6.72 kB
| # src/config.py | |
| from dataclasses import dataclass | |
| class Config: | |
| resolution: int = 518 | |
| patch_grid: int = 37 | |
| n_patch: int = 1369 | |
| embed_dim: int = 768 | |
| backbone: str = "stub" # "stub" (local CI) | "dinov2_vitb14_reg" (GPU host) | |
| # REJECTED (kept for reference): RINE-style last-N fusion never beat single-layer readout. | |
| # n_intermediate_layers: int = 1 | |
| extract_layer: int = 8 # SHIP DEFAULT (train.py trains 8 and 10 for the ensemble) β >0 = read patch tokens after DINOv2 block L (1-indexed) and TRUNCATE the stack to L blocks (real FLOP saving); tests whether localized signal survives earlier. 0 = full depth. Mutually exclusive with n_intermediate_layers>1. | |
| # REJECTED: MIL top-k image logits (k=16/64 and DC-centered) gave no transfer gain β the | |
| # head's self-attention broadcasts the verdict into every patch, so top-k of a broadcast | |
| # is the broadcast. Left commented for the record. | |
| # mil_top_k: int = 0 | |
| # mil_centered: bool = False | |
| label_smooth: float = 0.05 # BCE target smoothing eps: targets eps/1βeps instead of 0/1 (bounds optimal logits, calibrates probs). 0 = hard labels. | |
| # REJECTED: warp minimal-pair augmentation taught the warp artifact, not anatomy | |
| # (unseen-GAN AUC β0.027). Implementation retained in data/aug/warp.py for reference. | |
| # warp_strength: float = 1.0 | |
| # p_global_warp: float = 0.0 | |
| corruption_scale: float = 1.0 # train-only: >1 stretches corruption severity ranges toward their harsh end (clamped). Ship default 1.0 β scaling alone measured negative; keep at 1.0 unless re-validated together with lambda_feat. | |
| lambda_feat: float = 1.5 # feature-consistency weight: cosine drift of the pooled trainable representation across the clean/corrupted pair (label-blind, both classes) β forces the decision path onto corruption-stable semantic/geometric directions. | |
| fusion_project: bool = True # fusion projection: True=dense DxD (~590K); False=scalar layer-mix (K params, preferred at low data) | |
| train_impls: dict | None = None # {family:[impl,...]} operator subset for TRAINING β set BEFORE training so held-out impls stay genuinely unseen (the impl-holdout gap is only valid when training is restricted to this subset) | |
| data_parallel: bool = False # DataParallel across all visible GPUs (e.g. dual T4): splits the heavy frozen-backbone forward for ~2x + halves per-GPU batch memory. No idle GPU regardless of arm count. | |
| head_hidden: int = 0 # 0 = linear-probe head; >0 = MLP head (Linear-GELU-Linear) | |
| head_pool: str = "attn" # "attn" (baseline MIL) | "dist" (+mean/std/top-k patch-logit stats) | "nbr" (dist + zero-init 3x3 depthwise conv over the patch grid = local adjacency; density-gate redirect, orthogonal to global-realism signal) | "enc" (dist + zero-init self-attention encoder w/ 2D pos-embed = configural "sequence-not-bag" test) | |
| # NULLED (never shipped): opt-in spectral branch β JPEG/blur corruption destroys the | |
| # frequency signal it reads; only viable as a fusion member, which we did not ship. | |
| # use_freq_branch: bool = False | |
| enc_layers: int = 2 # EncoderPoolHead: transformer-encoder depth (head_pool="enc") | |
| enc_heads: int = 8 # EncoderPoolHead: self-attention heads (head_pool="enc") | |
| use_pos_embed: bool = True # EncoderPoolHead: add fixed 2D sin/cos positional embedding before the encoder | |
| # SUPERSEDED by deshortcut=True (the full pipeline); kept for ablation only. | |
| # defeat_resolution: bool = False | |
| deshortcut: bool = False # train: thumbnail-degrade+contrast+sharpness+codec aug (stronger shortcut defeat) | |
| p_codec: float = 0.5 # deshortcut: P(random JPEG/PNG re-encode) β kills the codec-history shortcut | |
| random_resolution: bool = False # train: per-batch random resolution (varied token grid, no res anchor) | |
| res_lo: int = 392 # random_resolution range lo (mult of 14) | |
| res_hi: int = 644 # random_resolution range hi (mult of 14) | |
| fair_eval: bool = False # eval: normalize real+fake to common size+format (no res/format tell) | |
| feature_mode: str = "jit" # Phase-2: "jit"|"cache" β cache path not yet implemented (no consumer in Phase 1) | |
| compile: bool = False # torch.compile toggle (GPU-host only) | |
| amp: bool = False # fp16 autocast on the FROZEN backbone only (T4 tensor cores ~2x); head stays fp32 | |
| gpu_preprocess: bool = False # workers emit uint8 (resize only); float/normalize/res-resize happen ON GPU (halves worker CPU, 4x smaller host transfers). Bilinear resize commutes with per-channel normalize, so numerics match the CPU path. | |
| lambda_aug: float = 0.8 | |
| lambda_cons_max: float = 0.3 | |
| # NULLED (never shipped): teacher distillation from a pretrained forensics model was cut | |
| # early on licensing + complexity grounds; the frozen-backbone head needs no teacher. | |
| # lambda_kd: float = 0.0 | |
| pos_weight: float = 0.0 # 0 = unweighted BCE; >0 scales the fake(1) term (calibration) | |
| entropy_gate: float = 0.5 | |
| stack_prob: float = 0.1 | |
| seed: int = 0 | |
| epochs: int = 10 | |
| epoch_frac: float = 1.0 # train on this fraction of the loader per epoch (0.5 = half an epoch); shuffle=True makes the half-pass a random subsample | |
| batch_size: int = 32 | |
| eval_batch_size: int = 32 # eval forward-pass chunk (predict_fn); bounds VRAM on large val sets | |
| eval_pool_max: int = 64 # max decoded val images resident at once (bounds HOST RAM in streaming eval) | |
| eval_workers: int = 0 # >0 = thread-pool the eval corruption prep (PIL releases the GIL); 0 = serial (legacy) | |
| holdout_eval_cap: int = 0 # 0=eval whole holdout; >0=stratified subsample cap (speed) | |
| val_eval_cap: int = 0 # 0=eval whole val EVERY epoch; >0=stratified per-epoch subsample (a 7.5k val x 19 conds = hours of CPU-bound corruption PER EPOCH on the 47k corpus) | |
| lr: float = 1e-3 | |
| lr_schedule: str = "none" # "none" | "onecycle" (per-step mid-epoch warmup+cosine) | |
| num_workers: int = 2 | |
| pin_memory: bool = True | |
| max_images: int = 0 # 0 = all | |
| data_root: str = "data" | |
| cache_dir: str = "cache" | |
| # Weights & Biases logging (OFF by default; training hosts flip use_wandb=True) | |
| use_wandb: bool = False | |
| wandb_project: str = "track5-aigc" | |
| wandb_run_name: str = "" # empty -> wandb autogenerates | |
| log_every: int = 10 # log train metrics every N steps | |
| def smoke(cls) -> "Config": | |
| return cls(max_images=200, epochs=1, compile=False, batch_size=8) | |