whisper-large-v3-da-coral-lora

LoRA fine-tune of openai/whisper-large-v3 for Danish speech recognition, trained on CoRal-project/coral-v3 (conversation split) with telephone-codec augmentation to close the domain gap between CoRal's clean studio recordings and real telephone-call audio.

Model description

  • Base model: openai/whisper-large-v3
  • Method: LoRA (PEFT), rank=32, alpha=64, dropout=0.05, target modules: q_proj, v_proj
  • Trainable parameters: 15.7M (1.01% of the 1.56B total)

Training data

CoRal-project/coral-v3 β€” real, human-transcribed Danish speech collected by the Alexandra Institute with Danish Innovation Fund support. Only the conversation split was used (not read_aloud); 10,000 raw samples were filtered and augmented down to 9,027 training chunks (9.9 hours of audio):

  • ~74% telephone-codec-simulated (8kHz bandwidth limiting, low-bitrate mp3 round-trip, light noise) β€” to match real telephone-call audio, since coral-v3's raw recordings are clean/studio-quality, not phone-quality
  • ~26% clean (loudness-normalized only) β€” to help retain general Danish transcription ability alongside the telephone-domain adaptation
  • All samples loudness-normalized (EBU R128, -16 LUFS) β€” coral-v3's raw recordings have highly inconsistent levels, some near-silent

coral-v3 is released under an OpenRAIL license; this model inherits that license.

Training procedure

  • 2 epochs, effective batch size 32 (per-device batch 1, grad accumulation 32)
  • Learning rate 1e-4, linear warmup over the first 40 of 548 total steps
  • fp16, gradient checkpointing
  • No read_aloud data was used in training (see evaluation below for the effect)

Evaluation

Evaluated against a held-out coral-v3 set (94 conversation + 100 read_aloud samples, disjoint from training β€” guaranteed by skipping the exact sample count training consumed with the same shuffle seed) with real ground truth, so WER is directly computable:

model conversation WER read_aloud WER
whisper-large-v3 (untrained base) 0.704 0.303
this model 0.367 0.220
CoRal roest-v3-whisper-1.5b (purpose-built Danish model) 0.327 0.101

This model nearly halves conversational Danish WER relative to the untrained base, closing most of the gap to CoRal's own purpose-built model starting from a generic base. The read_aloud improvement is smaller because training only used the conversation split.

Limitations

A qualitative audit on 30 real (non-coral, actual telephone call) Danish recordings found a ~13% fabrication rate β€” invented person names, invented entities, or meaning-inverting errors not present in the base model's output for the same audio. Examples observed: inventing a name not supported by any reference transcription, and inverting a stated success/failure outcome. The untrained base model has a comparable overall failure rate on real calls too (it has its own well-known hallucination pattern on quiet audio, which this model appears to suppress, at the cost of introducing different errors elsewhere) β€” so this isn't unique to fine-tuning, but it does mean:

  • Do not use this model as a sole source for automated name/entity extraction without cross-checking against a second model or human review.
  • Output drops most punctuation and capitalization, following coral-v3's transcription convention β€” apply punctuation restoration as a post-process step if a clean, readable transcript is required.
  • Performs noticeably better on informal conversational Danish than on formal/read-aloud style speech, since training only covered the former.

Usage

import torch
from transformers import WhisperForConditionalGeneration, WhisperProcessor
from peft import PeftModel

REPO = "x2q/whisper-large-v3-da-coral-lora"
processor = WhisperProcessor.from_pretrained(REPO, language="danish", task="transcribe")
base = WhisperForConditionalGeneration.from_pretrained(
    "openai/whisper-large-v3", torch_dtype=torch.float16
).to("cuda")
model = PeftModel.from_pretrained(base, REPO).eval()

# inputs = processor.feature_extractor(audio, sampling_rate=16000, return_tensors="pt") \
#     .input_features.to("cuda").half()
# ids = model.generate(inputs, language="danish", task="transcribe", num_beams=5)
# processor.tokenizer.decode(ids[0], skip_special_tokens=True)
Downloads last month
2
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for x2q/whisper-large-v3-da-coral-lora

Adapter
(226)
this model

Dataset used to train x2q/whisper-large-v3-da-coral-lora