Automatic Speech Recognition
PEFT
Safetensors
Algerian Arabic
whisper
algerian-darija
arabic
lora
qlora
Eval Results (legacy)

Hadra-ASR-whisper-small

The collective's small-scale speech recogniser for Algerian Darja: a QLoRA adapter on openai/whisper-small that adds 25,952,256 trainable LoRA parameters (rank 64) over the frozen 241,734,912-parameter Whisper small base, trained in a 3-phase curriculum over three OddAdmix Algerian speech collections for 15,829 cumulative steps.

On the held-out test splits with the Darija normaliser below, it scores 34.85% WER (Kahwa podcast), 14.87% (Loubna stories), and 27.54% (Rawi stories). Measured once on fixed splits; no independent reproduction run exists yet (see Limitations).

Results

WER on three OddAdmix Algerian test splits, decoded with the Darija normaliser below. Test row counts are unmeasured (the OddAdmix repos publish train splits of 23,264 / 48,590 / 5,296 rows; test partitions are undocumented).

system Kahwa podcast Loubna stories Rawi stories
Hadra-ASR-whisper-small + LoRA 34.85% 14.87% 27.54%
openai/whisper-small unadapted unmeasured unmeasured unmeasured

The headline row above comes from one measurement run under one normaliser. The unadapted base was not scored in the same harness, so no delta is claimed here. Read each WER as a single-run claim: it needs an independent reproduction before it can be quoted as fact.

Anchor harnesses. The collective's default reference suites are DziriEval and MADAR. Both are text suites and do not cover speech recognition, so no anchor score applies to this model — unmeasured with that reason, not by omission.

Intended use

Speech-to-text transcription of Algerian Darja audio: podcasts, YouTube content, interviews, storytelling, subtitling, and voice-assistant input. Fine-tuning starting point for other Algerian Arabic speech tasks.

Not suitable for: text-to-speech or any generation of audio; translation between languages; any language or dialect other than Algerian Darija; any decision about a person. Heavy French code-switching may be transcribed phonetically into Arabic script. Eastern and Saharan accents are outside the training domains and may perform worse. It has not been evaluated for bias, toxicity, or factuality.

Usage

transformers, peft, torch, librosa, nothing else. The adapter loads over openai/whisper-small with trust_remote_code unnecessary — native Whisper classes plus PEFT.

Verified runnable core (transformers 4.57.6, 2026-09-17 — feature extraction only, shapes pasted from the real run):

from transformers import WhisperFeatureExtractor

REPO = "algerian-nlp/Hadra-ASR-whisper-small"
fe = WhisperFeatureExtractor.from_pretrained(REPO)  # sampling_rate 16000
feats = fe(audio_array, sampling_rate=16000, return_tensors="pt").input_features
print(feats.shape)  # torch.Size([1, 80, 3000]) for 1 s of 16 kHz audio

Full transcription path:

import torch
from transformers import pipeline

pipe = pipeline(
    task="automatic-speech-recognition",
    model="algerian-nlp/Hadra-ASR-whisper-small",
    torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
    chunk_length_s=30,
)
result = pipe("path/to/algerian_audio.mp3", generate_kwargs={"language": "arabic", "task": "transcribe"})
print(result["text"])

Known defect, binding on the snippet above. WhisperProcessor.from_pretrained(REPO) and therefore pipeline(...) fail on transformers 4.57.6: the shipped tokenizer_config.json stores extra_special_tokens as a list where current transformers expects a mapping (AttributeError: 'list' object has no attribute 'keys', reproduced 2026-09-17 on this repo). The feature extractor and the weight files are unaffected. Last-known-good transformers version is unmeasured — pin the version you verified before reporting transcription numbers.

Input-preparation notes the reader will get wrong: resample to mono 16,000 Hz float32 first; force the decoder to Arabic (language="arabic", task="transcribe"); score through the Darija normaliser below, not raw strings — the headline WERs were measured after it (diacritics and tatweel stripped, alef/yaa normalised, punctuation stripped).

import string

_ARABIC_DIACRITICS = "ًٌٍَُِّْٰ"
_TATWEEL = "ـ"
_PUNCT_MAP = {ord(c): None for c in string.punctuation + "،؛؟«»"}

