Downloads · 30 days
6
6% of all-time downloads
AzCandi/yasr-yoruba-mms
yasr-yoruba-mms is a automatic speech recognition model from AzCandi. Use it when you need speech turned into text. The card lists the license as cc-by-4.0.
Fine-tuned from facebook/mms-1b-all on Mozilla Common Voice Yoruba using a signal-processing-informed curriculum learning strategy. Only 2,271,582 of 964,768,990 parameters are updated (0.24%) — the Yoruba adapter lay…
Downloads · 30 days
6
6% of all-time downloads
All-time downloads
104
Public
Parameters
965M
3.9 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors3.9 GB · 100%
From the Hugging Face model README
Fine-tuned from facebook/mms-1b-all on Mozilla Common Voice Yoruba using a signal-processing-informed curriculum learning strategy. Only 2,271,582 of 964,768,990 parameters are updated (0.24%) — the Yoruba adapter layers and CTC projection head. The CNN feature extractor and all 48 transformer encoder layers remain frozen throughout training.
| Evaluation Set | WER | CER | Notes |
|---|---|---|---|
| Test set (clean, held-out) | 33.85% | 10.08% | 572 speaker-stratified clips |
| Tier-3 challenge set (noisy) | 36.62% | 12.18% | 554 out-of-distribution clips, never seen in training |
| Validation set (greedy, no LM) | 40.89% | 10.36% | Step 3 acoustic model only |
Clean-to-noisy degradation: +2.77pp WER (typical ASR systems degrade 10–20pp on out-of-distribution audio). The small gap reflects the signal-processing preprocessing and augmentation choices described below.
| Component | Parameters | Status |
|---|---|---|
| CNN Feature Extractor (7 conv layers) | 4,210,176 | Frozen |
| Transformer Encoder (48 layers) | 958,286,848 | Frozen |
| Yoruba Adapter Layers (×48, per-layer norm + linear_1 + linear_2) | 2,151,168 | Trainable |
| CTC Projection Head (lm_head) | 120,414 | Trainable |
| Total trainable | 2,271,582 | 0.24% of model |
The MMS adapter architecture inserts a small bottleneck module (down-projection 1280→16, up-projection 16→1280) inside each of the 48 transformer layers. Fine-tuning only these modules and the CTC head is the correct strategy for the low-resource regime: with fewer than 900 clean training clips, updating the full 964M-parameter model would be severely under-determined.
All 4,655 clips in the Mozilla Common Voice Yoruba corpus were analysed before any model decisions were made. Key findings and their direct implications:
| Preprocessing Finding | Implication for Training |
|---|---|
| Corpus median SNR > 25 dB | Justified freezing the CNN feature extractor |
| Bimodal RMS distribution (two recording populations) | Required per-clip −23 LUFS normalisation rather than corpus-level normalisation |
| pYIN F0 confirmed at 160–180 Hz (Yoruba tonal contours) | Justified speed perturbation over pitch-shifting for augmentation |
| K-means quality clustering → 3 tiers | Defined a curriculum: clean data first, noisy data second |
| Only 878 Tier-1 clips available | Set maximum safe trainable parameter budget at 2.27M |
Preprocessing steps applied to all audio:
Quality tiering (K-means k=3, 49-dimensional MFCC + wavelet feature space):
Rebuilt from validated.tsv (3,470 clips) using speaker-stratified GroupShuffleSplit:
| Partition | Clips | % | Speaker overlap |
|---|---|---|---|
| Train | 2,503 | 72.1% | 0 |
| Validation | 395 | 11.4% | 0 |
| Test | 572 | 16.5% | 0 |
The original Common Voice Yoruba split (41% train / 31% test / 28% dev) was discarded as train-starved and lacking speaker stratification guarantees.
Known limitation — combining-codepoint tone stripping: Yoruba dot-below vowels with tone marks (e.g. ọ́ = U+1ECD + U+0301) are stored as two-token sequences in the MMS vocabulary. pyctcdecode's character-level beam alignment does not correctly handle these multi-codepoint sequences when unigram constraints are applied, causing tone marks on ọ, ẹ, ṣ to be stripped in beam search output. Workaround: beam search runs without unigrams, relying on the 4-gram LM for word-level constraints. Greedy decoding (torch.argmax) preserves tone marks correctly.
from transformers import Wav2Vec2ForCTC, AutoProcessor
import torch, librosa
model_id = "AzCandi/yasr-yoruba-mms"
processor = AutoProcessor.from_pretrained(model_id)
processor.tokenizer.set_target_lang("yor")
model = Wav2Vec2ForCTC.from_pretrained(model_id)
model.eval()
# Load audio — 16 kHz mono recommended
speech, _ = librosa.load("audio.wav", sr=16000, mono=True)
# Transcribe
inputs = processor(speech, sampling_rate=16000, return_tensors="pt")
with torch.no_grad():
logits = model(**inputs).logits
pred_ids = torch.argmax(logits, dim=-1)
transcription = processor.decode(pred_ids[0])
print(transcription)
# pip install pyctcdecode kenlm
from pyctcdecode import build_ctcdecoder
import numpy as np
# Build decoder — download lm_4gram.bin from model repo
decoder = build_ctcdecoder(
labels=list(processor.tokenizer.get_vocab().keys()),
kenlm_model_path="lm_4gram.bin",
alpha=0.7,
beta=1.0,
)
with torch.no_grad():
logits = model(**inputs).logits
transcription = decoder.decode(logits[0].cpu().numpy())
print(transcription)
import librosa
import scipy.signal as signal
import numpy as np
import pyloudnorm as pyln
def preprocess_yoruba_audio(path):
# Load and resample
speech, sr = librosa.load(path, sr=16000, mono=True)
# Bandpass filter: 80–7,900 Hz, Kaiser N=255, zero-phase
sos = signal.butter(8, [80, 7900], btype='bandpass',
fs=16000, output='sos')
speech = signal.sosfiltfilt(sos, speech)
# Loudness normalise to −23 LUFS
meter = pyln.Meter(16000)
loudness = meter.integrated_loudness(speech)
speech = pyln.normalize.loudness(speech, loudness, -23.0)
return speech.astype(np.float32)
| Parameter | Value |
|---|---|
| Sample rate | 16,000 Hz |
| BPF passband | 80–7,900 Hz |
| BPF window | Kaiser, N=255 |
| BPF phase | Zero-phase (sosfiltfilt) |
| Wavelet | Daubechies-4 (db4) |
| Wavelet levels | 5 |
| Denoising threshold | Soft, per-level MAD estimator |
| Loudness target | −23 LUFS (ITU-R BS.1770) |
| Quality clustering | K-means k=3, 49-dim MFCC + wavelet energy/entropy |
| File | Description |
|---|---|
| config.json | Model architecture configuration |
| model.safetensors | Full model weights (backbone frozen + trained adapters) |
| tokenizer_config.json | Tokeniser configuration for Yoruba |
| vocab.json | 94-token Yoruba character vocabulary |
| preprocessor_config.json | Audio feature extractor configuration |
| lm_4gram.bin | KenLM 4-gram binary language model (3.1 MB) |
| README.md | This model card |
If you use YASR in your research, please cite the MMS paper and Mozilla Common Voice:
@article{pratap2023scaling,
title={Scaling speech technology to 1,000+ languages},
author={Pratap, Vineel and Tjandra, Andros and Shi, Bowen and others},
journal={arXiv preprint arXiv:2305.13516},
year={2023}
}
@inproceedings{ardila2020common,
title={Common Voice: A massively-multilingual speech corpus},
author={Ardila, Rosana and others},
booktitle={Proceedings of LREC},
year={2020}
}
Developed as part of doctoral research in Computer Science. Training was conducted on Google Colab (Tesla T4 GPU). The signal-processing-informed curriculum methodology was grounded in acoustic analysis of the Mozilla Common Voice Yoruba corpus using pYIN F0 extraction, wavelet subband energy profiling, and spectral flatness-ranked K-means quality clustering.