Instructions to use travis-moore/sema-afro with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use travis-moore/sema-afro with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("automatic-speech-recognition", model="travis-moore/sema-afro")# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForSpeechSeq2Seq processor = AutoProcessor.from_pretrained("travis-moore/sema-afro") model = AutoModelForSpeechSeq2Seq.from_pretrained("travis-moore/sema-afro", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Sema Afro β African Speech Recognition (17 languages, code-switch)
Sema Afro transcribes 17 African languages in a single open model, including the way people switch between a language and English inside one sentence. It is trained on roughly 1.6 million audio clips (on the order of 2,000 hours) of Sema's own recordings plus licensed open-source African speech, with a dedicated decoder-token slot per language so the languages reinforce rather than dilute one another.
It is the strongest deployable open model across these African languages (it beats the open baseline, OpenAI Whisper large-v3, on 12 of 15 benchmarked languages) and it ranks first on real Ghanaian Twi/English code-switch.
β οΈ Read this before you call the model: the
languageargument is an internal routing slot, not the ISO codeTo keep 17 languages from blurring together, each language is trained under its own spare Whisper decoder token. Those slot tokens deliberately reuse other languages' codes, so they collide with the ISO codes you'd expect:
- Twi / Twi-English code-switch β
yo(not Yoruba!)- Yoruba β
suΒ· Igbo βhawΒ· Luganda βloΒ· Kinyarwanda βlbΒ· Zulu βbaΒ· Xhosa βtkΒ· Wolof βtgΒ· Oromo βsdΒ· Fula βnn- (Hausa
ha, Swahilisw, Amharicam, Afrikaansaf, Lingalaln, Shonasn, Somalisokeep their normal codes.)Passing
language="yo"for Yoruba audio will silently transcribe it with the Twi model. Never pass a bare ISO code β always go through thesema_lang()helper in the Usage section (or the full slot table at the bottom).
Highlights
- 17 African languages in one checkpoint, with intra-sentence code-switch (e.g. TwiβEnglish). Other open models at this breadth (Meta MMS) use a separate monolingual model per language and cannot code-switch.
- Beats OpenAI Whisper large-v3 on 12 of 15 languages benchmarked, several by very large margins (Amharic 40.9 vs 110.6, Wolof 24.3 vs 58.9, Yoruba 34.5 vs 49.6). It ties Swahili and trails on Afrikaans and Somali.
- Keeps near-native English (CER 2.9) β which is exactly what lets it handle TwiβEnglish code-switch instead of breaking on the English spans.
- #1 on Ghanaian Twi/English code-switch β 34.2 CER on 78 human-verified clips, ahead of GhanaNLP's Khaya (34.5), OpenAI gpt-4o (39.7), Meta MMS (48.0) and Intron (78.4).
- Honest caveat: on single-language read speech, Meta MMS posts lower error on most languages, but it is CC-BY-NC (non-commercial), ships one model per language, and cannot code-switch β a research ceiling, not a deployable competitor. The apples-to-apples open+commercial comparison is Whisper large-v3, below.
Benchmarks
Metric. Collapsed Character Error Rate (CER): lowercase, strip punctuation and whitespace, Levenshtein distance / reference length. Lower is better. We report CER (not WER) because African word segmentation is unstable.
Method. Every model is scored on the same audio with the same scorer. Read-speech rows are the FLEURS test split (held out β we train only on train), first 150 clips per language. The code-switch row is 78 human-verified Twi/English clips in no model's training data. Competitors run on their own documented best config and current versions (October 2026).
Ghanaian Twi/English code-switch (78 human-verified clips)
| System | CER β |
|---|---|
| Sema Afro (this model) | 34.2 |
| Khaya / GhanaNLP | 34.5 |
| OpenAI gpt-4o-transcribe | 39.7 |
| Meta MMS | 48.0 |
| Intron Sahara | 78.4 |
Read speech, FLEURS test β Sema Afro vs the open baseline
| Language | Sema Afro | OpenAI Whisper large-v3 | Meta MMSΒΉ | IntronΒΉ | OpenAI gpt-4oΒΉ |
|---|---|---|---|---|---|
| Hausa | 18.5 β | 25.7 | 7.2 | 7.7 | β |
| Yoruba | 34.5 β | 49.6 | 20.8 | 18.6 | β |
| Igbo | 23.7 β | 35.5 | 13.4 | 28.8 | 39.6 |
| Swahili | 8.0 β | 8.0 | 3.6 | 7.9 | 7.3 |
| Lingala | 9.2 β | 12.4 | 4.2 | β | β |
| Luganda | 16.1 β | 20.8 | 7.0 | 28.6 | 14.6 |
| Amharic | 40.9 β | 110.6 | 7.8 | 21.9 | β |
| Afrikaans | 11.4 β | 9.7 | 6.6 | 11.0 | 5.2 |
| Shona | 14.7 β | 21.1 | 4.6 | 7.4 | β |
| Somali | 32.6 β | 31.4 | 13.5 | β | β |
| Zulu | 19.7 β | 30.8 | 6.4 | 11.0 | 24.7 |
| Xhosa | 22.3 β | 30.4 | 6.9 | 11.4 | 31.7 |
| Wolof | 24.3 β | 58.9 | 12.3 | 22.1 | 22.7 |
| Oromo | 28.3 β | 40.9 | 18.4 | 25.5 | 26.2 |
| Fula | 20.1 β | 25.9 | 14.9 | 18.1 | 25.9 |
| English | 2.9 β | ~4 | β | β | β |
β Sema Afro beats Whisper large-v3 Β· β tie Β· β Whisper wins. Record across the 15 African read-speech languages: 12 wins, 1 tie, 2 losses (and English adds a 13th win).
ΒΉ Meta MMS, Intron and OpenAI gpt-4o are shown for context but are not commercially deployable open models (MMS is CC-BY-NC and monolingual-per-model; Intron and OpenAI are closed/non-commercial APIs). Whisper large-v3 (MIT) is the apples-to-apples open+commercial comparison.
Kinyarwanda (rw) and Twi (tw) are supported but not in FLEURS; Twi is measured on the code-switch set above. English (en) is a separate FLEURS split; on its full test (647 clips) Sema Afro scores CER 2.9. A full-split re-run of the table above (whole FLEURS test, not 150 clips) confirmed every language within ~1β3 CER, with Yoruba improving to 31.2.
Usage
pip install --upgrade transformers torch librosa
The
languagevalue is a routing slot, not an ISO code (see the warning at the top). Always resolve it throughsema_lang()so you never accidentally send, say, Yoruba audio to the Twi slot.
import torch
from transformers import pipeline
# Friendly name -> internal routing slot. NEVER pass a bare ISO code as `language`.
SEMA_SLOT = {
"twi": "yo", "akan": "yo", "code-switch": "yo", "twi-english": "yo",
"hausa": "ha", "swahili": "sw", "amharic": "am", "afrikaans": "af",
"lingala": "ln", "shona": "sn", "somali": "so",
"yoruba": "su", "igbo": "haw", "luganda": "lo", "kinyarwanda": "lb",
"zulu": "ba", "xhosa": "tk", "wolof": "tg", "oromo": "sd", "fula": "nn",
}
def sema_lang(name: str) -> str:
try:
return SEMA_SLOT[name.strip().lower()]
except KeyError:
raise ValueError(f"Unknown language '{name}'. Supported: {sorted(SEMA_SLOT)}")
asr = pipeline(
"automatic-speech-recognition",
model="travis-moore/sema-afro",
torch_dtype=torch.float16,
device="cuda:0", # or "cpu"
)
# Twi + English code-switch
print(asr("ghana_twi_english.wav", generate_kwargs={"language": sema_lang("twi"), "task": "transcribe"}))
# Yoruba (sema_lang maps this to the 'su' slot β NOT 'yo'!)
print(asr("yoruba.wav", generate_kwargs={"language": sema_lang("yoruba"), "task": "transcribe"}))
# Hausa
print(asr("naija_hausa.wav", generate_kwargs={"language": sema_lang("hausa"), "task": "transcribe"}))
Multiple files (set batch_size):
print(asr(["a.wav", "b.wav"], batch_size=8, generate_kwargs={"language": sema_lang("twi"), "task": "transcribe"}))
Long audio (over 30s) β enable chunking:
asr = pipeline("automatic-speech-recognition", model="travis-moore/sema-afro",
chunk_length_s=30, batch_size=8, torch_dtype=torch.float16, device="cuda:0")
print(asr("long_audio.mp3", generate_kwargs={"language": sema_lang("hausa"), "task": "transcribe"}))
Timestamps:
print(asr("audio.wav", return_timestamps=True,
generate_kwargs={"language": sema_lang("twi"), "task": "transcribe"})["chunks"])
On language selection. Always pass the language β Sema Afro does not reliably detect the language on its own (it is biased toward the Twi slot), so leaving it unset can mis-route non-Twi audio. For fully hands-off transcription, run a spoken-language-ID step first (e.g. an
mms-lidclassifier) and map its result throughsema_lang().
Languages (17) and their routing slots
The slot is the value you pass as
language(viasema_lang()), not the language's ISO code. Several slots intentionally reuse other languages' codes β read the warning at the top.
| Language | slot | Language | slot | Language | slot | ||
|---|---|---|---|---|---|---|---|
| Twi/Akan + code-switch | yo |
Hausa | ha |
Zulu | ba |
||
| Swahili | sw |
Yoruba | su |
Xhosa | tk |
||
| Amharic | am |
Igbo | haw |
Wolof | tg |
||
| Afrikaans | af |
Luganda | lo |
Oromo | sd |
||
| Lingala | ln |
Kinyarwanda | lb |
Fula | nn |
||
| Shona | sn |
Somali | so |
That is 17 languages. Each slot is a stable routing token kept distinct so the languages don't blur together.
Model details
Sema Afro is an encoder-decoder speech model (~809M parameters) that transcribes audio at 16 kHz. Each language is trained under its own decoder-token slot. It is distributed as safetensors and loads with the standard transformers automatic-speech-recognition classes.
Training data
Trained on roughly 1.6 million audio clips (on the order of 2,000 hours) across the 17 languages, combining Sema's own collected recordings with licensed open-source African speech corpora. All data is cleared for release.
Limitations
- Not the most accurate per-language read-speech model β Meta MMS leads there (non-commercial; see caveat).
- Pass the language, and pass it as a slot β automatic language detection is unreliable, and the
languageargument is a routing slot, not an ISO code (usesema_lang()). - Ga (
gaa) is not supported β no clean transcribed Ga training data currently exists. - Read-speech benchmarks are FLEURS (clean, recorded); real-world noisy audio is harder.
- Table numbers are 150-clip FLEURS-test / 78-clip code-switch samples (a full-split re-run confirmed them within ~1β3 CER; English is reported on the full 647-clip split) β directional at the decimal, solid at the margin.
- Downloads last month
- 20

