Instructions to use kasper-cbx/svale-600M-hf with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use kasper-cbx/svale-600M-hf with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("automatic-speech-recognition", model="kasper-cbx/svale-600M-hf")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("kasper-cbx/svale-600M-hf", device_map="auto") - Notebooks
- Google Colab
- Kaggle
svale-600M-hf
3dio-ai/svale-600M converted from its NeMo
archive to transformers format (ParakeetForTDT). Weights are unchanged — this is a
format conversion only, produced with the conversion script that ships with
transformers:
python src/transformers/models/parakeet/convert_nemo_to_hf.py \
--hf_repo_id 3dio-ai/svale-600M --model_type tdt --output_dir .
Requirements
pip install "transformers>=5.12" librosa torch
Both are load-bearing, and neither failure is obvious from the traceback:
transformers>=5.12is the floor for theparakeet_tdtarchitecture. Older versions raiseValueError: The checkpoint you are trying to load has model type parakeet_tdt but Transformers does not recognize this architecture.librosais imported by the feature extractor, not bytransformersitself, so a plaintransformers+torchenvironment fails at load withImportError: ParakeetFeatureExtractor requires the librosa library.
Use
import numpy as np
import torch
from transformers import pipeline
asr = pipeline(
"automatic-speech-recognition",
model="kasper-cbx/svale-600M-hf",
dtype=torch.bfloat16, # fp32 weights; bf16 is what the conversion was checked in
device="cuda",
)
# 16 kHz mono float32, one clip per call — see the batching note below.
asr({"raw": audio, "sampling_rate": 16000})
Output is lowercase and unpunctuated, like the original. Danish only — it takes no
language or task argument, and passing Whisper-style generate_kwargs will fail.
Decode one clip at a time
batch_size > 1corrupts output. Batched, the TDT decoder keeps emitting into the padding that makes a batch rectangular, so short clips come back with their tails repeated —"kø kø"decodes as"kø kø kø kø kø kø kø kø". Longer clips in the same batch pick up a few spurious trailing words.On a 45-utterance fixture, batched decoding reproduced the NeMo original on 23/45 utterances; one at a time reproduced 42/45. Every number on this card was measured one at a time, for both checkpoints.
This is a property of the batched TDT decoding path, not of these weights: the same
happens with the base model, and adding the eos_token_id below does not change it
(EOS is not what stops a frame-synchronous decoder).
Expected warnings
Using the model-agnostic default max_length (=NNN)— once per call, harmless. The value is derived from encoder length and tracks clip length (observed 50→3490); a fixedmax_new_tokensis what would truncate a long clip. That it does not truncate is measured — see the parity table.
Parity with the original
Both checkpoints were run over the full CoRal-v3 conversation test split (8,438
utterances, 8h 01m of audio) on one L4, decoding one clip at a time in both cases.
Scoring uses the Danish ASR leaderboard's
own normaliser and corpus-WER metric, so these numbers sit on the same scale as its
published ones.
| WER | CER | Throughput | |
|---|---|---|---|
3dio-ai/svale-600M (NeMo) |
21.59 | 12.55 | 66.2x realtime |
kasper-cbx/svale-600M-hf (this repo) |
21.54 | 12.50 | 49.1x realtime |
- WER delta −0.05 pp, paired bootstrap 95% CI [−0.14, +0.03] pp — the interval includes zero, so the two are statistically indistinguishable on this set.
- 87.3% of hypotheses (7,364 / 8,438) are byte-identical; the rest differ by a word or two, in both directions.
- The NeMo run reproduces the leaderboard's published 21.52 to within 0.07 pp, which is the check that the harness here is measuring the same thing it does.
Accuracy is on parity. Throughput is not: unbatched, this conversion runs at about 0.74x the original's rate, the difference being per-call Python overhead rather than anything about the weights.
Differences from a plain conversion run
generation_config.json carries "eos_token_id": 3, which the conversion script does
not emit but nvidia/parakeet-tdt-0.6b-v3
(the base this was fine-tuned from) does. The two tokenizers are byte-identical and id 3
is <|endoftext|> in both, so the value is the base model's, not an invention here. It
was added for fidelity with the base config; decoding is unchanged by it, verified at
batch_size 1 and 4.
Nothing else differs from what the script produces, and the weights are untouched.
Why convert at all
The original ships only as svale-600M.nemo, so using it requires nemo_toolkit. In a
Hugging Face ZeroGPU Space that is a problem beyond dependency weight: NeMo resident in
the main process breaks the fork() ZeroGPU uses to start GPU workers, and every
request fails with "GPU task aborted" — including requests for unrelated models in the
same app. Converting removes NeMo from the runtime entirely.
Licence
Inherits the NVIDIA Open Model License from the base model, and the CoRal OpenRAIL-D use restrictions that come with its training data: no speech synthesis, no biometric identification.
- Downloads last month
- 24