File size: 2,748 Bytes
7e9cfd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Code

The pipeline that produces predictions from the released models, for StanceEval-2026 Track 1 (seen
targets) and Track 2 (unseen targets). Base LLMs are fetched from their own Hugging Face repos.

```bash
pip install -r ../requirements.txt
```

## Prediction

1. Encoder ensemble, averaged softmax over the fine-tuned encoders:
   ```bash
   python -m src.predict --models <MODEL_DIRS> --csv <test.csv> --out preds_enc.txt
   ```
2. Retrieval few-shot LLM, with MARBERTv2-retrieved shots over a served instruction model on an
   OpenAI-compatible endpoint:
   ```bash
   export AUG_BASE_URL="http://localhost:8017/v1"; export AUG_MODEL="LilaRest/gemma-4-31B-it-NVFP4-turbo"
   python -m src.llm_classify --csv <test.csv> --train <pool.csv> --retrieve \
       --embed_model UBC-NLP/MARBERTv2 --shots 6 --n 6 --mode direct \
       --out_probs gemma.npy --base_url "$AUG_BASE_URL" --model "$AUG_MODEL"
   ```
3. LoRA member, scored by label log-probability:
   ```bash
   python -m src.llm_infer --adapter <lora_dir> --base_model ALLaM-AI/ALLaM-7B-Instruct-preview \
       --csv <test.csv> --out_probs allam.npy
   ```
4. Blend and None calibration, then labels:
   ```bash
   python -m src.blend_tune --csv <test.csv> --models <MODEL_DIRS> --enc_weight 0.45 \
       --llm_probs gemma.npy allam.npy --llm_weights 0.5 0.5 --none_bias 0.0 --out pred.txt
   ```

The final label decision uses the plug-in rule for *F*<sub>avg2</sub>: claim class *c* when *P*(*c*)
exceeds *F*<sub>c</sub>/2, otherwise fall back to `None`.

## Training

Encoders are config-driven, and the full config also lands in each model's `best.json`:

```bash
python -m src.train --config configs/track{1,2}.yaml --overrides model_hf=<id>,out_dir=<dir>
python -m src.train --config configs/track2_aug.yaml        # uses data/track2/train_aug.csv
```

LoRA adapters (r=16, α=32, base fetched from HF):

```bash
python -m src.llm_finetune --train_csv <train.csv> \
    --base_model ALLaM-AI/ALLaM-7B-Instruct-preview --out_dir outputs/allam_t2 \
    --epochs 3 --batch_size 16 --save_every 15
```

The generated pools in `../data/` come from `src/gen_synth.py` (style and target-matched shots) and
`src/augment.py` (paraphrase augmentation). See [`../data/README.md`](../data/README.md).

## Rebuilding an auxiliary encoder

Four encoders were used only as probability sources and never saved. Override the base id to rebuild
them, for example AraELECTRA:

```bash
python -m src.train --config configs/track1.yaml \
    --overrides model_hf=aubmindlab/araelectra-base-discriminator,out_dir=outputs/t1_araelectra
```

The same pattern rebuilds the XLM-R-large, ARBERTv2 and AraBERT-large members. Encoder label order is
`["Against","Favor","None"]`, set in `src/data.py`.