Skip to content

Add NB-Whisper (Norwegian Whisper fine-tunes) as whisper variants #152

Description

@niklasfjeldberg

Request

Add NB-Whisper, the Norwegian Whisper fine-tunes from the National Library of Norway, as whisper variants.

  • Upstream repos: NbAiLab/nb-whisper-{tiny,base,small,medium,large} (Apache-2.0)
  • Family key: whisper (existing)
  • Variant names: nb-whisper-tinynb-whisper-large
  • Architecture pattern: encoder-decoder, unchanged from stock Whisper

This comes from a discussion on Handy, where @cjpais asked for the models to be quantized through transcribe.cpp and tracked here.

Upfront

I don't understand all of the technical detail here, and I used AI (Claude Code) for the conversion work and the measurements below. I did run the models myself, on my own machine, and the improvement is real for me and not only in the numbers. I wanted to be honest about that split rather than present this as more than it is.

My testing

I dropped the Norwegian model into Handy as a custom model and used it for normal dictation. It is a clear improvement.

The biggest single thing: Handy used to often detect my Norwegian as Danish or Swedish and transcribe the whole thing in the wrong language. That stopped. Compound words hold together better, and I am correcting the output far less than before. Before this I was running a much larger model and still fixing text afterwards.

Conversion results

Four of five sizes converted and quantized through scripts/convert-whisper.py + transcribe-quantize.

WER on 8 clips from the Fleurs nb_no test split (the benchmark NB-Whisper's own paper uses), 175 reference words, greedy decoding, -l no, CPU backend. This is a small sample, so treat it as a check that the conversion is faithful rather than a real benchmark:

Model (Q5_K_M) Download Measured WER Paper
NB-Whisper Tiny 44 MB 12.57% 15.2%
NB-Whisper Base 64 MB 9.14% 11.5%
NB-Whisper Small 194 MB 8.00% 8.3%
NB-Whisper Medium 583 MB 7.43% 7.2%
Stock Whisper Large v3 1.16 GB 11.43% 10.4%
Stock Whisper Small 194 MB 30.29% 29.6%

Per-quant for small: F32 8.00, F16 8.00, Q8_0 8.00, Q6_K 7.43, Q4_K_M 7.43. No quant level degrades.

Other checks:

  • ctest -R whisper green with TRANSCRIBE_WHISPER_GGUF pointed at the converted model.
  • GGUF metadata correct: general.name "NB-Whisper Small", author/organization NbAiLab, pinned general.repo_url, license apache-2.0.
  • All five small quant file sizes come out byte-identical to the shipped stock whisper-small entries, as expected for identical architecture.

Pinned revisions: tiny 8b38492d, base 2ab372b6, small e9bb5cb8, medium 0ed074d5, large 8c6249fd. SHA-256s for the 24 produced files available if useful, though they are reproducible from the commands above.

Patch needed

convert-whisper.py rejects unknown slugs via VARIANT_DISPLAY_NAMES. Five lines, following the existing breeze-asr-25 precedent for a community fine-tune. grep -rn breeze over the repo returns only that one line, so nothing else needs registering:

     "breeze-asr-25":          "Breeze-ASR-25",
+    "nb-whisper-tiny":        "NB-Whisper Tiny",
+    "nb-whisper-base":        "NB-Whisper Base",
+    "nb-whisper-small":       "NB-Whisper Small",
+    "nb-whisper-medium":      "NB-Whisper Medium",
+    "nb-whisper-large":       "NB-Whisper Large",

Happy to open this as a PR if you want it that way.

nb-whisper-large is blocked on sharded safetensors

NbAiLab/nb-whisper-large ships model-00001-of-00002.safetensors (4.99 GB) + model-00002-of-00002.safetensors (1.18 GB) + model.safetensors.index.json, with no single model.safetensors. convert-whisper.py hardcodes model_dir / "model.safetensors" (line 486) and fails the existence check, so large cannot be converted as-is.

The pattern that would fix it already exists in this repo: convert-voxtral.py (~line 84) reads the index's weight_map when present and falls back to the single file otherwise. convert-granite, convert-medasr, convert-moss and convert-qwen3_asr do the same. I have not attempted that change, since it is converter code rather than a table entry and seems like your call.

Minor observations

  • general.languages carries all 99 Whisper languages, inherited from the tokenizer, though these are Norwegian models. The HF card metadata says no/nb/nn/en, which is probably what a catalog entry should use.
  • scripts/lib/hf_source.py::download_snapshot passes no allow_patterns, so it pulled 6.1 GB for nb-whisper-small (that repo ships safetensors + pytorch + TF + Flax + ct2/ + onnx/). Converting from a hand-picked 281 MB subset worked identically. Left out of the patch since it is shared by about a dozen converters.

What I can offer

I am happy to help maintain this where I realistically can, which is testing Norwegian and Nynorsk output and reporting problems. I am probably not the right person to fix converter internals, so I would rather say that now than promise more than I can deliver.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions