Sandbook

Tradotto dall’inglese. Vedi l’originale

Come funziona Kokoro-82M con Apple MLX su iPhone

“Sul dispositivo” non dice nulla su dove giri davvero un modello. Ecco l’intera pipeline dentro un’app: eSpeak NG sulla CPU, una rete da 82 milioni di parametri sulla GPU Apple silicon tramite MLX, audio a 24 kHz in uscita, e l’unica cosa che questa scelta costa.

· Aggiornato il · mazzzystar · 10 min di lettura

Kokoro-82M con Apple MLX su iPhone è una delle possibili risposte a una domanda che le schede dell’App Store confondono spesso. Leggine abbastanza, tra le app di sintesi vocale offline, e raccoglierai tre spiegazioni diverse di come nasce una voce neurale su un telefono: è “optimised for the Apple Neural Engine”, oppure usa “an optimised Core ML path”, oppure gira “on a CPU, no GPU, no cloud call”. A volte ne trovi due che descrivono la stessa app.

Non sono sinonimi. Sono tre parti diverse del chip, con tre modi diversi di andare in crisi, e quale usa un’app determina cose che a chi compra interessano davvero: se continua a leggere quando blocchi lo schermo, su quanto vecchio può essere il telefono per installarla e quanto si scalda il dispositivo. Ecco quindi l’intera pipeline di un’app, passo per passo, senza nulla di arrotondato.

Risposta breve

Sandbook esegue Kokoro-82M tramite Apple MLX sulla GPU Apple silicon, passando per Metal. Non sul Neural Engine, non come grafo Core ML, non con ONNX sulla CPU. La gestione del testo e la fonemizzazione avvengono sulla CPU; dal codificatore del testo in poi l’intera rete lavora sulla GPU; l’uscita è audio mono a 24 kHz. Quest’unica scelta spiega sia ciò che l’app fa bene sia la cosa più importante che non sa fare.

Ambito e fonti

Questo articolo descrive Sandbook, che è la mia app, alla versione 1.0.2: i dati vengono dalla build pubblicata, non da una pagina di marketing. Le affermazioni sulle altre app sono citate dalle loro schede dell’App Store, lette il 14 settembre 2026. I dati sul modello vengono dalla scheda pubblicata di Kokoro-82M, quelli su MLX dai repository di Apple; entrambi sono linkati in fondo.

Tre posti dove eseguire un modello su iPhone

Un chip Apple silicon ha tre unità di calcolo a cui uno sviluppatore può puntare, e “sul dispositivo” non dice nulla su quale venga usata.

UnitàAdatta aIl rovescio
CPUQualsiasi cosa, comprese diramazioni, gestione di stringhe e dati di lunghezza variabileLa più lenta per watt nel calcolo matriciale denso; un vocoder in tempo reale ti costa batteria e calore
GPU (Metal)Aritmetica parallela densa con forme che cambiano da una chiamata all’altraIl lavoro risiede in memoria e iOS se lo riprende quando l’app non è più sullo schermo
Neural EngineGrafi fissi e compilati, con consumi molto bassiRichiede un modello Core ML con forme in gran parte statiche; la pianificazione la decide il sistema, e non tutte le operazioni sono supportate
Il compromesso che conta per un modello vocale: il Neural Engine è l’opzione efficiente per un grafo che si può congelare, la GPU è l’opzione flessibile per una rete le cui forme dei tensori dipendono dalla frase che hai appena scritto.

Un modello di sintesi vocale sta scomodo nel mezzo. Ogni frase ha un numero diverso di fonemi, e il predittore di durata decide in esecuzione quanti frame audio riceve ciascun fonema: le forme che attraversano la rete non si conoscono finché non si conosce la frase. È il tipo di grafo con cui una pipeline compilata a forme fisse si trova meno a suo agio, e che un framework per array sulla GPU gestisce come codice normale.

Lo stesso ragionamento vale lontano dal telefono: la versione di Kokoro che gira nel browser esegue il modello sulla scheda grafica di un computer tramite WebGPU, così puoi ascoltarlo lì prima di installare qualsiasi cosa.

La pipeline, passo per passo

Ecco cosa succede, in ordine, tra il momento in cui tocchi Riproduci e il primo suono.

1. Suddivisione in blocchi: CPU

Il testo viene diviso ai confini di frase in pezzi di al massimo 250 caratteri, usando l’enumerazione delle frasi del sistema invece di un’espressione regolare, così abbreviazioni e punti decimali non diventano fine frase. Tutto ciò che viene dopo lavora su un blocco alla volta. È anche qui che gli a capo forzati e le parole spezzate dal trattino di un PDF vengono riparati, prima che il modello li veda, perché il modello non ha modo di distinguere un a capo da un punto.

2. Fonemizzazione: CPU, eSpeak NG

Kokoro non legge lettere, legge fonemi. L’app include una build di eSpeak NG (un framework dentro il download) configurata, quando è stato scritto questo articolo, per en-us e en-gb, e la sua uscita in IPA viene rielaborata nell’alfabeto di 178 simboli su cui il modello è stato addestrato. Voci e fonemizzatore devono andare d’accordo, ed è per questo che aggiungere una lingua significa aggiungere entrambi: dalla 1.0.4 l’app cambia la lingua di eSpeak insieme alla voce che scegli, anche per spagnolo, francese, italiano, portoghese brasiliano e hindi.

