Kokoro TTS
Kokoro-82M es un modelo de texto a voz ligero y no autorregresivo basado en StyleTTS 2 con un vocoder ISTFTNet. Se ejecuta íntegramente en el Neural Engine a través de CoreML, produciendo voz natural a 24 kHz a partir de una entrada de texto en una sola pasada forward.
Kokoro-82M está diseñado para su despliegue en el dispositivo en iOS. Con 82M parámetros (~80 MB con 1 bucket, INT8), cabe cómodamente en iPhone y iPad. CoreML se ejecuta en el Neural Engine, dejando la GPU libre para otras tareas.
Idiomas soportados
| Idioma | Código | Voces de ejemplo |
|---|---|---|
| Inglés (EE. UU.) | en | af_heart, am_adam, af_sky |
| Inglés (Reino Unido) | en | bf_emma, bm_george |
| Español | es | ef_dora |
| Francés | fr | ff_siwis |
| Hindi | hi | hf_alpha, hm_omega |
| Italiano | it | if_sara |
| Japonés | ja | jf_alpha, jm_omega |
| Portugués | pt | pf_dora |
| Chino | zh | zf_xiaobei, zm_yunjian |
| Coreano | ko | kf_somi |
50 voces predefinidas en total. Convención de nombres: [language_prefix][gender]_[name] — p. ej., af_heart = mujer estadounidense “Heart”, if_sara = mujer italiana “Sara”.
Referencia de códigos de voz
Cada ID de voz de Kokoro sigue el mismo patrón: un prefijo de idioma de una letra, un código de género de una letra, un guion bajo y luego el nombre de la voz. Use la tabla siguiente para asignar el idioma de destino al prefijo correcto.
Tabla de prefijos de idioma
| Prefijo | Idioma | Localización | Sufijos de género |
|---|---|---|---|
a | Inglés | Estadounidense (en-US) | af_, am_ |
b | Inglés | Británico (en-GB) | bf_, bm_ |
e | Español | (es) | ef_, em_ |
f | Francés | (fr-FR) | ff_ |
h | Hindi | (hi) | hf_, hm_ |
i | Italiano | (it) | if_, im_ |
j | Japonés | (ja) | jf_, jm_ |
k | Coreano | (ko) | kf_ |
p | Portugués | Brasileño (pt-BR) | pf_, pm_ |
z | Chino | Mandarín (zh) | zf_, zm_ |
Todas las voces por idioma
Inglés — Estadounidense (af_*, am_*)
Femenino: af_alloy, af_aoede, af_bella, af_heart (predeterminado), af_jessica, af_kore, af_nicole, af_nova, af_river, af_sarah, af_sky
Masculino: am_adam, am_echo, am_eric, am_fenrir, am_liam, am_michael, am_onyx, am_puck, am_santa
Inglés — Británico (bf_*, bm_*)
Femenino: bf_alice, bf_emma, bf_isabella, bf_lily
Masculino: bm_daniel, bm_fable, bm_george, bm_lewis
Español (ef_*, em_*)
Femenino: ef_dora
Masculino: em_alex, em_santa
Francés (ff_*)
Femenino: ff_siwis
Hindi (hf_*, hm_*)
Femenino: hf_alpha, hf_beta
Masculino: hm_omega, hm_psi
Italiano (if_*, im_*)
Femenino: if_sara
Masculino: im_nicola
Japonés (jf_*, jm_*)
Femenino: jf_alpha, jf_gongitsune, jf_nezumi, jf_tebukuro
Masculino: jm_kumo
Coreano (kf_*)
Femenino: kf_somi
Portugués — Brasileño (pf_*, pm_*)
Femenino: pf_dora
Masculino: pm_alex, pm_santa
Chino — Mandarín (zf_*, zm_*)
Femenino: zf_xiaobei, zf_xiaoni, zf_xiaoxiao, zf_xiaoyi
Masculino: zm_yunjian, zm_yunxi, zm_yunxia, zm_yunyang
Ejecute speech kokoro --list-voices para imprimir todas las voces incluidas actualmente en el modelo. Los ID de voz son estables entre versiones — utilice la cadena exacta (p. ej., if_sara) al invocar --voice desde la CLI o pasar voice: a la API de Swift.
Arquitectura
Kokoro utiliza un pipeline CoreML de 3 etapas. Sin bucle de sampling — todas las etapas son pasadas forward no autorregresivas con un paso de alineación en Swift entre las etapas 1 y 2.
Pipeline de 3 etapas
| Etapa | Modelo | Entrada | Salida |
|---|---|---|---|
| 1. Duración | duration.mlmodelc | Tokens de fonemas + embedding de voz + velocidad | Duraciones, características prosódicas, codificación de texto |
| — | Alineación en Swift | Duraciones + características de la etapa 1 | Características prosódicas y de texto alineadas |
| 2. Prosodia | prosody.mlmodelc | Características prosódicas alineadas + estilo | Predicciones de F0 (tono) + ruido |
| 3. Decodificador | decoder_*.mlmodelc | Texto alineado + F0 + ruido + estilo | Forma de onda de audio a 24 kHz |
Buckets de fonemas (modelo de duración)
El modelo de duración usa formas de entrada enumeradas. La entrada se rellena hasta el bucket más pequeño que quepa:
| Bucket | Máx. fonemas | Caso de uso |
|---|---|---|
| p16 | 16 | Frases cortas |
| p32 | 32 | Oraciones cortas |
| p64 | 64 | Oraciones medianas |
| p128 | 128 | Oraciones largas |
Buckets del decodificador
Modelos de decodificador con forma fija para diferentes longitudes máximas de audio (cada frame = 600 muestras a 24 kHz):
| Bucket | Máx. frames | Máx. audio |
|---|---|---|
decoder_5s | 200 | 5.0s |
decoder_10s | 400 | 10.0s |
decoder_15s | 600 | 15.0s |
Requiere iOS 18+ / macOS 15+.
Fonemizador
El texto se convierte en tokens de fonemas mediante un pipeline de tres niveles — todo con licencia Apache-2.0, sin dependencias GPL:
- Búsqueda en diccionario — Diccionarios de pronunciación de inglés americano y británico con soporte para heterónimos
- Stemming de sufijos — Descomposición morfológica para sufijos conocidos (p. ej., "-ing", "-tion")
- BART G2P — Fallback neuronal de grafema a fonema usando un modelo CoreML encoder-decoder separado para palabras fuera de vocabulario
Pesos del modelo
| Componente | Tamaño | Formato |
|---|---|---|
| Modelo de duración | ~39 MB | .mlmodelc |
| Modelo de prosodia | ~17 MB | .mlmodelc |
| Modelos de decodificador (3 buckets) | ~107 MB cada uno | .mlmodelc |
| Embeddings de voz (54 voces) | ~0.3 MB | JSON (Float32 de 256 dim) |
| Encoder + decoder G2P | ~1.5 MB | .mlmodelc |
| Diccionarios + vocab | ~6 MB | JSON |
| Total (1 decodificador) | ~170 MB |
Rendimiento
| Métrica | Valor |
|---|---|
| Parámetros | 82M |
| Backend de inferencia | CoreML (Neural Engine) |
| RTFx de inferencia | ~0.7 (más rápido que tiempo real) |
| Frecuencia de muestreo de salida | 24 kHz |
| Memoria de pesos | ~170 MB (1 bucket de decodificador) |
A diferencia de Qwen3-TTS y CosyVoice3 que generan tokens paso a paso, Kokoro usa un pipeline de 3 etapas sin bucle de sampling. Todas las etapas son pasadas forward deterministas.
Uso de la CLI
speech kokoro "Hello, world!" --voice af_heart --output hello.wav
Opciones
| Opción | Por defecto | Descripción |
|---|---|---|
<text> | Texto a sintetizar | |
--voice | af_heart | Nombre del preset de voz |
--language | en | Código de idioma: en, es, fr, hi, it, ja, pt, zh, ko, de |
--output, -o | kokoro_output.wav | Ruta del archivo WAV de salida |
--list-voices | Lista todas las voces disponibles y sale | |
--model, -m | ID del modelo en HuggingFace |
Ejemplos
# English with default voice
speech kokoro "Hello, how are you today?" --output hello.wav
# French
speech kokoro "Bonjour le monde" --voice ff_siwis --language fr --output bonjour.wav
# Japanese
speech kokoro "こんにちは世界" --voice jf_alpha --language ja --output konnichiwa.wav
# List all 50 voices
speech kokoro --list-voices
API de Swift
import KokoroTTS
import AudioCommon
let tts = try await KokoroTTSModel.fromPretrained()
// Downloads ~170 MB on first run
let audio = try tts.synthesize(text: "Hello world", voice: "af_heart")
// audio: [Float] — 24 kHz mono PCM
try WAVWriter.write(samples: audio, sampleRate: 24000, to: outputURL)
Compute Unit Override
fromPretrained(computeUnits:) selects which hardware runs the main CoreML model. The default (.all) lets Core ML prefer the Neural Engine, which is the fastest path on every supported device. Pass .cpuAndGPU to bypass the ANE as a fallback on platforms where the ANE compiler produces incorrect output for this model.
import CoreML
import KokoroTTS
// Default: ANE preferred
let tts = try await KokoroTTSModel.fromPretrained()
// Fallback: bypass the Neural Engine
let tts = try await KokoroTTSModel.fromPretrained(computeUnits: .cpuAndGPU)
Cuándo usar Kokoro
| Caso de uso | TTS recomendado |
|---|---|
| App iOS, ligera, eficiente en batería | Kokoro (CoreML, 82M params, ~170 MB) |
| Máxima calidad, streaming, clonación de voz | Qwen3-TTS (MLX, 600M params, ~1.7 GB) |
| Streaming multilingüe, 9 idiomas | CosyVoice3 (MLX, 500M params, ~1.2 GB) |
| Diálogo hablado full-duplex | PersonaPlex (MLX, 7B params, ~5.5 GB) |
Licencia
- Pesos del modelo: Apache-2.0 (hexgrad/Kokoro-82M)
- Conversión a CoreML: Apache-2.0 (aufklarer/Kokoro-82M-CoreML)
- Diccionarios y G2P: Apache-2.0