Kokoro 82M for Core ML
Kokoro-82M v1.0 by hexgrad, converted to seven Core ML models that run mostly on the Apple Neural Engine (iOS 17+, macOS 14+). Made for the Listen al-Gaib app, which reads books aloud on the phone; published so the files can be fetched and checked by anyone.
Credits
- Weights: hexgrad/Kokoro-82M, Apache 2.0. All the model's quality is theirs.
- Conversion: the seven-stage Core ML split (ALBERT, duration, alignment, prosody, noise,
vocoder, tail) and the vocoder's dual-output Neural Engine trick are
laishere/kokoro-coreml (
convert.pyat commit484907db6a8347a6afb6e7b86850ea2878c6a3fb, Apache 2.0). This repository is not affiliated with or endorsed by hexgrad or laishere.
What changed
The files are the output of laishere's converter, with two changes to the script: its Core ML
self-tests and end-to-end check ran on the CPU and the Neural Engine only (the GPU path crashes on
macOS 27), and the output directory is a parameter. The weights of five models are palettized to
8 bits (k-means), so they differ slightly from the original float32 weights; the converter is
not deterministic, so a new run will not reproduce these exact bytes. The models were then
compiled with xcrun coremlcompiler. The script is in the app's repository under
scripts/coreml/.
Files
coreml/Kokoro{Albert,PostAlbert,Alignment,Prosody,Noise,Vocoder,Tail}.mlmodelc, 82 MB in all.
Inputs are flexible: up to 512 token ids (with the leading and trailing 0) and 2000 frames (about 50
seconds of audio), 24 kHz output. Voices are not included: use the 510 x 256 float32 style tables
from the ONNX export (voices/*.bin, onnx-community/Kokoro-82M-v1.0-ONNX); the row for a
sentence is the one indexed by its token count. Text must be turned into Kokoro's phoneme ids
first (misaki, or any equivalent G2P).
Chain: ALBERT -> PostAlbert (durations; the speed input is applied here) -> Alignment -> Prosody
-> Noise -> Vocoder -> Tail. Load ALBERT, PostAlbert, Alignment, Prosody and Vocoder with
.cpuAndNeuralEngine; Noise and Tail (float32: they accumulate phase and run the iSTFT) with
.cpuOnly. Do not load them with .all or the GPU. The Vocoder's anchor output is unused and must
stay in the graph.
Measured
Same phonemes, Whisper base.en, 16 sentences x 4 voices plus 1.4x, on an Apple M4: word error rate 7.0% (PyTorch float32 7.3%, the int8 ONNX export 7.5%); audio length within 1-2% of float32; pitch a median 10 cents from float32. Speed: 22x real time on the M4; 13-14x on an iPhone 13 (iOS 27.2), whose first load after an install compiles for the Neural Engine for about 13 s. These are one person's measurements, not a benchmark suite.
License
Apache License 2.0 (see LICENSE), the same as Kokoro-82M and the conversion code it comes from.