MMS-300m Fine-tuned for Wolof ASR
Fine-tuned facebook/mms-300m for Wolof (Wolof: wol) automatic speech recognition using CTC.
Evaluation Results
| Metric | Value |
|---|---|
| WER | 13.64% |
| CER | 4.51% |
| RTF | 263x |
on ALFFA Wolof + Google FLEURS
Training Details
Base Model
- Architecture: Wav2Vec2 (300M parameters)
- Base checkpoint:
facebook/mms-300m
Datasets
| Dataset | Samples | Text Column |
|---|---|---|
Or4kool/wolof_speech_dataset | ~9,260 (filtered) | text |
Alwaly/wolof_asr_bg | ~81,361 | transcription |
(data augmentation) | ~72,863 | transcription |
| Total | ~163K |
- Evaluation on 10% held-out
Data Augmentation (on-the-fly)
- Speed perturbation
- Volume perturbation
- Time masking:
Hyperparameters
- Hardware: 8× NVIDIA V100 32GB
- Epochs: 20
- Batch size: 8 per GPU × 8 GPUs = 64 effective
- Learning rate: 1e-4 (cosine schedule)
- Warmup steps: 1,000
- Precision: fp16 mixed precision
- Gradient clipping: max_grad_norm=1.0
- Gradient checkpointing: enabled
- Feature encoder: frozen (freeze_feature_encoder=True)
- CTC blank token:
<pad>(index 0)
Training Stability
- CTCTrainer: Custom Trainer
- CTC validity filter
- DDP:
find_unused_parameters=Truefor frozen feature encoder compatibility
Usage
from transformers import Wav2Vec2ForCTC, Wav2Vec2Processor
import torch
import soundfile as sf
processor = Wav2Vec2Processor.from_pretrained("sokho2/mms-300m-wolof-v001")
model = Wav2Vec2ForCTC.from_pretrained("sokho2/mms-300m-wolof-v001")
# Load audio (16kHz mono)
audio, sr = sf.read("audio.wav")
inputs = processor(audio, sampling_rate=16000, return_tensors="pt", padding=True)
with torch.no_grad():
logits = model(**inputs).logits
predicted_ids = torch.argmax(logits, dim=-1)
transcription = processor.batch_decode(predicted_ids)
print(transcription[0])
Comparison with Other Models
| Model | WER | CER | RTF | Params |
|---|---|---|---|---|
| sokho2/mms-300m-wolof-v001 (this model) | 13.64% | 4.51% | 263x | 300M |
| Omnilingual ASR CTC 1B | 28.01% | 7.45% | 163x | 1B |
| bilalfaye/wav2vec2-large-mms-1b-wolof | 29.00% | 8.60% | 138x | 1B |
| vonewman/wav2vec2-large-mms-1b-wolof | 32.15% | 8.94% | 140x | 1B |
| M9and2M/marone_wolof_wav2vec2-xls-r-300m | 39.11% | 21.77% | 264x | 300M |
| BenDaouda/wav2vec2-large-xls-wolof-asr | 41.31% | 14.70% | 267x | 300M |
| BenDaouda/wav2vec2-large-xls-r-1b-wolof-VoiceToText | 48.08% | 15.83% | 267x | 1B |
| Or4kool/mms_300m_wolof_stt | 72.19% | 35.61% | 267x | 300M |
| kingabzpro/wav2vec2-large-xlsr-53-wolof | 96.93% | 53.47% | 271x | 300M |
Evaluated on 2,337 samples from ALFFA Wolof (dev + test) + Google FLEURS Wolof (wo_sn) test set.
Limitations
- Wolof has significant dialectal variation and French code-switching (~36% of training data contains some French); the model may struggle with heavily French-mixed utterances
- Short utterances (< 2 seconds) tend to have inflated WER due to single-word errors having outsized impact
- No punctuation
- Spelling variants in Wolof (e.g., "xam" vs "ham") are penalized as errors even when phonetically equivalent
License
CC-BY-NC-4.0 (following the base MMS model license)
@misc{sokho2-mms-300m-wolof,
author = {Sokho2},
title = {MMS-300M Wolof ASR},
year = {2026},
url = {https://huggingface.co/sokho2/mms-300m-wolof}
}