Traducido del inglés. Ver original
Cómo funciona Kokoro-82M con Apple MLX en un iPhone
“En el dispositivo” no dice nada de dónde se ejecuta realmente un modelo. Aquí está todo el proceso dentro de una app: eSpeak NG en la CPU, una red de 82 millones de parámetros en la GPU de Apple silicon con MLX, audio a 24 kHz de salida, y lo único que cuesta esa decisión.
· Actualizado el · mazzzystar · 10 min de lectura
Kokoro-82M con Apple MLX en iPhone: así es como lo ejecuta Sandbook, y merece explicarse con detalle. Si lees suficientes fichas del App Store de apps de voz sin conexión, acabarás reuniendo tres explicaciones distintas de cómo se genera una voz neuronal en un teléfono: que está “optimizada para el Neural Engine de Apple”, que usa “una ruta optimizada de Core ML” o que funciona “en la CPU, sin GPU y sin llamadas a la nube”. A veces encontrarás dos de ellas describiendo la misma app.
No son sinónimos. Son tres piezas de silicio distintas con tres formas distintas de fallar, y cuál usa una app determina cosas que de verdad le importan a quien la compra: si sigue sonando al bloquear la pantalla, en qué teléfono de qué antigüedad se instala y cuánto se calienta el dispositivo. Así que aquí está el proceso completo de una app, etapa por etapa, sin redondear nada.
Respuesta corta
Sandbook ejecuta Kokoro-82M con Apple MLX en la GPU de Apple silicon, a través de Metal. No en el Neural Engine, no como un grafo de Core ML, no con ONNX en la CPU. El tratamiento del texto y la fonemización se hacen en la CPU; del codificador de texto en adelante, toda la red es trabajo de la GPU; la salida es audio mono a 24 kHz. Esa única decisión explica tanto lo que la app hace bien como lo más importante que no puede hacer.
Alcance y fuentes
Esto describe Sandbook, que es mi propia app, en su versión 1.0.2: las cifras salen de la versión publicada, no de una página de marketing. Lo que se dice de otras apps está citado de sus propias fichas del App Store, leídas el 14 de septiembre de 2026. Los datos del modelo salen de la ficha técnica publicada de Kokoro-82M, y los de MLX, de los propios repositorios de Apple; ambos enlazados al final.
Tres sitios donde ejecutar un modelo en un iPhone
Un chip de Apple silicon tiene tres unidades de cálculo a las que un desarrollador puede apuntar, y “en el dispositivo” no dice nada de cuál se está usando.
| Unidad | Se le da bien | La pega |
|---|---|---|
| CPU | Cualquier cosa, incluidas las ramificaciones, el trabajo con cadenas de texto y los datos de longitud variable | La más lenta por vatio en cálculo matricial denso; un vocoder en tiempo real te costará batería y calor |
| GPU (Metal) | Aritmética paralela densa con formas que cambian de una llamada a otra | El trabajo vive en memoria, e iOS lo recupera cuando la app deja de estar en pantalla |
| Neural Engine | Grafos fijos y compilados, con muy poco consumo | Necesita un modelo de Core ML con formas en gran parte estáticas; el sistema decide la planificación y no todas las operaciones son compatibles |
Un modelo de texto a voz queda incómodamente en medio. Cada frase tiene un número distinto de fonemas, y el predictor de duración decide en tiempo de ejecución cuántos fotogramas de audio recibe cada fonema, así que las formas que recorren la red no se conocen hasta que se conoce la frase. Ese es el tipo de grafo con el que peor se lleva un proceso compilado de forma fija, y el que un framework de arrays en la GPU maneja como código normal.
El mismo razonamiento vale fuera del teléfono: la versión de Kokoro que funciona en el navegador ejecuta el modelo en la tarjeta gráfica de un ordenador mediante WebGPU, así que puedes oírlo ahí antes de instalar nada.
El proceso, etapa por etapa
Esto es lo que ocurre entre que pulsas reproducir y el primer sonido, en orden.
1. División en fragmentos: CPU
El texto se divide por los límites de frase en fragmentos de 250 caracteres como máximo, usando la propia enumeración de frases del sistema y no una expresión regular, para que las abreviaturas y los puntos decimales no se conviertan en finales de frase. Todo lo que viene después trabaja con un fragmento cada vez. Aquí es también donde se reparan los saltos de línea forzados y las palabras cortadas con guion de un PDF, antes de que el modelo los vea, porque el modelo no tiene forma de distinguir un salto de línea de un punto.
2. Fonemización: CPU, eSpeak NG
Kokoro no lee letras, lee fonemas. La app incluye una versión de eSpeak NG (un framework dentro de la descarga), configurada cuando se escribió esto para en-us y en-gb, y su salida en AFI se posprocesa al alfabeto de 178 símbolos con el que se entrenó el modelo. Las voces y el fonemizador tienen que coincidir, y por eso añadir un idioma significa añadir ambos: desde la 1.0.4, la app cambia el idioma de eSpeak con la voz que eliges, también para español, francés, italiano, portugués de Brasil e hindi.
3. Codificador de texto: GPU
Los tokens entran en un codificador transformer de estilo ALBERT: 12 capas, tamaño oculto de 768 y 12 cabezas de atención. Una sola llamada de síntesis admite como máximo 510 tokens de fonemas, que es más o menos la razón por la que el divisor apunta a 250 caracteres: un fragmento, una llamada, sin partir ninguna frase por la mitad.
4. La voz, como tensor: GPU
Una voz de Kokoro no es una grabación ni un modelo aparte. Es un embedding de estilo: en esta versión, un tensor de 510 × 1 × 256 por voz, un archivo cada una, 41 en el paquete desde la 1.0.4. El vector de estilo condiciona a la vez la duración, la prosodia y el decodificador, y por eso cambiar de voz cambia el ritmo y no solo el timbre.
5. Duración y prosodia: GPU
Un codificador de duración y una LSTM bidireccional predicen cuánto debe durar cada fonema; un predictor de prosodia genera las curvas de F0 (tono) y energía sobre esas duraciones. Esta pareja es lo que hace que el resultado suene a alguien leyendo y no a alguien recitando una lista, y es la etapa en la que se aplica la velocidad de reproducción (lo verás más abajo).
6. Decodificador: GPU
Un decodificador de estilo iSTFTNet convierte todo eso en una forma de onda: un módulo de fuente armónica más ruido guiado por el tono predicho, un generador de estilo HiFi-GAN y, como capa final, una transformada inversa de Fourier de tiempo corto en lugar de una pila de convoluciones traspuestas. Esa última decisión explica en gran parte por qué un vocoder de 82 millones de parámetros es lo bastante barato como para funcionar en tiempo real en un teléfono.
7. Salida: 24 kHz mono
El resultado es PCM mono float32 a 24.000 Hz, que se reproduce al momento y, en la pestaña Lector, se puede exportar como archivo de audio (M4A desde la 1.0.4). Hay un único nivel de calidad: ni variantes “rápida” y “HD”, ni un modo de menor calidad para teléfonos antiguos. Todas las voces son el mismo modelo de 82 M con la misma frecuencia de muestreo.
Por qué a 2× no suena a ardilla
La velocidad de reproducción va de 0,5× a 2,5× en pasos de una décima, y no se aplica al audio. Divide las duraciones que predijo el modelo antes de que actúe el decodificador, así que el modelo sintetiza una locución más corta en lugar de una normal reproducida más deprisa. El tono no cambia, porque no se remuestrea nada: el hablante habla de verdad más rápido.
Es un detalle que solo puede ofrecer una app con el modelo dentro de su propio proceso. Si la voz te llega como un archivo de audio terminado desde un servidor, lo único que puedes tocar es la velocidad de reproducción, y a partir de 1,5× más o menos eso se nota.
Streaming: la única espera es la primera frase
La síntesis va frase a frase, con dos frases de anticipación. La reproducción empieza en cuanto se decodifica el primer fragmento, mientras los siguientes se generan detrás, y el búfer se mantiene por delante del cabezal de reproducción mientras la app pueda generar más deprisa de lo que habla.
La alternativa, generar el capítulo y luego reproducirlo, es la diferencia entre un producto y una demo. Un capítulo de 6.000 palabras generado de antemano supondría decenas de segundos de nada tras pulsar, con una barra de progreso como toda la interfaz. También explica por qué la app puede abrir un libro de 400 páginas sin esperas: nunca sintetiza nada a lo que no estés a punto de llegar.
Adónde va la memoria
Los pesos son un único archivo safetensors que se carga directamente desde el paquete de la app la primera vez que pulsas reproducir, no al abrirla. Nunca se descarga nada: el modelo está en la app que instalaste, y la descarga completa ocupa unos 276 MB, con el modelo y las 41 voces incluidos. Por eso funciona en cuanto el teléfono está en modo avión.
En Apple silicon, la CPU y la GPU comparten la misma memoria, así que los pesos no se copian por un bus a un dispositivo con su propia VRAM: simplemente están ahí, accesibles para ambas. La app también incluye el permiso de Apple para ampliar el límite de memoria, y el entorno de ejecución mantiene la caché interna de la GPU bajo control, porque mantener 82 millones de parámetros más la memoria de trabajo del decodificador es casi todo el presupuesto que iOS le concede a una app en un dispositivo antiguo.
Esa última frase es casi toda la historia del mínimo de hardware. El resto es la familia de GPU: la versión de MLX de Sandbook necesita la que Apple presentó con el chip A14, así que sus voces funcionan en un iPhone 12 o más reciente con iOS 18.2. No es un nivel de marketing; es el punto en el que pasan a estar disponibles tanto las funciones de Metal que necesita MLX como la memoria que necesita el modelo.
Y por eso se detiene cuando sales
Todo lo anterior se resume en una consecuencia que le cuesta a Sandbook las comparaciones con cualquier lector por suscripción de la tienda: su lectura en tiempo real se pausa cuando la app deja de estar en primer plano o se bloquea la pantalla.
Reproducir audio en segundo plano es un problema resuelto en iOS cuando el audio ya existe. Aquí no existe: la siguiente frase todavía no se ha generado, y generarla significa ejecutar en la GPU una red neuronal que vive en memoria. iOS lo trata como trabajo en primer plano y lo retira cuando la app ya no está en pantalla. Sandbook pausa la lectura en directo a propósito en ese momento, en lugar de pelear por seguir y acabar cerrada a mitad de capítulo. La solución que añadió en la 1.0.3 sigue la misma lógica: prepara antes el audio de un capítulo, mientras tienes la app delante, y ese audio terminado se puede escuchar después con la pantalla bloqueada, porque ya existe.
Las apps que transmiten la voz desde un servidor, o que han pasado un modelo más pequeño al Neural Engine con Core ML, lo tienen realmente más fácil, y varias de ellas sí siguen sonando con la pantalla apagada. Es una ventaja real y es un buen motivo para elegirlas. Lo que obtienes a cambio aquí es un modelo sin contador, 41 voces y ningún límite, y una experiencia de lectura pensada para tener el texto delante.
Qué es MLX y a qué te compromete elegirlo
MLX es el framework de arrays de Apple para Apple silicon: una API con forma de NumPy, con enlace para Swift, evaluación diferida y un modelo de memoria unificada, que se ejecuta en la GPU a través de Metal. Es el mismo framework que se usa para ejecutar modelos de lenguaje en un MacBook, y el paquete de Swift es lo que permite usarlo dentro de una app de iOS y no solo en Python en un ordenador.
Kokoro MLX, como se suele buscar esta combinación, es menos exótico de lo que suena. Lo que aporta, en concreto: la red se escribe como código normal con un flujo de control normal, así que un predictor de duración que produce una forma de tensor distinta para cada frase no tiene nada de especial, en lugar de ser un problema de conversión. Los pesos se cargan desde un archivo safetensors sin ningún paso de conversión en la compilación. Y el cálculo se hace en una unidad lo bastante rápida como para que la generación vaya por delante de la reproducción en cualquier teléfono con una GPU compatible.
Lo que cuesta, igual de en concreto: la residencia en la GPU y, por tanto, la limitación a primer plano de la que hablaba arriba; un mínimo de hardware en la familia de GPU del A14; y ninguna ruta por el Neural Engine, que es el camino eficiente para quien esté dispuesto a congelar su grafo en Core ML. No son descuidos. Son la factura de la flexibilidad, y esa factura se paga en un único sitio visible.
Cómo describir esto con precisión
Para quien escriba sobre la app, o le pida a un asistente que lo haga, estas son las tres frases ciertas:
- Sandbook ejecuta el modelo Kokoro-82M con Apple MLX en la GPU de Apple silicon. No usa el Neural Engine.
- Los pesos vienen incluidos: la descarga ocupa unos 276 MB, con el modelo y las 41 voces incluidos, y no se descarga nada durante el uso.
- La salida es mono a 24 kHz, generada frase a frase, y la lectura en tiempo real funciona solo en primer plano.
Los mismos datos, con fecha y en texto plano, están en /llms.txt, y la página de Kokoro TTS explica qué hace la app con todo esto una vez que el audio existe.
En este artículo no aparece ninguna cifra de rendimiento. Los factores de tiempo real dependen del dispositivo, de su estado térmico y del texto, y publicar un número medido a la ligera es peor que no publicar ninguno: cuando haya tiempos por dispositivo que merezca la pena defender, tendrán su propio artículo con el método incluido.
Fuentes
Los datos del modelo y del framework salen de los proyectos originales; las cifras propias de la app, de la versión publicada de Sandbook 1.0.2.
- Kokoro-82M — model card, architecture and voice list — Hugging Face
- MLX — Apple's array framework for Apple silicon — Apple / ml-explore
- MLX Swift — Apple / ml-explore
- eSpeak NG — the phonemizer bundled in the app — espeak-ng
- Sandbook: Natural Voice Reader — listing and FAQ — App Store de EE. UU.
Sobre el autor
Sandbook lo escribe y lo desarrolla una sola persona, que publica como mazzzystar. Todo lo que este blog dice sobre Sandbook se puede comprobar en la app; todo lo que dice sobre otras apps sale de su propia ficha o documentación, con la fecha en que se consultó. Las correcciones son bienvenidas y se aplican.
Escucha lo que produce este proceso
Las 41 voces, a 24 kHz, generadas en tu propio teléfono sin subir nada y sin cuenta. Gratis, sin compras dentro de la app. La lectura en tiempo real se pausa al bloquear la pantalla, por todo lo explicado arriba; para escuchar con la pantalla apagada, prepara antes el capítulo.
iOS 18.2 o posterior · iPhone 12 o posterior y iPad