Edda v0.2 large hurtig: faster Danish speech recognition

This is Edda v0.2 large by the Alexandra Institute and Danish Foundation Models, with a small drafter model added on top. All of the speech recognition is done by edda. Its weights here are byte-identical to the original release. syv.ai trained only the drafter, which makes edda's greedy decoding faster without changing what it writes. Please credit and cite the original edda model when you use this.

Hurtig is Danish for fast.

Edda decodes one token per forward pass of its 32-layer decoder. Here, a 170M-parameter DFlash2-style block-diffusion drafter proposes up to 15 tokens at once. Edda checks the whole block in one forward pass and keeps the longest prefix it agrees with, plus its own next token. Edda's greedy choice still decides every token, so the transcript is edda's greedy transcript, produced about 2.4Γ— faster.

Results

Measured end to end, encoder included, at batch size 1 on one RTX 3090 in fp16. The test used 60 clips of at most 30 s from each test set of the open Danish ASR leaderboard. "Identical" compares against edda's own greedy generate() output.

test set identical tokens per edda pass speed-up edda greedy β†’ hurtig
FTSpeech 60/60 9.31 3.22Γ— 407 β†’ 126 ms
FLEURS da_dk 60/60 5.56 2.57Γ— 467 β†’ 182 ms
CoRal-v3 conversation 60/60 5.63 2.23Γ— 298 β†’ 134 ms
CoRal-v3 read-aloud 60/60 4.56 1.99Γ— 291 β†’ 147 ms
Common Voice Danish 59/60 5.41 1.91Γ— 218 β†’ 114 ms
all 299/300 5.94 2.39Γ— 336 β†’ 140 ms

The one clip that differs is a half-precision near-tie. Verifying a block of tokens in one pass can flip a choice between two almost equally likely tokens, compared with decoding them one at a time.

Greedy, not beam search. Edda's default decoding is beam search with 5 beams, and that is what its published WER of 8.65 uses. Hurtig reproduces edda's greedy output, which has a somewhat higher WER than 5-beam search. Use plain edda with beams if you need the last bit of accuracy, and hurtig if you need speed.

Usage

# pip install transformers torch safetensors huggingface_hub soundfile
import sys, soundfile as sf
from huggingface_hub import snapshot_download

path = snapshot_download("syvai/edda-v0.2-large-hurtig")
sys.path.insert(0, path)
from hurtig import load, transcribe

model, drafter, processor = load(path)          # edda + drafter on CUDA in fp16
audio, sr = sf.read("clip.wav", dtype="float32")  # mono, 16 kHz, at most 30 s
print(transcribe(model, drafter, processor, audio, sampling_rate=sr))

hurtig.spec_generate(model, drafter, mel) returns the token ids and the number of tokens accepted per edda pass. The repo still loads as plain edda: WhisperForConditionalGeneration.from_pretrained("syvai/edda-v0.2-large-hurtig") ignores the drafter files.

Limitations:

  • Batch size 1 only.
  • Danish transcription without timestamps only (prompt <|da|><|transcribe|><|notimestamps|>).
  • Clips of at most 30 s; longer audio has to be chunked first.

The drafter

hurtig.py follows z-lab/dflash's DFlash2DraftModel, adapted to Whisper:

  • Block drafting. A block is the last verified token followed by 15 mask slots. Each slot predicts its own token in a single forward pass.
  • Context from edda. Hidden states from edda decoder layers 1, 8, 15, 22 and 29 are concatenated and passed through a linear layer and RMSNorm. The result is injected as extra keys and values into each draft layer's self-attention.
  • Audio. Each draft layer also cross-attends to edda's encoder output.
  • DFlash2 additions. A grouped two-tap dynamic causal convolution sits around self-attention and the MLP. A candidate selector takes the top 16 tokens per slot and picks a consistent path with a rank-256 pairwise score.
  • Initialisation and size. The 5 draft layers start as copies of edda decoder layers 0, 8, 16, 23 and 31. Token embeddings, positions and the output head are edda's own, frozen and not stored. The drafter has 170M trainable parameters, stored in fp16 as drafter.safetensors.

Training. The drafter was trained for 20k steps on edda's own greedy transcripts of 80k Danish training clips. The audio came from FTSpeech, CoRal-v3, NST, FLEURS and Common Voice train splits, in edda's training mix. It learns to predict what edda will write, not the reference transcripts. Loss is DFlash's position-decayed cross-entropy (Ξ³ = 7) plus a cross-entropy loss on the selector.

License and attribution

Apache License 2.0, the same as edda.

  • Edda v0.2 large (model.safetensors, config.json, generation_config.json, the tokenizer and preprocessor files) is redistributed unchanged from danish-foundation-models/edda-v0.2-large. Edda was trained by the Alexandra Institute within the CoRal project and released by Danish Foundation Models under the Apache License 2.0. Its base model, openai/whisper-large-v3, is MIT-licensed.
  • The drafter (drafter.safetensors, drafter_config.json, hurtig.py) was trained by syv.ai. It is a derivative of edda: it is initialised from edda's decoder layers and trained on edda's outputs.
  • Method: DFlash (arXiv:2602.06036) and DFlash2 by z-lab (github.com/z-lab/dflash).

The training audio corpora carry their own licenses; see the respective dataset cards linked from edda's model card.

Downloads last month
85
Safetensors
Model size
2B params
Tensor type
F16
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for syvai/edda-v0.2-large-hurtig

Finetuned
(1)
this model

Paper for syvai/edda-v0.2-large-hurtig