run6_checkpoint_12000s : Whisper darija-v5 fine-tuné (run 6, step 12000)
Fine-tuning de darija-v5 (whisper-darija-v5-checkpoint-2800) pour la
transcription de la darija marocaine avec alternance français/anglais.
Ce modèle a aussi appris à ne rien écrire sur du silence ou du bruit.
Entraînement
- Données : lmaana, Dataset13, batch2, batch4, batch5 (309 346 segments)
- 400 segments de silence/bruit répétés 5 fois (0,64 %)
- 12 000 steps d'un programme de 19 458 (2 époques), batch 32, LR 1e-6 (warmup 500, décroissance linéaire), weight decay 0,01, SpecAugment, bf16
- Choisi par une règle fixée avant les mesures : le plus ancien checkpoint du plateau, aucun plus tardif ne faisant mieux de plus de 0,2 point
Résultats (fp32, décodage greedy, normalisation darija)
eval_isma : 357 phrases annotées par des humains.
| Modèle | WER | CER | Sub. | Del. | Ins. |
|---|---|---|---|---|---|
| darija-v5 (départ) | 0.1871 | 0.0845 | 0.1407 | 0.0257 | 0.0207 |
run 5 (run5_bestcheckpoint) |
0.1577 | 0.0703 | 0.1207 | 0.0202 | 0.0168 |
| ce modèle | 0.1509 | 0.0711 | 0.1125 | 0.0212 | 0.0172 |
Silence : 80 segments de bruit jamais vus à l'entraînement, fin de texte permise dès le premier token.
| Modèle | Segments où le modèle écrit quelque chose |
|---|---|
| darija-v5 | 100 % |
| ce modèle | 0 % |
Autoriser la sortie vide ne change rien sur eval_isma (mêmes WER et suppressions au chiffre près). eval_isma a aussi servi au choix du checkpoint : les chiffres peuvent être légèrement optimistes.
Utilisation
Par défaut, Whisper interdit la fin de texte comme premier token
(begin_suppress_tokens) : il écrit toujours au moins un mot, même sur du
silence. Pour profiter de l'apprentissage du silence, on calcule d'abord le
premier token ; s'il s'agit de la fin de texte, la transcription est vide.
import torch
from transformers import WhisperForConditionalGeneration, WhisperProcessor
repo = "mouadElmansour/run6_checkpoint_12000s"
processor = WhisperProcessor.from_pretrained(repo)
model = WhisperForConditionalGeneration.from_pretrained(repo).eval()
tok = processor.tokenizer
def transcrire(audio): # tableau float32 mono à 16 kHz
features = processor(audio, sampling_rate=16000, return_tensors="pt").input_features
prompt = [tok.convert_tokens_to_ids(t) for t in
("<|startoftranscript|>", "<|ar|>", "<|transcribe|>", "<|notimestamps|>")]
with torch.no_grad():
logits = model(input_features=features, decoder_input_ids=torch.tensor([prompt])).logits[0, -1]
interdits = set(model.generation_config.suppress_tokens or []) | {220}
logits[sorted(interdits)] = float("-inf")
if logits.argmax().item() == tok.eos_token_id:
return "" # silence
ids = model.generate(features, language="ar", task="transcribe", num_beams=1)
return processor.batch_decode(ids, skip_special_tokens=True)[0]
- Downloads last month
- 4