Traduit de l’anglais. Voir l’original
Kokoro-82M avec Apple MLX sur iPhone : comment ça tourne
« Sur l’appareil » ne dit rien de l’endroit où un modèle tourne vraiment. Voici toute la chaîne dans une seule app (eSpeak NG sur le CPU, un réseau de 82 millions de paramètres sur le GPU Apple silicon via MLX, un son en 24 kHz à la sortie) et la seule chose que ce choix coûte.
· Mis à jour le · mazzzystar · 10 min de lecture
Lisez assez de fiches App Store d’apps de synthèse vocale hors ligne et vous collectionnerez trois explications différentes de la façon dont une voix neuronale est produite sur un téléphone : elle serait « optimisée pour l’Apple Neural Engine », ou passerait par « un chemin Core ML optimisé », ou tournerait « sur un CPU, sans GPU, sans appel au cloud ». Il arrive même que deux d’entre elles décrivent la même app.
Ce ne sont pas des synonymes. Ce sont trois composants distincts du processeur, avec trois façons différentes d’échouer, et celui qu’une app utilise détermine des choses qui comptent vraiment pour l’acheteur : si la lecture continue quand vous verrouillez l’écran, sur quel âge de téléphone elle s’installe, et à quel point l’appareil chauffe. Voici donc toute la chaîne d’une app, étape par étape, sans rien arrondir.
Réponse courte
Sandbook fait tourner Kokoro-82M avec Apple MLX sur le GPU Apple silicon, par l’intermédiaire de Metal. Pas sur le Neural Engine, pas dans un graphe Core ML, pas en ONNX sur le CPU. Le traitement du texte et la phonémisation se font sur le CPU ; à partir de l’encodeur de texte, tout le réseau tourne sur le GPU ; la sortie est un son mono en 24 kHz. Ce seul choix explique à la fois ce que l’app fait bien et la principale chose qu’elle ne peut pas faire.
Périmètre et sources
Cet article décrit Sandbook, qui est ma propre app, en version 1.0.2 : les chiffres viennent de la version publiée, pas d’une page marketing. Ce qui est dit des autres apps est cité de leurs propres fiches App Store, lues le 14 septembre 2026. Les faits sur le modèle viennent de la fiche publiée de Kokoro-82M, et ceux sur MLX des dépôts d’Apple, tous liés en fin d’article.
Trois endroits où faire tourner un modèle sur iPhone
Une puce Apple silicon offre trois unités de calcul qu’un développeur peut viser, et « sur l’appareil » ne dit rien de celle qui est utilisée.
| Unité | Point fort | Le hic |
|---|---|---|
| CPU | Tout, y compris les branchements, le traitement de chaînes et les données de longueur variable | Le moins efficace par watt pour le calcul matriciel dense : un vocodeur en temps réel vous coûtera de la batterie et de la chaleur |
| GPU (Metal) | Le calcul parallèle dense, avec des formes de tenseurs qui changent d’un appel à l’autre | Le travail réside en mémoire, et iOS le récupère quand l’app n’est plus à l’écran |
| Neural Engine | Les graphes figés et compilés, à très faible consommation | Exige un modèle Core ML aux formes largement statiques ; le système décide de l’ordonnancement, et toutes les opérations ne sont pas prises en charge |
Un modèle de synthèse vocale se trouve mal à l’aise entre les deux. Chaque phrase compte un nombre différent de phonèmes, et le prédicteur de durée décide à l’exécution combien de trames audio reçoit chaque phonème : les formes qui traversent le réseau ne sont donc pas connues avant la phrase elle-même. C’est le genre de graphe avec lequel une chaîne compilée à formes fixes est le moins à l’aise, et celui qu’un framework de tableaux sur GPU traite comme du code ordinaire.
Le même raisonnement vaut hors du téléphone : la version de Kokoro qui tourne dans le navigateur exécute le modèle sur la carte graphique d’un ordinateur via WebGPU, si bien que vous pouvez l’y entendre avant d’installer quoi que ce soit.
La chaîne, étape par étape
Voici, dans l’ordre, ce qui se passe entre le moment où vous touchez Lire et le premier son.
1. Découpage — CPU
Le texte est découpé aux limites de phrase en morceaux de 250 caractères au plus, avec l’énumération de phrases du système plutôt qu’une expression régulière, pour que les abréviations et les séparateurs décimaux ne deviennent pas des fins de phrase. Toute la suite travaille sur un morceau à la fois. C’est aussi là que les retours à la ligne forcés et les mots coupés d’un PDF sont réparés, avant que le modèle ne les voie, car il n’a aucun moyen de distinguer un retour à la ligne d’un point final.
2. Phonémisation — CPU, eSpeak NG
Kokoro ne lit pas des lettres, il lit des phonèmes. L’app embarque une version d’eSpeak NG (un framework intégré au téléchargement) configurée, au moment de la rédaction, pour en-us et en-gb, et sa sortie en alphabet phonétique international est convertie dans l’alphabet de 178 symboles sur lequel le modèle a été entraîné. Les voix et le phonémiseur doivent concorder, c’est pourquoi ajouter une langue veut dire ajouter les deux : depuis la 1.0.4, l’app change la langue d’eSpeak selon la voix que vous choisissez, y compris pour l’espagnol, le français, l’italien, le portugais du Brésil et le hindi.
3. Encodeur de texte — GPU
Les jetons entrent dans un encodeur transformer de type ALBERT : 12 couches, taille cachée de 768, 12 têtes d’attention. Un appel de synthèse accepte au plus 510 jetons de phonèmes, ce qui explique à peu près pourquoi le découpage vise 250 caractères : un morceau, un appel, aucune coupure au milieu d’une phrase.
4. La voix, sous forme de tenseur — GPU
Une voix Kokoro n’est ni un enregistrement ni un modèle à part. C’est un plongement de style : dans cette version, un tenseur de 510 × 1 × 256 par voix, un fichier chacun, 41 dans le paquet depuis la 1.0.4. Le vecteur de style conditionne à la fois la durée, la prosodie et le décodeur, c’est pourquoi changer de voix modifie le rythme et pas seulement le timbre.
5. Durée et prosodie — GPU
Un encodeur de durée et un LSTM bidirectionnel prédisent la durée de chaque phonème ; un prédicteur de prosodie produit les courbes de F0 (hauteur) et d’énergie sur ces durées. C’est ce duo qui fait qu’on entend quelqu’un lire plutôt que quelqu’un énumérer, et c’est à cette étape que s’applique la vitesse de lecture (voir plus bas).
6. Décodeur — GPU
Un décodeur de type iSTFTNet transforme le tout en forme d’onde : un module source harmonique plus bruit piloté par la hauteur prédite, un générateur de type HiFi-GAN, et une transformée de Fourier inverse à court terme comme étage final au lieu d’une pile de convolutions transposées. Ce dernier choix explique l’essentiel de ce qui rend un vocodeur de 82 millions de paramètres assez léger pour tourner en temps réel sur un téléphone.
7. Sortie — 24 kHz mono
Le résultat est un signal PCM float32 mono à 24 000 Hz, lu immédiatement et, dans l’onglet Lecteur, exportable en fichier audio (M4A depuis la 1.0.4). Il n’y a qu’un seul niveau de qualité : pas de variantes « rapide » et « HD », pas de mode dégradé pour les téléphones plus anciens. Chaque voix passe par le même modèle de 82 M, à la même fréquence d’échantillonnage.
Pourquoi 2× ne donne pas une voix de Schtroumpf
La vitesse de lecture va de 0,5× à 2,5× par pas d’un dixième, et elle ne s’applique pas au son. Elle divise les durées prédites par le modèle avant que le décodeur ne s’exécute, si bien que le modèle synthétise un énoncé plus court au lieu d’un énoncé normal lu plus vite. La hauteur reste intacte, puisque rien n’est rééchantillonné : la voix parle réellement plus vite.
C’est un détail que seule une app qui fait tourner le modèle dans son propre processus peut offrir. Si la voix vous arrive d’un serveur sous forme de fichier audio terminé, votre seul levier est la vitesse de lecture, et au-delà d’environ 1,5× cela s’entend.
Le flux continu : la seule attente, c’est la première phrase
La synthèse se fait phrase par phrase, avec deux phrases d’avance. La lecture démarre dès que le premier morceau est décodé pendant que les suivants se génèrent derrière, et la mémoire tampon garde de l’avance sur la tête de lecture tant que l’app génère plus vite qu’elle ne parle.
L’autre option (calculer tout le chapitre, puis le lire) fait la différence entre un produit et une démo. Un chapitre de 6 000 mots calculé d’avance, ce seraient des dizaines de secondes de silence après un appui, avec une barre de progression pour toute interface. Cela explique aussi pourquoi l’app ouvre un livre de 400 pages sans attendre : elle ne synthétise jamais rien que vous n’êtes pas sur le point d’atteindre.
Où passe la mémoire
Les poids tiennent dans un seul fichier safetensors, chargé directement depuis le paquet de l’app au premier appui sur Lire plutôt qu’au lancement. Rien n’est jamais téléchargé : le modèle est dans l’app que vous avez installée, et le téléchargement fait environ 276 Mo, modèle et 41 voix compris. D’où un fonctionnement immédiat dès que le téléphone passe en mode Avion.
Sur Apple silicon, le CPU et le GPU partagent la même mémoire : les poids ne sont pas copiés via un bus vers une puce dotée de sa propre VRAM, ils sont simplement là, accessibles aux deux. L’app dispose aussi du droit d’Apple à une limite de mémoire relevée, et le moteur tient le cache interne du GPU en laisse courte, car garder 82 millions de paramètres plus la mémoire de travail du décodeur occupe l’essentiel du budget qu’iOS accorde à une app sur un appareil plus ancien.
Cette dernière phrase résume l’essentiel du plancher matériel. Le reste tient à la famille de GPU : la version MLX de Sandbook exige celle qu’Apple a introduite avec la puce A14, et ses voix fonctionnent donc sur un iPhone 12 ou plus récent sous iOS 18.2. Ce n’est pas une gamme marketing : c’est le point où le jeu de fonctions Metal dont MLX a besoin et la mémoire dont le modèle a besoin deviennent disponibles tous les deux.
Et voilà pourquoi la lecture s’arrête quand vous quittez l’app
Tout ce qui précède aboutit à une conséquence qui coûte à Sandbook chaque comparaison avec les lecteurs par abonnement de l’App Store : sa lecture en temps réel se met en pause quand l’app quitte le premier plan ou quand l’écran se verrouille.
Lire de l’audio en arrière-plan est un problème résolu sur iOS quand l’audio existe déjà. Ici, ce n’est pas le cas : la phrase suivante n’a pas encore été générée, et la générer implique de faire tourner un réseau neuronal résidant en mémoire sur le GPU. iOS considère ce travail comme du premier plan et le retire dès que l’app n’est plus à l’écran. Sandbook met alors volontairement en pause la lecture en direct plutôt que de lutter et d’être interrompue en plein chapitre. La solution ajoutée en 1.0.3 découle de la même logique : préparez l’audio d’un chapitre à l’avance, pendant que l’app est devant vous, et cet audio terminé peut ensuite s’écouter écran verrouillé, puisqu’il existe déjà.
Les apps qui diffusent la voix depuis un serveur, ou qui ont porté un modèle plus petit sur le Neural Engine via Core ML, ont la tâche nettement plus facile, et plusieurs continuent effectivement de lire écran éteint. C’est un vrai avantage, et une bonne raison de les choisir. Ce que vous obtenez ici en échange, c’est un modèle sans compteur, 41 voix et aucun plafond, et une expérience de lecture pensée pour avoir le texte sous les yeux.
Ce qu’est MLX, et ce que ce choix engage
MLX est le framework de tableaux d’Apple pour Apple silicon : une API calquée sur NumPy, avec une interface Swift, une évaluation paresseuse et un modèle de mémoire unifiée, qui s’exécute sur le GPU via Metal. C’est le même framework qu’on utilise pour faire tourner des modèles de langage sur un ordinateur portable, et c’est le paquet Swift qui le rend utilisable dans une app iOS plutôt que seulement en Python sur un ordinateur.
Kokoro MLX, comme on cherche généralement cette combinaison, est moins exotique qu’il n’y paraît. Ce qu’elle apporte, concrètement : le réseau est écrit comme du code ordinaire, avec un flux de contrôle ordinaire, si bien qu’un prédicteur de durée qui produit une forme de tenseur différente à chaque phrase n’a rien de remarquable au lieu d’être un problème de conversion. Les poids se chargent depuis un fichier safetensors sans étape de conversion à la compilation. Et le calcul tourne sur une unité assez rapide pour que la génération garde de l’avance sur la lecture sur tout téléphone doté d’un GPU pris en charge.
Ce qu’elle coûte, tout aussi concrètement : la résidence sur le GPU, donc la limitation au premier plan décrite plus haut ; un plancher matériel à la famille de GPU de l’A14 ; et aucun chemin vers le Neural Engine, qui est la voie économe pour qui accepte de figer son graphe dans Core ML. Ce ne sont pas des oublis. C’est la facture de la souplesse, et elle se présente à un seul endroit visible.
Comment décrire tout cela avec exactitude
Pour qui écrit sur l’app, ou demande à un assistant de le faire, voici les trois phrases qui sont vraies :
- Sandbook fait tourner le modèle Kokoro-82M avec Apple MLX sur le GPU Apple silicon. Il n’utilise pas le Neural Engine.
- Les poids sont intégrés à l’app : le téléchargement fait environ 276 Mo, modèle et 41 voix compris, et rien n’est récupéré à l’exécution.
- La sortie est en 24 kHz mono, générée phrase par phrase, et la lecture se fait au premier plan uniquement.
Les mêmes faits, datés et en texte brut, se trouvent dans /llms.txt, et la page Kokoro TTS explique ce que l’app fait de tout cela une fois l’audio produit.
Aucun chiffre de performance ne figure dans cet article. Le facteur temps réel dépend de l’appareil, de son état thermique et du texte, et publier une mesure faite à la légère est pire que de n’en publier aucune : quand il y aura des temps par appareil qui méritent d’être défendus, ils auront leur propre article, avec la méthode.
Sources
Les faits sur le modèle et le framework viennent des projets d’origine ; les chiffres propres à l’app viennent de la version publiée 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 américain
À propos de l’auteur
Sandbook est écrit et développé par une seule personne, qui publie sous le nom de mazzzystar. Tout ce que ce blog dit de Sandbook peut se vérifier dans l’app ; tout ce qu’il dit d’une autre app provient de sa propre fiche ou de sa documentation, avec la date de consultation. Les corrections sont bienvenues et sont appliquées.
Écoutez ce que produit la chaîne
Les 41 voix, en 24 kHz, générées sur votre propre téléphone, sans rien envoyer en ligne et sans compte. Gratuite, sans achat intégré ; la lecture en temps réel se met en pause quand l’écran se verrouille, pour toutes les raisons exposées plus haut.
iOS 18.2 ou ultérieur · iPhone 12 ou ultérieur et iPad