arnauld-a/griot-lora-ewe-turbo-dual
Griot ASR — LoRA ewe, corpus combiné (Whisper large-v3-turbo)
Adaptateur LoRA pour l'ewe (ee, famille Gbe, Ghana et Togo), entraîné sur deux corpus combinés : google/WaxalNLP (description d'image) et Nelver28/ewe-asr (texte biblique). Second volet de l'étude Griot sur l'ewe, après un premier modèle entraîné sur Waxal seul (`griot-lora-ewe-turbo`).
⚠️ Ce modèle nécessite un paramètre d'inférence non standard, sans lequel 13 à 16 % des transcriptions sont tronquées en plein milieu d'un mot — voir [Inférence](#inférence) avant tout usage.
Composition du corpus d'entraînement
\Nombre de locuteurs Nelver28 connu par métadonnées globales — les identifiants individuels ne sont pas publiés dans le dépôt.*
Intégrité train/test
Contrairement au corpus Waxal, dont la disjonction speaker-level est vérifiée via data/ASR_v2/metadata/split_map/ewe.csv, l'absence de fuite de locuteurs entre train et test de Nelver28 ne peut pas être confirmée. Avec seulement 10 locuteurs déclarés au total, le risque de recouvrement est non négligeable si le split n'a pas été construit avec cette contrainte. Les métriques sur le test Nelver28 sont donc à lire avec cette réserve.
Sélection du checkpoint
Évaluation en cours d'entraînement (greedy, jeu de validation combiné) :
Le meilleur checkpoint par CER et WER (2500) diffère légèrement du meilleur par eval_loss (2000) — la sélection s'est faite sur le CER, la métrique la plus proche de l'usage réel. Ces chiffres sont mesurés en greedy, sur un jeu de validation, et ne sont pas comparables aux résultats de production ci-dessous, mesurés en beam=4 avec le correctif d'inférence sur les deux jeux de test séparément.
Avec un batch effectif calculé à partir du nombre de pas et d'epochs déclarés (2975 pas ÷ 5,00 epochs × 38 539 énoncés d'entraînement) : ≈ 65 — nettement plus large que le batch de 16 utilisé sur les runs mono-corpus, cohérent avec un volume d'entraînement 3× supérieur (160 h contre 50 h).
Résultats de production — test v2 par corpus, beam=4, correctif appliqué
\Effondrement mesuré relativement à la longueur de référence (n_mots_hyp < 0,5 × n_mots_ref), pas par seuil absolu — voir la note méthodologique ci-dessous.*
\\Un seuil absolu de 10 mots détectait initialement 231/2 931 (7,9 %) « effondrés » sur Nelver28. Diagnostic par logits sur ces cas : `<|endoftext|>` au rang 0 avec 92–99,9 % de confiance, aucune sur-représentation des tokens ajoutés — ce ne sont pas des troncatures mais des transcriptions complètes et correctes d'énoncés courts (listes de noms propres, citations brèves), propres au registre biblique de ce corpus. Le seuil absolu, calibré sur la structure de Waxal (33,8 mots/énoncé en moyenne), n'était pas transposable à Nelver28.
Le CER nettement meilleur sur Nelver28 (2,97 contre 12,44 sur Waxal) reflète la différence de registre — versets courts et formulaïques contre description d'image en plusieurs phrases — pas une meilleure qualité acoustique.
Inférence
from peft import PeftModel
from transformers import (WhisperForConditionalGeneration, WhisperProcessor,
WhisperTokenizer)
REPO = "arnauld-a/griot-lora-ewe-turbo-dual"
BASE = "openai/whisper-large-v3-turbo"
tok = WhisperTokenizer.from_pretrained(REPO) # vocabulaire étendu (51 883)
proc = WhisperProcessor.from_pretrained(REPO)
m = WhisperForConditionalGeneration.from_pretrained(BASE)
m.resize_token_embeddings(len(tok)) # AVANT l'adaptateur
m = PeftModel.from_pretrained(m, REPO).merge_and_unload()
out = m.generate(features, language="<|ewe|>", task="transcribe",
num_beams=4, repetition_penalty=1.0, no_repeat_ngram_size=14,
max_new_tokens=440, length_penalty=1.2,
return_dict_in_generate=True, output_scores=True) # ← OBLIGATOIRE
hyp = tok.decode(out.sequences[0], skip_special_tokens=True)return_dict_in_generate=True, output_scores=True sont obligatoires
Sans ces deux paramètres — documentés par transformers comme n'affectant que le format de la sortie retournée, pas la génération elle-même — 13 à 16 % des transcriptions s'arrêtent en plein milieu d'un mot, avec une forte confiance résiduelle du modèle sur la suite correcte au moment de la coupure (<|endoftext|> classé au rang 34 000–37 000 sur ~52 000 candidats). Avec ces deux paramètres : CER divisé par plus de 2, effondrement divisé par plus de 100 sur le test Waxal.
Investigation complète, dix-sept hypothèses écartées avant celle-ci (scaling LoRA, gel des embeddings, volume de données, contamination du clavier dans le corpus, taille de batch...) : voir ewe_artefact_troncature_synthese.md sur demande.
num_return_sequences n'a aucun effet sur cet artefact, seul ou combiné avec les paramètres ci-dessus — inutile de le passer si vous ne voulez qu'une séquence.
length_penalty doit retomber à 1.0 sur le chemin long-form (>30 s) : sur une fenêtre ne portant que quelques secondes de parole, 1.2 pousse le décodeur à combler le vide. 1/1 884 énoncés Waxal et 29/2 931 énoncés Nelver28 du test dépassent ce seuil.
Vocabulaire
51 866 → 51 883 tokens (un token de plus que le modèle mono-corpus Waxal, griot-lora-ewe-turbo à 51 882) : 14 caractères ewe, le tilde combinant U+0303 (nasalisation), <\|ewe\|>, et un token <\|pad\|> dédié — distinct de <\|endoftext\|>, jamais entraîné puisque toujours masqué dans les labels.
Licence
⚠️ Statut de licence composite, non résolu.
google/WaxalNLP: CC-BY-4.0 (Université du Ghana).Nelver28/ewe-asr: aucune licence déclarée sur le dépôt source au moment de l'entraînement.
Ce modèle est entraîné sur un mélange incluant des données dont les conditions de réutilisation ne sont pas explicitées. À clarifier auprès du mainteneur de Nelver28/ewe-asr avant toute redistribution commerciale. Modèle de base (openai/whisper-large-v3-turbo) sous Apache-2.0.
Références
Voir le README du modèle mono-corpus `griot-lora-ewe-turbo` pour le détail des 17 hypothèses testées sur l'artefact de troncature, les runs comparatifs (LoRA turbo/large-v3, gel/dégel des embeddings, full fine-tuning), et les références bibliographiques.
