norsk-parakeet

Norwegian (Bokmål) speech recognition: moondream/parakeet-ultra, a post-trained NVIDIA Parakeet TDT 0.6B v3, fine-tuned on about 2,400 hours of Norwegian speech in two stages. It writes cased, punctuated text.

  • v3 (current, 31 Oct 2026): stage 1 plus continued training on additional Norwegian speech. At least as good as v2 on every test set, without v2's runaway output.
  • v2 (tag v2): an earlier continuation of stage 1. It sometimes keeps writing after the speech ends; use v3 instead.
  • v1 (tag v1): stage 1 only, one epoch on open Norwegian speech. Load it with from_pretrained("ahdrage/norsk-parakeet", revision="v1").

Code, training recipe and progress log: github.com/ahdrage/norsk-parakeet.

Known issue: numbers glued to the word before

This version often writes "september2017" for "september 2017", because the training labels lost the word boundary before numbers. Word scores are not affected. Until a retrained version is out, fix it after decoding:

import re
text = re.sub(r"(?<=[a-zæøåéèêóòôüäö])(?=\d)|(?<=[^\d\s][,;:])(?=\d)", " ", text)

Results

WER (%) on digit-free utterances, text normalized (lowercase, no punctuation) as in norsk-asr. Same test subsets for every row: 1,000 utterances of NPSC and NST, all of FLEURS nb (357) and Stortinget validation (697).

Model Params FLEURS NPSC NST Stortinget
NB-Whisper large 1.55B 4.2 16.5 2.0 9.0
norsk-asr + 4-gram LM – 10.0 9.7 5.6 12.2
parakeet-ultra, zero-shot 0.6B 64.3 71.8 67.1 74.7
norsk-parakeet v1 (greedy, no LM) 0.6B 8.1 7.6 4.6 11.2
norsk-parakeet v2 (greedy, no LM) 0.6B 6.7 7.1 4.4 11.0
norsk-parakeet v3 (greedy, no LM) 0.6B 6.2 7.1 4.2 10.9

Runaway output on 3,571 held-out clips:

v1 v2 v3
Clips repeating a phrase 3 20 2
Fastest output (words per second of audio) 97 128 7

Inference runs at roughly 500–800× real time on an RTX PRO 4000 Blackwell.

Usage

import torch
from transformers import AutoProcessor, ParakeetForTDT

processor = AutoProcessor.from_pretrained("ahdrage/norsk-parakeet")
model = ParakeetForTDT.from_pretrained("ahdrage/norsk-parakeet").eval()
# audio: 16 kHz mono float32 numpy array, up to ~30 s per clip
inputs = processor(audio, sampling_rate=16000, return_tensors="pt")
with torch.no_grad():
    out = model.generate(**inputs)
print(processor.batch_decode(out.sequences, skip_special_tokens=True)[0])

Requires transformers >= 5.21.

Longer audio should be cut at pauses into chunks of up to 30 s. On 10 h of held-out whole recordings, WER was 11.0 with these cuts, 11.5 with fixed 30 s cuts and 14.0 with fixed 15 s cuts, where a cut in the middle of speech can also make the model run away. Chunks much longer than 30 s loop more often.

import numpy as np

def split_at_pauses(wav, max_s=30, sr=16000):
    hop, n = sr // 20, int(max_s * sr)
    if len(wav) <= n:
        return [wav]
    frames = wav[:len(wav) // hop * hop].reshape(-1, hop).astype(np.float64)
    energy = np.convolve((frames**2).mean(1), np.ones(4) / 4, "same")  # over 200 ms
    chunks, a = [], 0
    while len(wav) - a > n:
        lo, hi = (a + n * 2 // 3) // hop, (a + n) // hop  # the quietest point in the last third
        b = (lo + int(np.argmin(energy[lo:hi]))) * hop
        chunks.append(wav[a:b])
        a = b
    return chunks + [wav[a:]]

Transcribe the chunks as above, in batches, and join the text.

Training

  • Data: the National Library of Norway's open releases of Stortinget speech, NST and NPSC (Bokmål train), filtered as in norsk-asr: digit-free utterances whose transcripts agree with a Whisper pass (WER ≤ 0.15), clips up to 30 s, implausible speech rates removed.
  • Recipe: all parameters, AdamW, peak LR 5e-5 with cosine decay, 64 s of audio per batch, bf16 autocast, BatchNorm statistics frozen, one epoch (110,608 steps), on one 24 GB GPU.
  • Stage 2 (v3): from v1, one epoch over additional speech mixed with part of the stage-1 data, peak LR 3e-5, 79,323 steps. Clips were cut in the pauses between sentences; clips with CER above 30% against v1's output, or whose first or last words v1 does not hear, were left out.

Limitations

  • Bokmål only; Nynorsk and dialect-heavy speech are not specifically trained.
  • Numbers: v1 writes numbers out as words (its training data was digit-free); v3 also uses digits.
  • Conversational and noisy audio is harder; test on your own audio.

License and attribution

CC-BY-4.0, as its base models. Built on NVIDIA's parakeet-tdt-0.6b-v3 (CC-BY-4.0) and Moondream's parakeet-ultra (CC-BY-4.0). Training data from the National Library of Norway (Nasjonalbiblioteket).

Downloads last month
81
Safetensors
Model size
0.6B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for ahdrage/norsk-parakeet

Finetuned
(22)
this model