Route it, or hand it off.
Intent routing across 10 languages, with LoRA written from scratch.
| Run | mean of 10 | en | hi | ta | sw |
|---|---|---|---|---|---|
| Probe, en | 55.7 | 78.8 | 66.6 | 17.7 | 16.5 |
| LoRA, en | 67.0 | 87.1 | 74.9 | 47.9 | 23.8 |
| Full, en | 66.8 | 88.1 | 75.4 | 39.3 | 24.1 |
| Probe, multi | 58.4 | 75.1 | 66.8 | 31.3 | 22.8 |
| LoRA, multi (studied) | 76.9 | 83.9 | 79.0 | 73.3 | 58.7 |
| Full, multi | 79.9 | 86.1 | 82.1 | 77.1 | 65.6 |
Highlighted: LoRA. Full fine-tuning trains 127× its parameters for 3.0 more points.
Four findings
LoRA ties full fine-tuning on a narrow target
Trained on English, the mean gap is +0.2 points [−0.2, +0.6]. Across ten languages, rank 8 trails by 3.0.
English-only training fails where pretraining is thin
Swahili falls to 23.8% and Tamil to 47.9%. The same budget over ten languages lifts them to 58.7% and 73.3%.
Calibration breaks in the same languages
Expected calibration error for Tamil is 0.120 after English-only training, 0.028 after multilingual.
Handing off cannot rescue an unknown language
Deferring the least-confident 20% buys Hindi 10 points and Swahili 4.
Confidence only helps where it separates right from wrong
LoRA, English-trained: accuracy on kept requests.
Three ways to train
One encoder, paraphrase-multilingual-MiniLM-L12-v2, plus a linear head. Apple M2, 8 GB.
| Method | What trains | Parameters |
|---|---|---|
| Probe | The head only | 23,100 |
| LoRA r = 8 | Query and value, α = 16, and the head | 170,556 |
| Full | Every layer and the head; word embeddings frozen | 21,662,652 |
Limits
- One seed per run. The confidence intervals cover test sampling, not training variance.
- Full fine-tuning froze the word embeddings: 96M of 118M parameters.
- One LoRA configuration; no rank sweep.
- Why Swahili is weakest is untested.
Reproduce
Saved logits in results/ rebuild every table in seconds.
git clone https://github.com/akshit9162/abstain-or-route
cd abstain-or-route
python -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python -m src.evaluate # every table
.venv/bin/pytest # 12 after setup
PATH=.venv/bin:$PATH ./setup.sh # data and encoder
rm results/*/meta.json && ./run.sh # ~2 h on an M2