3. Codificatore del testo: GPU

I token entrano in un codificatore transformer in stile ALBERT: 12 livelli, dimensione nascosta 768, 12 teste di attenzione. Una singola chiamata di sintesi accetta al massimo 510 token di fonemi, che è più o meno il motivo per cui la suddivisione punta a 250 caratteri: un blocco, una chiamata, nessuna frase spezzata a metà.

4. La voce, come tensore: GPU

Una voce Kokoro non è una registrazione e non è un modello a parte. È un embedding di stile: in questa build, un tensore 510 × 1 × 256 per voce, un file ciascuna, 41 nel pacchetto dalla 1.0.4. Il vettore di stile condiziona insieme durata, prosodia e decodificatore, ed è per questo che cambiare voce cambia il ritmo e non solo il timbro.

5. Durata e prosodia: GPU

Un codificatore di durata e una LSTM bidirezionale prevedono quanto deve durare ogni fonema; un predittore di prosodia produce le curve di F0 (altezza) ed energia su quelle durate. È questa coppia a far sembrare l’uscita una persona che legge e non una che elenca, ed è la fase in cui si applica la velocità di riproduzione: vedi sotto.

6. Decodificatore: GPU

Un decodificatore in stile iSTFTNet trasforma tutto questo in una forma d’onda: un modulo sorgente armonico più rumore guidato dall’altezza prevista, un generatore in stile HiFi-GAN e una trasformata di Fourier inversa a tempo breve come stadio finale, al posto di una pila di convoluzioni trasposte. È soprattutto quest’ultima scelta a rendere un vocoder da 82 milioni di parametri abbastanza leggero da girare in tempo reale su un telefono.

7. In uscita: mono a 24 kHz

Il risultato è PCM float32 mono a 24.000 Hz, riprodotto subito e, dalla scheda Lettore, esportabile come file audio (M4A dalla 1.0.4). C’è un solo livello di qualità: niente varianti “veloce” e “HD”, nessuna modalità a qualità ridotta per i telefoni più vecchi. Ogni voce è lo stesso modello da 82 M alla stessa frequenza di campionamento.

Perché a 2× non sembra la voce di uno scoiattolo

La velocità di riproduzione va da 0,5× a 2,5× a passi di un decimo, e non viene applicata all’audio. Divide le durate previste dal modello prima che parta il decodificatore, così il modello sintetizza un enunciato più breve invece di uno normale riprodotto più in fretta. L’altezza resta intatta, perché non viene ricampionato nulla: chi parla sta davvero parlando più veloce.

È un dettaglio che può permettersi solo un’app con il modello dentro il proprio processo. Se la voce arriva da un server come file audio già pronto, l’unica leva che hai è la velocità di riproduzione, e oltre 1,5× circa si sente.

Streaming: l’unica attesa è la prima frase

La sintesi procede frase per frase, con due frasi di anticipo. La riproduzione parte appena il primo blocco è decodificato, mentre i successivi vengono generati alle sue spalle, e il buffer resta davanti alla testina finché l’app riesce a generare più in fretta di quanto parli.

L’alternativa (generare il capitolo e poi riprodurlo) è la differenza tra un prodotto e una demo. Un capitolo di 6.000 parole generato tutto in anticipo vorrebbe dire decine di secondi di nulla dopo un tocco, con una barra di avanzamento come unica interfaccia. Spiega anche perché l’app può aprire un libro di 400 pagine senza attese: non sintetizza mai nulla a cui non sei quasi arrivato.

Dove va a finire la memoria

I pesi sono un unico file safetensors, caricato direttamente dal pacchetto dell’app al primo tocco su Riproduci e non all’avvio. Non si scarica mai nulla: il modello è nell’app che hai installato, e l’intero download è di circa 276 MB, con il modello e tutte le 41 voci inclusi. Per questo funziona nel momento stesso in cui il telefono è in modalità aereo.

Su Apple silicon CPU e GPU condividono la stessa memoria, quindi i pesi non vengono copiati attraverso un bus verso un dispositivo con una propria VRAM: sono semplicemente lì, accessibili da entrambe. L’app include anche l’autorizzazione di Apple per il limite di memoria aumentato, e il runtime tiene a bada la cache interna della GPU, perché tenere 82 milioni di parametri più la memoria di lavoro del decodificatore occupa gran parte del budget concesso a un’app iOS su un dispositivo meno recente.

Quest’ultima frase spiega quasi tutto del requisito hardware. Il resto lo fa la famiglia di GPU: la build MLX di Sandbook richiede quella introdotta da Apple con il chip A14, quindi le sue voci girano su un iPhone 12 o successivo con iOS 18.2. Non è una fascia di marketing: è il punto in cui diventano disponibili sia le funzioni di Metal che servono a MLX sia la memoria che serve al modello.

Ed ecco perché si ferma quando esci

