Whisper Small — Kikuyu (Gĩkũyũ) V5
Fine-tuned openai/whisper-small for Kikuyu speech recognition using LoRA on a combined corpus of google/WaxalNLP kik_tts and thiomi/thiomi-5k kik_Latn.
Results
| Split | WER | CER |
|---|---|---|
| Eval (WAXAL+Thiomi combined val) | 51.9% | 21.1% |
| Test (WAXAL only, apples-to-apples with V4) | 68.7% | 34.5% |
V4 Test WER was 83.6% — V5 is a 14.9pp improvement on the same WAXAL test split, driven by:
- 7× more training data (added Thiomi corpus, 1,226 → 6,406 samples post-filter)
- Fixed diacritic normalization (Unicode escapes instead of literal chars)
- Speed perturbation augmentation in addition to SpecAugment
Training config
- Base:
openai/whisper-small(244M params) - LoRA: r=32, alpha=64, targets: q_proj, k_proj, v_proj, out_proj, fc1, fc2
- Steps: 1800, effective batch 16 (per_device 16, grad_accum 1)
- LR: 5e-5 cosine, warmup 10%, weight decay 0.01
- fp16, gradient checkpointing, label smoothing 0.1
- Trained on Kaggle T4, ~7.6h
Usage
from transformers import WhisperForConditionalGeneration, WhisperProcessor
import soundfile as sf
processor = WhisperProcessor.from_pretrained("Kiragu/whisper-small-kikuyu-v5")
model = WhisperForConditionalGeneration.from_pretrained("Kiragu/whisper-small-kikuyu-v5")
y, sr = sf.read("your_kikuyu_audio.wav", dtype="float32")
inputs = processor(y, sampling_rate=sr, return_tensors="pt")
ids = model.generate(inputs.input_features, max_new_tokens=200)
text = processor.batch_decode(ids, skip_special_tokens=True)[0]
Part of Sauti AI
Live demo: https://sauti.alkenacode.dev
See metrics.json and inference_samples.json for details.