Automatic Speech Recognition
Transformers
Safetensors
Arabic
whisper
arabic
dialectal-arabic
asr
Eval Results (legacy)
Instructions to use oddadmix/whisper-small-arabic-dialectal with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use oddadmix/whisper-small-arabic-dialectal with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("automatic-speech-recognition", model="oddadmix/whisper-small-arabic-dialectal")# Load model directly from transformers import AutoProcessor, AutoModelForSpeechSeq2Seq processor = AutoProcessor.from_pretrained("oddadmix/whisper-small-arabic-dialectal") model = AutoModelForSpeechSeq2Seq.from_pretrained("oddadmix/whisper-small-arabic-dialectal") - Notebooks
- Google Colab
- Kaggle
| """Evaluate a fine-tuned Whisper checkpoint on the test split (WER / CER). | |
| uv run python evaluate_model.py --model ./whisper-small-ar-dialectal | |
| uv run python evaluate_model.py --model openai/whisper-small # baseline | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import torch | |
| import jiwer | |
| from datasets import load_dataset | |
| from transformers import WhisperProcessor, WhisperForConditionalGeneration | |
| from normalize import clean_text | |
| from train import keep_row | |
| DATASET = "oddadmix/dialectal-arabic-lahgtna-v2-smaller-augmented" | |
| def main() -> None: | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--model", required=True) | |
| ap.add_argument("--dataset", default=DATASET) | |
| ap.add_argument("--split", default="test") | |
| ap.add_argument("--batch_size", type=int, default=16) | |
| ap.add_argument("--limit", type=int, default=0, help="0 = full split") | |
| ap.add_argument("--normalize_letters", action="store_true") | |
| args = ap.parse_args() | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| proc = WhisperProcessor.from_pretrained(args.model, language="ar", task="transcribe") | |
| model = WhisperForConditionalGeneration.from_pretrained( | |
| args.model, torch_dtype=torch.bfloat16 | |
| ).to(device).eval() | |
| nl = args.normalize_letters | |
| ds = load_dataset(args.dataset, split=args.split) | |
| ds = ds.filter(lambda text, duration: keep_row(text, duration, nl), | |
| input_columns=["text", "duration"]) | |
| if args.limit: | |
| ds = ds.select(range(min(args.limit, len(ds)))) | |
| print(f"evaluating on {len(ds)} clips") | |
| fe = proc.feature_extractor | |
| preds: list[str] = [] | |
| refs: list[str] = [] | |
| for i in range(0, len(ds), args.batch_size): | |
| rows = ds[i : i + args.batch_size] | |
| arrays = [a["array"] for a in rows["audio"]] | |
| feats = fe(arrays, sampling_rate=16000, return_tensors="pt").input_features | |
| feats = feats.to(device, dtype=torch.bfloat16) | |
| with torch.no_grad(): | |
| gen = model.generate(input_features=feats, max_new_tokens=225) | |
| preds += proc.batch_decode(gen, skip_special_tokens=True) | |
| refs += rows["text"] | |
| print(f" {min(i + args.batch_size, len(ds))}/{len(ds)}", end="\r") | |
| preds = [clean_text(p, nl) for p in preds] | |
| refs = [clean_text(r, nl) for r in refs] | |
| pairs = [(p, r) for p, r in zip(preds, refs) if r.strip()] | |
| preds, refs = map(list, zip(*pairs)) | |
| print("\n" + "=" * 50) | |
| print(f"model : {args.model}") | |
| print(f"WER : {jiwer.wer(refs, preds):.4f}") | |
| print(f"CER : {jiwer.cer(refs, preds):.4f}") | |
| print("--- examples ---") | |
| for r, p in list(zip(refs, preds))[:5]: | |
| print(f" REF: {r[:90]}") | |
| print(f" HYP: {p[:90]}\n") | |
| if __name__ == "__main__": | |
| main() | |