Leokani G2P
English text to Kokoro-style phonemes, without espeak-ng.
Leokani G2P is a small, fast English phonemizer from Milliwatt Labs. It produces espeak compatible phoneme codes, made from the ground up: the same Kokoro/misaki-style codes Leokani-tts and Kokoro use. It contains no espeak-ng code or data files.
It needs only numpy and onnxruntime and about 19 MB of files, and takes under a millisecond per line on one CPU
thread. The weights, lexicon and goldens are CC BY 4.0 and the code is MIT, so you can use it in commercial
products with attribution.
It is the text front end of Leokani-tts 7M, which bundles it: try Leokani-tts in your browser.
Two sizes
| variant | letter-to-sound params | files | |
|---|---|---|---|
micro (default) |
2.22M | 19.0 MB | the same size as v1.0 |
mini |
2.94M | 21.8 MB | better on names and rare words |
Usage
As a pip package, with a command-line tool (source: github.com/Milliwatt-Labs/leokani-g2p):
pip install "leokani-g2p @ git+https://github.com/Milliwatt-Labs/leokani-g2p"
leokani-g2p "Dr. Okafor lands at 7:45 AM."
# dˈɑktəɹ ˈɑkæfəɹ lˈændz æt sˈɛvən fˈɔɹɾi fˈIv ˌAˈɛm.
import leokani_g2p
leokani_g2p.phonemize("The wind was cold, so we read inside.")
# 'ðə wˈɪnd wʌz kˈOld, sˌO wi ɹˈid ɪnsˈId.'
leokani_g2p.phonemize_chunks("A long paragraph. Of several clauses.") # one string per clause chunk
mini = leokani_g2p.load(variant="mini") # the larger model
Or straight from this repo, one file and its model files:
hf download milliwattlabs/leokani-g2p --local-dir leokani-g2p
pip install numpy onnxruntime
python leokani-g2p/leokani_g2p.py --text "Hello there. How was your day?"
python leokani-g2p/leokani_g2p.py --variant mini --text "Siobhan met Thibault." # files in mini/
Numbers, money, dates, times, units, phone numbers, emails, web addresses and versions are written out as words
first ("$4.99" is read as "4 dollars and 99 cents").
With Kokoro
The output uses Kokoro's phoneme codes, so a Kokoro voice can read it in place of its own text front end:
import numpy as np, soundfile as sf
from kokoro import KPipeline
import leokani_g2p
pipeline = KPipeline(lang_code="a", repo_id="hexgrad/Kokoro-82M")
audio = [r.audio.numpy()
for ps in leokani_g2p.phonemize_chunks("Dr. Okafor lands at 7:45 AM.")
for r in pipeline.generate_from_tokens(ps, voice="af_heart")]
sf.write("kokoro.wav", np.concatenate(audio), 24000)
With Leokani-tts
hf download milliwattlabs/leokani-tts-7M --local-dir leokani-tts
cd leokani-tts
pip install numpy onnxruntime
python leokani_onnx.py "Hello there. How was your day?" --g2p leokani -o hello.wav
Accuracy
How often Leokani G2P reads test text held out from building the model the same as the reference (American English, Kokoro's codes). Sentence references are espeak-ng's output (commit 8269af04, through misaki 0.9.4's mapping); the letters and same-spelling rows use our own reference readings. Those last three tests are new in 1.2.
| test | v1.0 | 1.2 micro (default) | 1.2 mini |
|---|---|---|---|
| held-out sentences, five test sets (1,940), apart from text read differently on purpose | 99.28 % | 99.33 % | 99.33 % |
| sentences built around unseen names (577) | 83.36 % | 91.33 % | 93.07 % |
| more sentences with unseen names (600) | 70.5 % | 85.0 % | 87.5 % |
| unseen rare words | 72.1 % | 80.1 % | 81.1 % |
| numbers, units, web addresses, abbreviations (165) | — | 78.2 % | 78.2 % |
| spelled-out letters and initialisms (148) | — | 88.5 % | 88.5 % |
| words spelled the same but said differently (213) | — | 87.3 % | 87.3 % |
Rare words that aren't in the lexicon are the weak spot, which is why names score lower. Mini is the better choice for text full of names; on everyday sentences the two give the same output.
Files
| file | params | size | |
|---|---|---|---|
leokani_g2p.py |
the runtime (MIT) | ||
context.onnx |
1.34M | 5.4 MB | how each word is said in its clause |
oov-encoder.onnx, oov-decoder.onnx |
2.22M | 9.0 MB | letter-to-sound for words outside the lexicon |
leokani-g2p.json.gz |
4.7 MB | lexicon, weak forms, number words | |
goldens.json |
outputs a port must reproduce exactly | ||
mini/ |
2.94M | 21.8 MB | the mini variant: the same four model files and its own goldens.json |
Speed, one CPU thread, per-word cache warm (Apple M3 Pro): 0.26 ms per line on everyday sentences, about 0.6 ms on text full of numbers, units and abbreviations.
Limitations
- American English only.
- Output is Kokoro/misaki-style phonemes, not espeak-ng's own IPA, and there is no audio: it is the text front end only.
- Unusual names and rare words outside the lexicon can be misread (see Accuracy).
- Some text is read on purpose differently from espeak-ng: amounts, units, emails and versions are said as words, and the pronoun "I" is always stressed.
- Heteronyms ("read", "lead", "wind", "lives") are picked from nearby words, and the guess can be wrong.
License
- Model weights (
*.onnx), the lexicon (leokani-g2p.json.gz) andgoldens.json: CC BY 4.0 (LICENSE-CC-BY-4.0.txt). - Code (
leokani_g2p.py): MIT (LICENSE).
Credit it as: Leokani G2P by Milliwatt Labs (milliwattlabs.com). The lexicon's word list includes words
from the CMU Pronouncing Dictionary (BSD-2-Clause) and place names from
GeoNames (CC BY 4.0). The phoneme codes are those of
misaki and Kokoro-82M by
hexgrad (Apache-2.0). See NOTICE for every credit.