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.
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).
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.
| 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 |
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:
| 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.
runs/): Apache-2.0. Derived from
google/embeddinggemma-2 (Apache-2.0).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/): the references come from FLEURS (CC BY 4.0, Google), NPSC (CC0),
and the NbAiLab Stortinget and NST sets (CC0).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.
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).
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.
| 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 |
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:
| 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.
runs/): Apache-2.0. Derived from
google/embeddinggemma-2 (Apache-2.0).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/): the references come from FLEURS (CC BY 4.0, Google), NPSC (CC0),
and the NbAiLab Stortinget and NST sets (CC0).