Paradee-8M v1.1

Paradee is a small English text-to-speech model. It has 7.88M parameters and is distilled from Kokoro-82M, and it speaks one voice, Kokoro's af_heart.

  • Small. The int8 model is one 8.5 MB ONNX file, against 325 MB for Kokoro.
  • Fast. It runs about 62x faster than real time on one CPU thread, with no GPU. One second of speech takes about 16 ms to make.
  • Close to its teacher. It scores 4.39 on UTMOS (Kokoro 4.52) and its word error rate is 5.9% (Kokoro 5.7%).
  • Drop-in. The ONNX inputs and output are the same as v1.0.

The code, the training scripts and the Python package are at github.com/sahilmahendrakar/paradee. The paper, Paradee: Distilling Kokoro-82M into an 8M-Parameter Single-Voice Text-to-Speech Model, describes v1.0.

What changed since v1.0

The text side is the same file as in Paradee-8M v1.0, and so is the first part of the decoder. What changed is the last part of the decoder, the bit that actually writes out the audio samples.

v1.0 used Kokoro's own audio generator at a smaller width. It starts at 80 frames a second and upsamples, step by step, to 24,000 samples a second. Those later steps run on a lot of samples, which makes them slow. Its output also had a slight buzz on voiced sounds (vowels and other sounds where the vocal cords vibrate), so v1.0 added a filter afterwards to fix the phase of that sound. Phase is the timing of each frequency's wave, and when the timing between them drifts the voice sounds buzzy.

v1.1 replaces both the generator and the filter with a new head that does all its work at 80 frames a second and never upsamples.

  • Voiced sound. The head starts from clean sine waves at the pitch and at its whole-number multiples, which is what a voiced sound is made of. It learns a gain for each frequency band, smooth across frequency, and a small timing correction. The sine waves are lined up with the pitch from the start, so the phase filter is no longer needed.
  • Everything else. Breath, hiss and consonants come from real random noise that the head shapes. Part of that noise pulses in time with the pitch, as breathy voiced sound does, and a second noise path works in 3 ms steps so that sharp consonants and word starts are not smeared.

The result is more than 3x faster than v1.0, with the same word error rate and less buzz. UTMOS (see Results) does not pick up the buzz. One measure that does is how much energy sits on the multiples of the pitch compared with halfway between them, between 2 and 4 kHz. Higher means cleaner voiced sound. Kokoro measures 3.1 dB, v1.0 measures 1.3 dB and v1.1 measures 3.9 dB, on the same 200 held-out sentences in PyTorch.

Samples

Five held-out sentences, read by Paradee v1.1, by v1.0 and by their teacher. The sentences are in samples/sentences.txt.

# Paradee v1.1 Paradee v1.0 Kokoro-82M (teacher)
1 listen listen listen
2 listen listen listen
3 listen listen listen
4 listen listen listen
5 listen listen listen

Usage

pip install git+https://github.com/sahilmahendrakar/paradee
python -m paradee "Paradee is a small voice that runs anywhere." -o hello.wav
from paradee import Paradee, SAMPLE_RATE
import soundfile as sf

tts = Paradee()
sf.write("hello.wav", tts("Paradee is a small voice that runs anywhere."), SAMPLE_RATE)

Files

File What it is
onnx/paradee_int8.onnx The whole model in one graph, weights in int8 (8.5 MB). Use this one.
onnx/paradee.onnx The same graph in fp32 (35 MB). It sounds the same.
config.json Kokoro's phoneme vocabulary and the sample rate
tokenizer.json The same vocabulary in the format transformers.js and kokoro-js load
pytorch/text_side.pt, pytorch/decoder.pt PyTorch weights for the two halves, for the training code on GitHub. The text side is the same file as v1.0.
samples/ The audio above
assets/quality_vs_speed.png, assets/wer_vs_speed.png The charts in Results

The ONNX graph goes from phoneme ids to audio.

  • Inputs. input_ids is int64 [1, T], phoneme ids from config.json with a 0 pad token at each end, at most 512 in total. speed is float32 [1], where 1.0 is normal speed.
  • Output. waveform is float32 [1, samples] at 24 kHz.

