# Native-Bird image-text alignment (AfriCaption / Flickr8k) # All paths are relative to the project root. seed: 42 data: dir: data/processed # train/val/test parquet from scripts/04_split.py image_dir: data/raw/flickr8k/Flicker8k_Dataset langs: [eng, ibo, hau, yor] # captions used for training (each image contributes one pair per kept language) max_text_len: 64 subset: null # int -> use only first N images per split (smoke tests) image_encoder: # Any open_clip model or HF CLIP/SigLIP checkpoint. Frozen; features are cached to disk once. backend: hf # hf | open_clip name: google/siglip-base-patch16-224 cache_dir: data/features # cached image features: //.pt text_encoder: # Pick the arm. Each arm is a sentence-transformers model id. arm: native_bird # native_bird | embeddinggemma2 | embeddinggemma1 | labse | custom arms: native_bird: {name: Modularcomputing/Native-Bird, prompt: ""} embeddinggemma2: {name: google/embeddinggemma-2, prompt: "task: search result | query: ", text_only: true} embeddinggemma1: {name: google/embeddinggemma-300m, prompt: "task: search result | query: "} labse: {name: sentence-transformers/LaBSE, prompt: ""} custom: {name: null, prompt: ""} unfreeze_last_n_layers: 0 # 0 = fully frozen (text embeddings are cached); >0 fine-tunes the top-N transformer layers cache_dir: data/features model: proj_dim: 512 proj_hidden: 0 # 0 = linear projection; >0 = 2-layer MLP with this hidden size dropout: 0.1 init_logit_scale: 2.659 # ln(1/0.07), CLIP default; learnable, clamped at ln(100) train: epochs: 20 batch_size: 256 # contrastive batch; bigger = more negatives lr: 1.0e-3 # projection heads text_lr: 1.0e-5 # unfrozen text layers (only if unfreeze_last_n_layers > 0) weight_decay: 0.01 warmup_steps: 100 same_image_negatives: mask # mask: captions of the same image in other languages are not treated as negatives device: auto # auto | cuda | cpu num_workers: 4 out_dir: runs/${text_encoder.arm} eval_every: 1 eval: split: test ks: [1, 5, 10] langs: [eng, ibo, hau, yor]