swedish-kokoro — Kokoro-82M fine-tuned to also speak Swedish

A fine-tune of Kokoro-82M (StyleTTS2, 82 M params) that adds a Swedish voice while keeping Kokoro's native languages. Kokoro's KModel is language-blind (it maps IPA → audio), so the same weights serve every language; the language lives in the G2P front-end you feed it.

  • Swedish: a female voice (sv_female) trained via TTS distillation.
  • Other languages (English, Spanish, French, Italian, Portuguese, Hindi, Mandarin, Japanese): inherited from the base model — only lightly perturbed by the short Swedish fine-tune (English verified near-identical to base).

Files

file what
kokoro_sv.pth PyTorch weights (5 inference modules), best checkpoint (pre-adversarial)
kokoro_sv.onnx ONNX export (fp32) for torch-free / CPU / edge inference
sv_female.pt Swedish voicepack [510, 1, 256]
config.json Kokoro config (178-token IPA vocab)
g2p/g2p_model.pt neural Swedish G2P model (NST-trained; better loanword/name pronunciation than espeak)
g2p/lexicon.tsv NST pronunciation lexicon for the neural G2P

Usage

PyTorch (best on NVIDIA GPU / Apple Silicon) — via the kokoro_svml.py wrapper from the project repo:

from kokoro_svml import KokoroSVML
tts = KokoroSVML()                                   # auto-downloads these weights
sv = tts.generate("Hej, jag pratar svenska!", lang="sv")
en = tts.generate("And English, from the same model.", lang="en")
import soundfile as sf; sf.write("sv.wav", sv, 24000)

ONNX (torch-free, CPU/edge) — onnxruntime + numpy only:

import json, numpy as np, onnxruntime as ort
from huggingface_hub import hf_hub_download
from misaki import espeak  # Swedish G2P (espeak 'sv')

sess  = ort.InferenceSession(hf_hub_download("Joakim/swedish-kokoro", "kokoro_sv.onnx"))
voice = ...  # load sv_female.pt -> [510,1,256] numpy
vocab = json.load(open(hf_hub_download("Joakim/swedish-kokoro", "config.json")))["vocab"]
ipa, _ = espeak.EspeakG2P(language="sv")("Hej världen!")
ids = [vocab[p] for p in ipa if p in vocab]
audio, pred_dur = sess.run(None, {"input_ids": np.array([[0,*ids,0]], np.int64),
                                  "ref_s": voice[len(ids)-1]})

Output is 24 kHz mono. Trim the EOS tail using pred_dur (see the repo's trim_eos_tail). For Swedish, set SV_NEURAL_G2P=nst_g2p for the higher-quality neural G2P (else espeak sv).

How it was made

  • Data: Swedish couldn't be sourced cleanly from LibriVox (the one usable female reader is ~1.7 h of skÃ¥nska), so the training set was synthesized with Chatterbox Multilingual (language_id="sv") cloning one clean reference clip — ~3.8 h of consistent single-speaker Swedish (TTS distillation).
  • Training: warm-started from base Kokoro; StyleTTS2 two-stage fine-tune on a 700-clip subset (RTX 3090, fp32, batch 4).
  • Checkpoint choice: the Stage-2 adversarial/SLM epoch injects a 25 ms comb/echo (degenerate on little data), so the shipped weights are the pre-adversarial checkpoint — the cleanest of the run.

Limitations

  • Swedish quality is TTS-distilled (Chatterbox-grade timbre), not human-grade, and carries a faint residual decoder comb (~12.5 ms). Good for use, not native.
  • The sj-ljud /ɧ/ is approximated as retroflex /Ê‚/.
  • Text normalization (numbers, Roman numerals — e.g. "Vi" → "VI" = 6) is the caller's responsibility; the bundled G2P doesn't normalize.
  • ONNX int8 is not provided — dynamic int8 slowed this conv-heavy vocoder down; use the fp32 ONNX (≈7× realtime on CPU) or PyTorch on GPU (≈60× realtime).

License

Apache-2.0, inheriting Kokoro-82M. The Swedish reference voice derives from a public-domain LibriVox recording.

Downloads last month
136
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Joakim/swedish-kokoro

Quantized
(50)
this model