norsk-asr
A fast Norwegian (Bokmål) speech recognizer trained only on open data. It is a CTC model on top of the audio encoder of google/embeddinggemma-2, following the recipe of QUAN-Transcribe-1.0, with an optional word 4-gram KenLM language model for beam search.
Code, training recipe and full experiment log: github.com/ahdrage/norsk-asr.
This is an early research model. It is much faster than Whisper-style models but less accurate on general speech; see the results and limitations below.
Usage
git clone https://github.com/ahdrage/norsk-asr.git && cd norsk-asr
uv sync --extra lm # KenLM bindings need a C++ compiler
uv run --extra lm python -m norsk_asr.download # this repo's model + LM (~850 MB)
uv run --extra lm python -m norsk_asr.transcribe opptak.mp3 --timestamps
Any audio length and format (via ffmpeg). Output is raw text: lowercase, no punctuation, numbers written as words. The first run also downloads the EmbeddingGemma 2 encoder (1.5 GB).
Model
audio (16 kHz) → log-mel → EmbeddingGemma 2 audio encoder (12 conformer layers, 305M params;
layers 1–11 frozen, layer 12 fine-tuned) → learned softmax mix of all 13 hidden states →
6-layer conformer reader (d=768, 83M params) → CTC over 83 character units
The checkpoint (model.safetensors) holds only the trained weights: the reader, layer mix,
output head and encoder layer 12. The frozen encoder layers are loaded from
google/embeddinggemma-2. config.json holds the model config and the unit inventory.
Files
| Path | What |
|---|---|
runs/full_top1/ |
the main model: 1,680 h, 5 epochs, top encoder layer trained |
runs/pilot_top1/, runs/pilot_frozen/ |
465 h pilots (top layer trained / encoder frozen) |
lm/no4.bin, lm/no4.unigrams.txt |
word 4-gram KenLM (trie, quantized) and its vocabulary — CC BY-SA 4.0 |
lm/*.log |
LM build log and decoding-weight tuning grids |
results/<model>/ |
per-utterance references and hypotheses on the test subsets, and summary.json |
Results
WER (%) on digit-free utterances, on the same 1,000-utterance subsets for every model (FLEURS 357, Stortinget 697 utterances). Beam search: width 64, LM weight α=0.6, word bonus β=1.0, tuned on dev sets (FLEURS dev, NPSC eval split), never on these test sets.
| Model | Training data | FLEURS | NPSC | NST | Stortinget | Speed |
|---|---|---|---|---|---|---|
| NB-Whisper large | ~66k h | 4.2 | 16.5 | 2.0 | 9.0 | 40–90× real time (H100) |
full_top1, greedy |
1,680 h | 15.2 | 12.9 | 8.9 | 15.3 | 1,000–1,600× (H100) |
full_top1 + 4-gram LM |
1,680 h | 10.0 | 9.7 | 5.6 | 12.2 | + beam search ~1,500× on 8 CPU cores |
How to read these:
- NPSC is a style win, not an accuracy win. NB-Whisper writes clean text and drops verbatim fillers ("og", "så", "jo") that NPSC's references keep; most of its NPSC errors are deletions. Counting misheard words only, the two models are about equal on NPSC, and NB-Whisper is 1.5–2.5× better on the other three sets.
- Digit-containing references are excluded because the spoken form of a number is ambiguous ("2019": "tjue nitten" or "to tusen og nitten").
- FLEURS has few utterances (~274 digit-free), so differences of ±1–1.5 points are noise.
- NST's read prompts repeat across speakers; some test sentences occur in training, read by other people.
Training data
| Data | Hours used | License |
|---|---|---|
| NbAiLab/nb_distil_speech_noconcat_stortinget (all 636 train shards) | 1,337 | CC0 1.0 |
| NbAiLab/nb_distil_speech_noconcat_nst (NST, Språkbanken) | 256 | NST: CC0 1.0 |
| NbAiLab/NPSC train, Bokmål | 87 | CC0 1.0 |
Utterances with digits in the transcript (75,706) or with high disagreement between the
transcript and Whisper (whisper_wer > 0.15; 15,895) were dropped, leaving 1,679.9 h. No test
session appears in training (checked by exact sentence overlap).
The language model was trained on 8.6 M sentences: NbAiLab/NCC shards 1–4 (Bokmål parliament proceedings, government and public reports, Målfrid web text and Norwegian Wikipedia, published 1990 or later; number-heavy sentences dropped) plus the training transcripts above. Every sentence sharing an 8-gram with a test or dev reference was removed.
Limitations
- Raw output only: no casing, punctuation or digits.
- Tested on parliament speech, read sentences and read Wikipedia text. Not evaluated on broadcast, podcasts, conversation, telephone audio, strong dialects or noisy audio.
- Trained on clips of 30 s or less; long audio is split at quiet points into pieces ≤ 25 s.
- Bokmål only; Nynorsk speech is transcribed into Bokmål-like spelling at best.
- Quiet off-microphone speech (for example a chairperson's aside) is sometimes dropped.
License and attribution
- Model weights (
runs/): Apache-2.0. Derived from google/embeddinggemma-2 (Apache-2.0). - Language model (
lm/): CC BY-SA 4.0, because its training text includes Norwegian Wikipedia (CC BY-SA 3.0). It also contains text from the Norwegian Colossal Corpus under NLOD 2.0 (parliament, government and public reports, Målfrid), published by the National Library of Norway. - Results (
results/): the references come from FLEURS (CC BY 4.0, Google), NPSC (CC0), and the NbAiLab Stortinget and NST sets (CC0). - Code: Apache-2.0, at github.com/ahdrage/norsk-asr.
Model tree for ahdrage/norsk-asr
Base model
google/embeddinggemma-2Datasets used to train ahdrage/norsk-asr
NbAiLab/NCC
NbAiLab/nb_distil_speech_noconcat_stortinget
Evaluation results
- wer on FLEURS nb_no (test, digit-free)test set self-reported10.000
- wer on NPSC Bokmål (test, 1,000-utterance subset)test set self-reported9.700
- wer on NST (validation, 1,000-utterance subset)validation set self-reported5.600
- wer on Stortinget (validation clean, digit-free)self-reported12.200