def normalize_darja_text(text: str) -> str:
    if not text:
        return ""
    text = text.translate({ord(c): None for c in _ARABIC_DIACRITICS})
    text = text.replace(_TATWEEL, "")
    text = text.replace("إ", "ا").replace("أ", "ا").replace("آ", "ا")
    text = text.replace("ى", "ي")
    text = text.translate(_PUNCT_MAP)
    return " ".join(text.split()).strip()

Architecture

Parameters 267,687,168 total (241,734,912 frozen base + 25,952,256 LoRA trainable, 9.6950%)
Layers / hidden / heads 12 encoder + 12 decoder / 768 / 12 (Whisper small)
Attention Whisper encoder-decoder, unchanged
Adapter LoRA rank 64, alpha 128, dropout 0.05 on q_proj k_proj v_proj out_proj fc1 fc2, bias none (from adapter_config.json in this repo)
Quantization 4-bit NF4 base with fp16 compute via bitsandbytes
Positions / max length Whisper 30-second chunks (chunk_length_s=30)
Objective ASR cross-entropy fine-tuning, sequential 3-phase curriculum

Deviations from the reference (openai/whisper-small): the base weights are frozen and quantised, all learning sits in the LoRA adapters, and training runs as a curriculum — Kahwa conversational podcasts first, Loubna expressive stories second, Rawi narratives third — rather than one mixed run. phase_state.json in this repo records all three phases complete at global step offset 15,829, one more than the phase-step sum (4,942 + 10,324 + 562 = 15,828).

Training data

Three OddAdmix Algerian speech collections (train rows counted 2026-09-17 via the Hub datasets-server): Kahwa podcast 23,264 rows, Loubna stories 48,590 rows, Rawi stories 5,296 rows — 77,150 rows total. Audio resampled to mono 16 kHz; transcripts filtered to 0.5–30.0 s duration and 1.0–25.0 chars/sec density; French tags, bracketed markers, diacritics, tatweel, and punctuation stripped by the normaliser above.

Decontamination. Unmeasured: no screen of training audio against the test splits is documented, and the test partitions themselves are undocumented.

Licence composition of the training audio

The adapter weights are MIT. That grant does not relicense the audio they were trained on. The composition, so you can make your own judgement:

tier rows share
other (unresolvable Hub licence on all three OddAdmix sets) 77,150 100%

All three OddAdmix collections carry license:other in Hub metadata. A permissive-only rebuild cannot be cut by code from this information — contact the audio owners before redistributing derivatives.

Training recipe

Objective ASR fine-tuning of LoRA adapters, base frozen
Optimiser AdamW, per-phase learning rate (betas unmeasured)
Batch 8 per device × 4 accumulation = 32 effective
Schedule cosine annealing with warmup 100 / 50 / 30 steps per phase
Steps 15,829 — Phase 1 Kahwa 4,942 (lr 1e-4) → Phase 2 Loubna 10,324 (lr 5e-5) → Phase 3 Rawi 562 (lr 2e-5)
Regularisation gradient checkpointing; LoRA dropout 0.05
Precision 4-bit NF4 base, fp16 compute
Hardware 1× NVIDIA Tesla T4 16 GB; wall-clock unmeasured
Seed unmeasured

Final eval losses: 0.521 (Phase 1), 0.312 (Phase 2), 0.2548 (Phase 3). The curve is single-run and unverified beyond the run record. Checkpoints were saved on best WER per phase with automatic Hub upload; the W&B project k_touati-estin/whisper-algerian-darja-v5 is the run record.

Limitations

All three WERs are single-run and unreproduced. 14.87–34.85% WER on spontaneous dialectal speech comes from one measurement with no eval logs, no published test rows, and no seed — the constraint on every claim in Results is an independent reproduction run, which does not exist yet.

The shipped processor config is broken on current transformers. tokenizer_config.json fails WhisperProcessor.from_pretrained on transformers 4.57.6 (list-shaped extra_special_tokens); the feature extractor and weights load fine. Any transcription number must name the transformers version it ran on.

Three domains are the whole world. Kahwa podcasts plus Loubna and Rawi storytelling, all OddAdmix — Central/Western accents dominate; Eastern, Saharan, noisy-field, and heavily French-matrix audio are outside the measured envelope.

Contamination is unbounded, not cleared. Train/test partitioning of the OddAdmix audio is undocumented, so test leakage can neither be confirmed nor excluded.

