File size: 6,413 Bytes
f28663f d252c0b 08f5e69 2931876 08f5e69 d252c0b 08f5e69 d252c0b 2931876 08f5e69 2931876 08f5e69 2931876 08f5e69 2931876 08f5e69 2931876 08f5e69 2931876 08f5e69 | 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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | ---
license: mit
pipeline_tag: audio-classification
tags:
- language-identification
- spoken-language-identification
- audio-classification
- speech
- multilingual
- wav2vec2
- mms
- xls-r
- pytorch-lightning
datasets:
- google/fleurs
---
# BA-Lang - Spoken Language Identification checkpoints
Checkpoints for **spoken language identification (LID)**: a self-supervised
speech backbone, pooled with **MHFA**
(Multi-Head Factorized Attention) and scored with either a standard
cosine-softmax classifier or **BA-LR** (Binary Attribute Likelihood Ratio),
a Bernoulli classifier over a learned binary attribute embedding.
- Training code / recipe: [https://github.com/AMIAD-Research/BA-Lang]
- BA-LR / BA-Lang model: Y. Jelassi et al., *"Reconnaissance de la langue parlée explicable avec BA-LR"*, JEP 2026 —
[isca-archive.org/jep_2026/jelassi26_jep.html](https://www.isca-archive.org/jep_2026/jelassi26_jep.html)
## Architecture
```
raw audio (16 kHz)
│
▼
SSL backbone (MMS-1B or wav2vec2-XLS-R)
│
▼
Multi-Head Factorized Attentive pooling (MHFA)
│
▼
classification head
├─ Linear, or
└─ BA-Lang: binary encoder → per-class Bernoulli log-likelihood
│
▼
language logits
```
## Checkpoints
| File | Backbone | Corpus | Languages | Head | Step | Val. accuracy | Size |
|---|---|---|---|---|---|---|---|
| `MMS-Fleurs-step-010360-val_classif_acc-0.9168118238449097.ckpt` | MMS-1B | FLEURS | 102 | Linear | 10360 | 91.68% | 3.86 GB |
| `MMS-Fleurs-e2e-balang-stepstep-008856-val_classif_acc-0.9167537689208984.ckpt` | MMS-1B | FLEURS | 102 | BA-Lang (e2e) | 8856 | 91.68% | 3.87 GB |
| `MMS-Fleurs-e2e-balang-MIR-rho-0.95-step-032472-val_classif_acc-0.90935212373733...ckpt` | MMS-1B | FLEURS | 102 | BA-Lang (e2e) + Matryoshka-inspired regularization, ρ=0.95 | 32472 | 90.94% | 3.87 GB |
| `MMS-Fleurs-e2e-balang-ND-rho-0.857-step-047232-val_classif_acc-0.89306861162185...ckpt` | MMS-1B | FLEURS | 102 | BA-Lang (e2e) + Nested Dropout, ρ=0.857 | 47232 | 89.31% | 3.87 GB |
| `MMS-Tidylang-step-008533-val_classif_acc-0.9778640866279602.ckpt` | MMS-1B | Tidylang | 35 | Linear | 8533 | 97.79% | 3.86 GB |
| `MMS-Tidylang-e2e-balang-step-005565-val_classif_acc-0.9929152131080627.ckpt` | MMS-1B | Tidylang | 35 | BA-Lang (e2e) | 5565 | 99.29% | 3.87 GB |
| `XLSR-Fleurs-step-005904-val_classif_acc-0.8094159960746765.ckpt` | wav2vec2-XLS-R | FLEURS | 102 | Linear | 5904 | 80.94% | 1.27 GB |
| `XLSR-Fleurs-e2e-balang-step-047232-val_classif_acc-0.8120864033699036.ckpt` | wav2vec2-XLS-R | FLEURS | 102 | BA-Lang (e2e) | 47232 | 81.21% | 1.27 GB |
| `XLSR-Tidylang-step-008904-val_classif_acc-0.9662737846374512.ckpt` | wav2vec2-XLS-R | Tidylang | 35 | Linear | 8904 | 96.63% | 1.27 GB |
| `XLSR-Tidylang-e2e-balang-step-032648-val_classif_acc-0.9860262870788574...ckpt` | wav2vec2-XLS-R | Tidylang | 35 | BA-Lang (e2e) | 32648 | 98.60% | 1.27 GB |
## Datasets
Training is done separately on two corpora — pick the checkpoint matching
the languages you need.
- **[FLEURS](https://huggingface.co/datasets/google/fleurs)** (102
languages, ISO 639-3): `afr, amh, ara, asm, ast, aze, bel, ben, bos, bul,
cat, ceb, ces, ckb, cmn, cym, dan, deu, ell, eng, est, fas, fil, fin, fra,
ful, gle, glg, guj, hau, heb, hin, hrv, hun, hye, ibo, ind, isl, ita, jav,
jpn, kam, kan, kat, kaz, kea, khm, kir, kor, lao, lav, lin, lit, ltz, lug,
luo, mal, mar, mkd, mlt, mon, mri, msa, mya, nep, nld, nob, nso, nya, oci,
ori, orm, pan, pol, por, pus, ron, rus, slk, slv, sna, snd, som, spa, srp,
swa, swe, tam, tel, tgk, tha, tur, ukr, umb, urd, uzb, vie, wol, xho, yor,
yue, zul`.
- **Tidylang** (35 languages): `TidyVoiceX_ASV` (train/dev) and
`TidyVoiceX2_ASV` (eval), from Mozilla Data Collective
([train/dev](https://mozilladatacollective.com/datasets/cmihtsewu023so207xot1iqqw),
[eval](https://mozilladatacollective.com/datasets/cmkv32i5e02tumg07j79d3c35)):
`ara, bak, bel, ben, bul, cat, chv, cym, deu, div, ell, eng, fas, fra, hin,
hye, jpn, kat, lit, lug, mal, mar, nld, ori, pol, por, rus, tam, tha, tuk,
tur, uig, uzb, yue, zho`.
```python
import yaml
lang_list = yaml.safe_load(open("configs/data/fleurs.yaml"))["language_list"]
# or configs/data/tidylang.yaml for the Tidylang checkpoints
```
## Quickstart — inference on your own audio
```bash
git clone https://github.com/AMIAD-Research/BA-Lang
cd BA-Lang
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pip install huggingface_hub
python -c "
from huggingface_hub import hf_hub_download
hf_hub_download(
repo_id='yjelassi/BA-Lang',
filename='MMS-Fleurs-e2e-balang-stepstep-008856-val_classif_acc-0.9167537689208984.ckpt',
local_dir='.',
)
"
```
Then, on a single audio file (no manifest needed — this loads the
checkpoint directly and runs one forward pass):
```python
import torch
import torchaudio
import yaml
from balr_lid.models.lid_model import LanguageIdentificationModel
CHECKPOINT = "MMS-Fleurs-e2e-balang-stepstep-008856-val_classif_acc-0.9167537689208984.ckpt"
LANGUAGES = yaml.safe_load(open("configs/data/fleurs.yaml"))["language_list"]
model = LanguageIdentificationModel.load_from_checkpoint(
CHECKPOINT, map_location="cpu", weights_only=False
)
model.eval()
waveform, sr = torchaudio.load("my_audio.wav")
if waveform.shape[0] > 1:
waveform = waveform.mean(dim=0, keepdim=True)
if sr != 16000:
waveform = torchaudio.functional.resample(waveform, sr, 16000)
with torch.no_grad():
out = model(waveform)
probs = out["logits"].softmax(dim=-1)[0]
top5 = probs.topk(5)
for score, idx in zip(top5.values, top5.indices):
print(f"{LANGUAGES[idx]}: {score.item():.3f}")
```
### Batch inference over a dataset
To evaluate on many files at once (accuracy, confusion matrix, embedding
dump), build a manifest CSV (see
[docs/data_manifest.md](https://github.com/AMIAD-Research/BA-Lang))
and use the repo's batch script instead:
```bash
python -m balr_lid.inference \
--checkpoint MMS-Fleurs-e2e-balang-stepstep-008856-val_classif_acc-0.9167537689208984.ckpt \
--manifest data/manifests/fleurs-test.csv \
--audio-root /path/to/fleurs/audio \
--language-list afr amh ara ... \
--output predictions.csv
```
`--language-list` must match the checkpoint's training corpus, in order
(see [Datasets](#datasets) above).
|