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.

Countries where the trained languages are spoken

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 plus label_map ({"0": "female", "1": "male"}), the output-index mapping needed to interpret the head's output
  • metrics.json - full validation/test metrics, including the per-language table above
  • scripts/gender_id.py - reusable GenderClassifier class
  • scripts/infer_file.py - classify one audio file
  • scripts/infer_batch.py - classify every .wav in a directory
  • scripts/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
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Dataset used to train AfriSpeech/afrispeech-gender-id