Evaluated once vs unmeasured. Transcription WER on three fixed splits (one run) vs everything else: no anchor suite, no robustness sweep, no human side-by-side.

No safety evaluation of any kind has been performed.

Files

file size contents
adapter_model.safetensors 103,862,440 LoRA adapter weights (25,952,256 params) + SHA-256 4e31cc55f90fc620f0da088945709a7d8fa5660b9e7f8a8c8dfcc75c0a8ac4ca
adapter_config.json 1,261 LoRA hyperparameters; declares base openai/whisper-small and task type SEQ_2_SEQ_LM
tokenizer.json 3,931,328 fast tokenizer (see processor defect above)
tokenizer_config.json 2,125 tokenizer wiring — carries the list-shaped extra_special_tokens defect
processor_config.json 409 feature-extractor wiring (loads clean)
phase_state.json 93 curriculum record: all three phases complete at step 15,829

Sizes read from resolved Hub downloads 2026-09-17; the adapter SHA-256 was hashed from the downloaded bytes. Deliberately not shipped: the frozen Whisper-small base (fetch openai/whisper-small), the optimizer state, and the training audio.

Config fix 2026-09-17. The shipped adapter_config.json carried "task_type": null, which trips a configuration parsing warning ("peft.task_type" must be a string) on load. It now declares "task_type": "SEQ_2_SEQ_LM" — the correct PEFT task type for an encoder-decoder ASR adapter. Ten bytes changed and nothing else: the adapter weights are untouched, so the SHA-256 above still holds. Verified with PeftConfig.from_pretrained on this repo — task_type parses as SEQ_2_SEQ_LM with no warning. The remaining monteclora_config / velora_config notice is benign version skew (keys written by PEFT 0.20.0, ignored by older readers) and was deliberately left in place rather than falsifying the training artifact.

Reproduction

Source checkpoint: the adapter in this repo, SHA-256 4e31cc55f90fc620f0da088945709a7d8fa5660b9e7f8a8c8dfcc75c0a8ac4ca; loads over openai/whisper-small with zero missing keys expected (adapter-only file).

# Training has no published script — the run record is the provenance.
# Transcription (after the processor-config fix lands):
pipe = pipeline(task="automatic-speech-recognition",
                model="algerian-nlp/Hadra-ASR-whisper-small",
                chunk_length_s=30)
pipe("clip.mp3", generate_kwargs={"language": "arabic", "task": "transcribe"})

Seeding notes: the training seed is unmeasured — reruns will move by an unmeasured amount. If a number cannot be reproduced from this section, it is not a result: that applies to every WER in Results until an independent run reproduces them.

Citation

@misc{algerian_nlp_hadra_asr_whisper_small_2026,
  title  = {Hadra-ASR-whisper-small: Algerian Darja speech recognition with a Whisper-small LoRA adapter},
  author = {Touati, Kamel and Algerian NLP Collective},
  year   = {2026},
  url    = {https://huggingface.co/algerian-nlp/Hadra-ASR-whisper-small}
}
@article{radford2022whisper,
  title={Robust Speech Recognition via Large-Scale Weak Supervision},
  author={Radford, Alec and Kim, Jong Wook and Xu, Tao and Brockman, Greg and McLeavey, Christine and Sutskever, Ilya},
  journal={arXiv preprint arXiv:2212.04356},
  year={2022}
}

Licence

MIT for the adapter weights and card. Read the licence composition of the training audio above before redistributing derivatives — a permissive grant on the adapter makes no claim about the underlying speech.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for algerian-nlp/Hadra-ASR-whisper-small

Adapter
(287)
this model

Datasets used to train algerian-nlp/Hadra-ASR-whisper-small

Paper for algerian-nlp/Hadra-ASR-whisper-small

Evaluation results

  • WER (test, darija normaliser; single run, seeds unmeasured) on OddAdmix Algerian Kahwa Podcast (test)
    self-reported
    0.348
  • WER (test, darija normaliser; single run, seeds unmeasured) on OddAdmix Algerian Loubna Stories (test)
    self-reported
    0.149
  • WER (test, darija normaliser; single run, seeds unmeasured) on OddAdmix Algerian Rawi Stories (test)
    self-reported
    0.275