The graph draws its own random noise, so two runs on the same text differ slightly in the noisy parts of the sound.

Phonemes must be written the way misaki, Kokoro's own grapheme-to-phoneme library, writes them, because that is all Paradee saw in training. In the browser, kokoro-js phonemizes with eSpeak NG instead. There, web/misaki.js converts eSpeak's spelling to misaki's. Without it, Whisper mishears about 31% of words, and with it about 2%.

Results

All numbers are on the same 200 held-out sentences, scored the same way. Speed is how many times faster than real time the model runs, on one CPU thread of an Apple M4 Pro.

UTMOS against speed for Paradee v1.1, v1.0 and other small models

English word error rate against speed for Paradee v1.1, v1.0 and other small models

Model (voice) Params File size Speed UTMOS WER
Paradee v1.1 (af_heart), int8 ONNX 7.88M 8.46 MB 62.1x 4.39 5.9%
Paradee v1.0 (af_heart), int8 ONNX 8.07M 9.04 MB 18.5x 4.41 5.9%
Paradee v1.0 (af_heart), PyTorch, from the paper 8.07M 8.45 MB 25.0x 4.41 5.7%
Kokoro-82M, teacher (af_heart) 81.8M 325 MB 7.6x 4.52 5.7%
Kokoro-7M-Distill (af_msa) 7.48M 30.1 MB 35.5x 4.18 7.4%
Piper, en_US-lessac-medium 15.7M 63.2 MB 15.4x 4.36 8.8%
KittenTTS nano 0.8 (Bella) 14.0M 56.8 MB 10.7x 4.01 5.5%

The first two rows are the released ONNX files, run through the same script in onnxruntime. They compare directly with each other. The other rows are copied unchanged from the v1.0 card and the paper, where speed was measured earlier in a different setup (PyTorch for Paradee and Kokoro, each model's own runtime for the rest, and Piper and KittenTTS timed from text rather than phonemes). So their speeds are not directly comparable with the first two rows. The two v1.0 rows show how much the setup alone moves the number. File size is the model as distributed (Paradee int8, the others fp32).

UTMOS is a neural network trained on human ratings. It predicts how natural a clip sounds, on a scale from 1 to 5. WER is the share of words that Whisper (base) transcribes wrongly. Each model speaks its own voice, so UTMOS compares naturalness, not closeness to af_heart.

The Open TTS Leaderboard results on the v1.0 card are for v1.0.

How it was made

Paradee has a 4.23M text side and a 3.65M decoder. The two halves were trained separately against the frozen teacher, on 12,000 WikiText-103 sentences (23.9 hours) read by Kokoro.

  1. The text side learns to predict the teacher's phoneme durations, pitch, loudness and feature encodings from the phonemes. It is Kokoro's own code at smaller widths, unchanged from v1.0.
  2. The decoder learns to turn the teacher's durations, pitch, loudness and feature encodings into the teacher's audio, first with spectrogram losses and then with adversarial training. Its first part is Kokoro's code at smaller widths, taken from v1.0, and its last part is the new head. Two extra losses match how tonal and how pulsing the teacher's upper frequencies are.
  3. The halves are joined with no further training.

All training ran on one MacBook Pro.

Limitations

  • English only, with American pronunciation, and one voice.
  • Numbers, abbreviations and unusual words are pronounced only as well as misaki handles them.
  • Consonants and the starts of words match the teacher slightly less closely than in v1.0.

License

Apache 2.0, the same as Kokoro-82M.

Citation

The paper describes v1.0.

@misc{mahendrakar2026paradee,
  title  = {Paradee: Distilling Kokoro-82M into an 8M-Parameter Single-Voice Text-to-Speech Model},
  author = {Mahendrakar, Sahil},
  year   = {2026},
  url    = {https://huggingface.co/sahilmahendrakar/Paradee-8M-v1.0}
}
Downloads last month
10
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for suryatmodulus/Paradee-8M-v1.1

Quantized
(98)
this model

Paper for suryatmodulus/Paradee-8M-v1.1