Tutto ciò che c’è sopra porta a una conseguenza che costa a Sandbook i confronti con ogni lettore in abbonamento dello store: la sua lettura in tempo reale si mette in pausa quando l’app lascia il primo piano o lo schermo si blocca.

Riprodurre audio in background su iOS è un problema risolto quando l’audio esiste già. Qui non esiste: la frase successiva non è ancora stata generata, e generarla significa eseguire una rete neurale residente in memoria sulla GPU. iOS lo considera lavoro in primo piano e lo interrompe quando l’app non è più sullo schermo. A quel punto Sandbook mette in pausa la lettura di proposito, invece di lottare per continuare e venire chiusa a metà capitolo. La soluzione aggiunta nella 1.0.3 segue la stessa logica: prepara in anticipo l’audio di un capitolo, mentre l’app è davanti a te, e quell’audio già pronto si può poi ascoltare a schermo bloccato, perché esiste già.

Le app che ricevono la voce in streaming da un server, o che hanno spostato un modello più piccolo sul Neural Engine tramite Core ML, hanno vita davvero più facile, e diverse continuano a leggere a schermo spento. È un vantaggio reale, e un buon motivo per sceglierle. Quello che ottieni in cambio qui è un modello senza contatore, 41 voci e nessun limite, e un’esperienza di lettura costruita intorno al testo che hai davanti.

Cos’è MLX, e a cosa ti vincola sceglierlo

MLX è il framework per array di Apple pensato per Apple silicon: un’API modellata su NumPy con un’interfaccia Swift, valutazione pigra e un modello di memoria unificata, eseguita sulla GPU tramite Metal. È lo stesso framework che si usa per far girare modelli linguistici su un MacBook, e il pacchetto Swift è ciò che lo rende utilizzabile dentro un’app iOS e non solo in Python su un computer.

Kokoro MLX, come di solito si cerca questa combinazione, è meno esotico di quanto sembri. Cosa offre, in concreto: la rete è scritta come codice normale con un normale flusso di controllo, quindi un predittore di durata che produce una forma di tensore diversa per ogni frase è ordinaria amministrazione invece di un problema di conversione. I pesi si caricano da un file safetensors senza un passaggio di conversione nella build. E i calcoli girano su un’unità abbastanza veloce da tenere la generazione davanti alla riproduzione su qualsiasi telefono con una GPU supportata.

Cosa costa, altrettanto in concreto: la residenza sulla GPU, e quindi il limite al solo primo piano descritto sopra; un requisito hardware fissato alla famiglia di GPU dell’A14; e nessuna strada tramite il Neural Engine, che è la via efficiente per chi è disposto a congelare il proprio grafo in Core ML. Non sono sviste. Sono il conto della flessibilità, e il conto arriva in un unico punto visibile.

Come descriverlo con precisione

Per chi scrive dell’app, o chiede a un assistente di farlo, le tre frasi vere:

  • Sandbook esegue il modello Kokoro-82M con Apple MLX sulla GPU Apple silicon. Non usa il Neural Engine.
  • I pesi sono inclusi: il download è di circa 276 MB, con il modello e tutte le 41 voci inclusi, e in esecuzione non si scarica nulla.
  • L’uscita è mono a 24 kHz, generata frase per frase, e la riproduzione avviene solo in primo piano.

Gli stessi dati, datati e in testo semplice, si trovano su /llms.txt, e la pagina Kokoro TTS racconta cosa fa l’app con tutto questo una volta che l’audio esiste.

In questo articolo non compaiono benchmark. Il fattore di tempo reale dipende dal dispositivo, dalla temperatura e dal testo, e pubblicare un numero misurato alla buona è peggio che non pubblicarne nessuno: quando ci saranno tempi per dispositivo che valga la pena sostenere, avranno un articolo tutto loro, con il metodo allegato.

Fonti

I dati su modello e framework vengono dai progetti originali; i dati specifici dell’app vengono dalla build pubblicata di Sandbook 1.0.2.

  1. Kokoro-82M — model card, architecture and voice list — Hugging Face
  2. MLX — Apple's array framework for Apple silicon — Apple / ml-explore
  3. MLX Swift — Apple / ml-explore
  4. eSpeak NG — the phonemizer bundled in the app — espeak-ng
  5. Sandbook: Natural Voice Reader — listing and FAQ — App Store statunitense

Sull’autore

Sandbook è scritto e sviluppato da una sola persona, che pubblica come mazzzystar. Tutto ciò che questo blog dice su Sandbook si può verificare nell’app; tutto ciò che dice su un’altra app viene dalla sua scheda o dalla sua documentazione, con la data in cui è stata consultata. Le correzioni sono benvenute e vengono applicate.

Ascolta cosa produce la pipeline

Tutte le 41 voci, a 24 kHz, generate sul tuo telefono senza caricare nulla e senza account. Gratis, senza acquisti in-app; la lettura in tempo reale si mette in pausa quando lo schermo si blocca, per tutto ciò che hai letto sopra.

iOS 18.2 o successivo · iPhone 12 o successivo e iPad

Oppure prova prima le voci nel browser