AfriSpeech Gender-ID
Predicts speaker gender (male/female) from short African-language speech clips (16 kHz). Trained and evaluated on google/WaxalNLP (ASR + TTS configs).
How it works
A 3D-Speaker CAM++ model trained
on VoxCeleb at 16 kHz, 512-dim output, as part of its
speaker-diarization/verification pipeline. This repo only ships a tiny MLP
head (onnx/model.onnx, 512 -> 64 -> 2) trained on top of
those embeddings.
Training data
WaxalNLP rows across 25 language configs where the gender field normalized
cleanly to male/female (case-insensitive male/m/female/f). Rows with a
blank or other value (e.g. "unknown") were dropped, as were configs where
every row failed to normalize - aka_asr, dag_asr, dga_asr, ewe_asr,
ful_asr, kpo_asr, mlg_asr, bau_tts, ewe_tts have no usable gender
labels in this dataset and are not represented in this model.
330,027 labeled utterances total (train=275862, validation=25667, test=28498). Splits follow WaxalNLP's own
train/validation/test partition (not re-shuffled). (Note: WaxalNLP's sog
config is Soga/Lusoga - tagged here as xog, its real ISO 639-3 code, since
sog is actually Sogdian.)
Training: 64-unit MLP head, Adam @ lr=0.001, batch size 256, 60 epochs, best checkpoint picked by validation accuracy.
Language coverage
Evaluated on these 22 languages: ach, amh, fat, ful, hau, ibo, kik, lin, lug, luo, mas, nyn, orm, pcm, sid, sna, swa, tir, twi, wal, xog, yor.
Sub-Saharan Africa only, shaded by how many of the 22 trained languages are spoken in each country (darker = more) - North Africa is intentionally left uncolored since none of the training data comes from there.
Gender shows up in pitch, formants, and voice-quality acoustics that aren't
very language-specific, so this model is a reasonable starting point for
Sub-Saharan African languages beyond the ones above too - it just hasn't
been measured on them. It's specifically scoped to Sub-Saharan Africa because
that's what WaxalNLP (and therefore this model's training data) covers - none
of the languages above are North African, so no claim is made there. The
language tags on this model card cover the wider Sub-Saharan African
language directory (via afriso) for
discoverability, not a claim of measured accuracy on every one of them.
Evaluation
- Validation accuracy: 0.9840
- Test accuracy: 0.9358
- Test macro F1: 0.9347
Speed (CPU only)
- Embedding extraction: 392 ms for a 31s clip (2 CPU threads)
- Gender head inference: 0.16 ms (negligible next to the embedding step)
- Real-time factor: 78x - a 3-second clip classifies in ~38 ms of compute
No GPU required for inference; this is exactly what the model card's Quickstart runs.
Comparison to other gender-ID models
On a stratified sample of 2215 held-out WaxalNLP test clips across 22 languages, against public gender-ID models that never saw African-language speech in training (all out-of-domain for them by construction):
| Model | Trained on | License | Accuracy | Macro F1 |
|---|---|---|---|---|
| Ours (sherpa-onnx embedding + tiny head) | WaxalNLP (African languages) | CC-BY-4.0 | 0.976 | 0.976 |
| audeering/wav2vec2-large-robust-24-ft-age-gender | aGender + Common Voice + TIMIT + VoxCeleb2 (EN/DE) | CC-BY-NC-SA-4.0 (non-commercial) | 0.935 | 0.935 |
| alefiury/wav2vec2-large-xlsr-53-gender-recognition-librispeech | LibriSpeech train-clean-100 (English, read speech) | Apache-2.0 | 0.911 | 0.910 |
| JaesungHuh/voice-gender-classifier | VoxCeleb2 (English-dominant celebrity interviews) | MIT | 0.934 | 0.934 |
| prithivMLmods/Common-Voice-Gender-Detection | Common Voice (crowdsourced, English-dominant) | Apache-2.0 | 0.940 | 0.940 |
| griko/gender_cls_svm_ecapa_voxceleb | VoxCeleb2 (English-dominant celebrity interviews) | Apache-2.0 | 0.931 | 0.931 |
This is an accuracy-only comparison, deliberately - the baselines run as plain PyTorch/transformers models, while ours is ONNX-exported, so a latency comparison would mostly measure that export gap rather than anything about the approach itself. See the Speed section above for this model's own real-world inference latency.
audeering's model natively outputs a 3-way female/male/child softmax, folded here to binary by taking the argmax over just female/male; it's also the only baseline with a non-commercial license (CC-BY-NC-SA-4.0) - everything else here, including ours, is Apache-2.0/MIT/CC-BY-4.0.
Quickstart
pip install sherpa-onnx onnxruntime huggingface_hub soundfile numpy
from huggingface_hub import hf_hub_download
import sherpa_onnx, onnxruntime as ort, soundfile as sf, numpy as np, json
# 1. sherpa-onnx's pretrained speaker-embedding extractor (unchanged, public)
embed_path = hf_hub_download("csukuangfj/speaker-embedding-models", "3dspeaker_speech_campplus_sv_en_voxceleb_16k.onnx")
extractor = sherpa_onnx.SpeakerEmbeddingExtractor(
sherpa_onnx.SpeakerEmbeddingExtractorConfig(model=embed_path, num_threads=2, provider="cpu")
)
# 2. this repo's tiny gender head + its config (holds the label map)
head_path = hf_hub_download("AfriSpeech/afrispeech-gender-id", "onnx/model.onnx")
config = json.load(open(hf_hub_download("AfriSpeech/afrispeech-gender-id", "config.json")))
label_map = config["label_map"]
session = ort.InferenceSession(head_path, providers=["CPUExecutionProvider"])
# 3. run on a 16 kHz mono wav file
audio, sr = sf.read("sample.wav", dtype="float32")
stream = extractor.create_stream()
stream.accept_waveform(sample_rate=sr, waveform=audio)
stream.input_finished()
embedding = np.asarray(extractor.compute(stream), dtype=np.float32).reshape(1, -1)
logits = session.run(["logits"], {"embedding": embedding})[0][0]
pred = label_map[str(int(logits.argmax()))]
print(pred)
See scripts/ for ready-to-run CLI versions of the above (single file and
whole-directory batch), built on the same gender_id.py helper.
Files
onnx/model.onnx- the trained MLP head (embedding -> logits)config.json- architecture metadata pluslabel_map({"0": "female", "1": "male"}), the output-index mapping needed to interpret the head's outputmetrics.json- full validation/test metrics, including the per-language table abovescripts/gender_id.py- reusableGenderClassifierclassscripts/infer_file.py- classify one audio filescripts/infer_batch.py- classify every.wavin a directoryscripts/requirements.txt- minimal deps for the scripts above
License
Model head weights: CC-BY-4.0, matching WaxalNLP's training data license. The embedding extractor and its license are hosted separately at csukuangfj/speaker-embedding-models.
- Downloads last month
- 289
