This repository implements a practical pipeline for training a small language model to answer multi-hop questions while ignoring distracting context.
The project targets noisy multi-hop QA on HotpotQA distractor-style data with a compact model:
- Base model:
Qwen/Qwen2.5-0.5B - Finetuning: QLoRA (4-bit) + LoRA adapters
- Budget: single GPU workflow
- Focus: robustness via harder negatives, evidence supervision, and curriculum learning
flowchart LR
A[HotpotQA samples] --> B[Preprocess + flatten context]
B --> C[Build data variants]
C --> C1[Clean]
C --> C2[Random negatives]
C --> C3[Hard negatives]
C3 --> D[Answer-only SFT: E2]
C3 --> E[Answer + Evidence SFT: E3]
C1 --> F[Curriculum stage 1]
C2 --> G[Curriculum stage 2]
E --> H[Curriculum stage 3]
F --> I[E4 curriculum model]
G --> I
H --> I
| ID | Training setup | Objective |
|---|---|---|
| E0 | Clean context | Answer-only SFT |
| E1 | Random negatives | Answer-only SFT |
| E2 | Hard negatives | Answer-only SFT |
| E3 | Hard negatives | Answer + evidence (weighted evidence loss) |
| E4 | Curriculum: clean -> random -> hard+evidence | Staged training |
Full inference-side EM/F1 is implemented but not completed in this local run.
The table below reports available training-side proxy metrics from outputs/metrics/*.json.
| Model | Train setting | Train loss | Eval loss | Loss drop (%) | Runtime (min) |
|---|---|---|---|---|---|
| E0 | clean-answer-only | 0.7816 | 0.7015 | 54.10 | 8.74 |
| E1 | random-answer-only | 0.8083 | 0.6751 | 58.88 | 8.35 |
| E2 | hard-answer-only | 0.8330 | 0.6471 | 64.44 | 8.32 |
| E3 | hard-answer-evidence | 4.0132 | 0.1773 | 66.36 | 8.38 |
| E4 | hard-answer-evidence (curriculum final stage) | 4.2826 | 0.1611 | 76.77 | 8.40 |
Notes:
- E2 vs E3/E4 train loss is not directly comparable due to different output objectives.
- E3/E4 low eval loss is measured on evidence-formatted validation targets.
.
├── src/ # Core modules: preprocessing, noisy-data building, training, eval, plotting
├── scripts/ # CLI entry points (train/evaluate/report artifacts)
├── notebooks/ # End-to-end workflow notebooks (01~06)
├── report/ # LaTeX report draft
├── outputs/ # Metrics/tables/figures artifacts (generated)
├── data/ # Raw/processed/formatted data (generated)
└── checkpoints/ # LoRA checkpoints/adapters (generated)
Python 3.10+ is recommended.
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install torch transformers peft datasets matplotlib bitsandbytesMain config file:
src/config.json
Important defaults:
max_input_length=2048max_output_length=160train_subset_size=1200,val_subset_size=200,test_subset_size=200lora_r=8,lora_alpha=16,lora_dropout=0.05learning_rate=2e-4,num_epochs=1evidence_loss_weight=2.0
Unified CLI:
python scripts/train.py --experiment e0
python scripts/train.py --experiment e1
python scripts/train.py --experiment e2
python scripts/train.py --experiment e3
python scripts/train.py --experiment e4Shortcut CLIs:
python scripts/train_e0.py
python scripts/train_e1.py
python scripts/train_e2.py
python scripts/train_e3.py
python scripts/train_e4_curriculum.pyRun full answer/evidence evaluation:
python scripts/evaluate_models.py \
--models e0 e1 e2 e3 e4 \
--settings clean_answer_only random_answer_only hard_answer_only hard_answer_evidenceRun robustness curves (optional):
python scripts/evaluate_models.py \
--run-robustness \
--robustness-models e0 e2 e4 \
--robustness-neg-counts 0 1 2 3 4 \
--robustness-negative-type hardStandard mode (uses outputs/metrics/eval_summary.json if present):
python scripts/build_report_artifacts.pyProxy mode (training-only tables/plots):
python scripts/build_report_artifacts.py --force-proxyThe notebook sequence is:
notebooks/01_setup_and_data_check.ipynbnotebooks/02_preprocess_hotpotqa.ipynbnotebooks/03_build_noisy_and_hardneg_data.ipynbnotebooks/04_train_baselines_and_evidence.ipynbnotebooks/05_evaluate_and_plot.ipynbnotebooks/06_report_tables_and_figures.ipynb
- This repo uses
.gitignoreto exclude large artifacts (checkpoints, images, generated datasets). - If you clone from GitHub, you may need to regenerate
data/,outputs/, andcheckpoints/locally.
- The currently committed artifacts emphasize training-side proxy metrics.
- Final task-level claims should rely on full inference outputs:
- Answer EM/F1
- Evidence Precision/Recall/F1
- Robustness curves over increasing negatives
Full PDF: Teaching Small LLMs What to Ignore





