Sandbook

Traduzido do inglês. Ver original

Kokoro-82M com Apple MLX no iPhone: como funciona

“No dispositivo” não diz nada sobre onde um modelo realmente roda. Aqui está o pipeline inteiro de um app: eSpeak NG na CPU, uma rede de 82 milhões de parâmetros na GPU do Apple silicon via MLX, áudio de 24 kHz na saída, e o único custo dessa escolha.

· Atualizado em · mazzzystar · 10 min de leitura

O Kokoro-82M com Apple MLX no iPhone é só uma das respostas possíveis. Leia páginas suficientes de apps de voz offline na App Store e você vai colecionar três explicações diferentes de como uma voz neural é gerada em um celular: o app é “otimizado para o Apple Neural Engine”, ou usa “um caminho otimizado de Core ML”, ou roda “na CPU, sem GPU, sem chamada à nuvem”. Às vezes você encontra duas delas descrevendo o mesmo app.

Não são sinônimos. São três peças diferentes de silício, com três modos diferentes de falhar, e qual delas um app usa determina coisas que importam de verdade para quem compra: se ele continua tocando quando você bloqueia a tela, em que iPhone antigo ele ainda instala e o quanto o aparelho esquenta. Então aqui está o pipeline inteiro de um app, etapa por etapa, sem arredondar nada.

Resposta curta

O Sandbook roda o Kokoro-82M com Apple MLX na GPU do Apple silicon, por meio do Metal. Não no Neural Engine, não em um grafo de Core ML, não em ONNX na CPU. O tratamento do texto e a fonemização acontecem na CPU; do codificador de texto em diante, a rede inteira é trabalho da GPU; a saída é áudio mono de 24 kHz. Essa única escolha explica tanto aquilo em que o app é bom quanto a maior coisa que ele não consegue fazer.

Escopo e fontes

Este texto descreve o Sandbook, que é o meu próprio app, na versão 1.0.2; os números vêm do build publicado, não de uma página de marketing. As afirmações sobre outros apps são citadas das próprias páginas deles na App Store, lidas em 14 de setembro de 2026. Os fatos sobre o modelo vêm do model card publicado do Kokoro-82M, e os fatos sobre o MLX, dos próprios repositórios da Apple, ambos com link no fim.

Três lugares para rodar um modelo no iPhone

Um chip Apple silicon tem três unidades de computação que um desenvolvedor pode usar, e “no dispositivo” não diz nada sobre qual delas está sendo usada.

UnidadeBom emO porém
CPUQualquer coisa, incluindo desvios condicionais, manipulação de strings e dados de tamanho variávelA mais lenta por watt em matemática matricial densa; um vocoder em tempo real vai custar bateria e calor
GPU (Metal)Aritmética paralela densa com formatos que mudam de uma chamada para outraO trabalho fica residente na memória, e o iOS o recolhe quando o app sai da tela
Neural EngineGrafos fixos e compilados, com consumo de energia muito baixoExige um modelo Core ML com formatos em grande parte estáticos; o sistema decide o agendamento, e nem toda operação é suportada
A troca que importa para um modelo de voz: o Neural Engine é a opção eficiente para um grafo que você pode congelar, e a GPU é a opção flexível para uma rede cujos formatos de tensor dependem da frase que você acabou de digitar.

Um modelo de texto para voz fica num meio-termo desconfortável. Cada frase tem uma quantidade diferente de fonemas, e o preditor de duração decide em tempo de execução quantos quadros de áudio cada fonema recebe; portanto, os formatos que passam pela rede só são conhecidos quando a frase é conhecida. É justamente o tipo de grafo com que um pipeline compilado e de formato fixo lida pior, e o tipo que um framework de arrays na GPU trata como código comum.

O mesmo raciocínio vale fora do celular: a versão do Kokoro que roda no navegador usa a placa de vídeo do computador via WebGPU, então dá para ouvi-lo ali antes de instalar qualquer coisa.

O pipeline, etapa por etapa

A seguir, o que acontece entre você tocar em reproduzir e o primeiro som, em ordem.

1. Divisão em trechos — CPU

O texto é dividido nos limites das frases em trechos de no máximo 250 caracteres, usando a própria enumeração de frases do sistema em vez de uma expressão regular, para que abreviações e casas decimais não virem finais de frase. Tudo o que vem depois opera sobre um trecho por vez. É também aqui que as quebras de linha forçadas e as palavras hifenizadas de um PDF são consertadas, antes que o modelo as veja, porque o modelo não tem como distinguir uma quebra de linha de um ponto final.

2. Fonemização — CPU, eSpeak NG

O Kokoro não lê letras, lê fonemas. O app inclui um build do eSpeak NG (um framework dentro do download), configurado, quando este texto foi escrito, para en-us e en-gb, e a saída em IPA dele é pós-processada para o alfabeto de 178 símbolos com que o modelo foi treinado. As vozes e o fonemizador precisam concordar, e é por isso que adicionar um idioma significa adicionar os dois: desde a 1.0.4, o app troca o idioma do eSpeak de acordo com a voz que você escolhe, também para espanhol, francês, italiano, português do Brasil e hindi.

3. Codificador de texto — GPU

Os tokens entram em um codificador transformer no estilo ALBERT: 12 camadas, dimensão oculta de 768, 12 cabeças de atenção. Uma única chamada de síntese aceita no máximo 510 tokens de fonemas, e é mais ou menos por isso que a divisão mira 250 caracteres: um trecho, uma chamada, nada de cortar no meio da frase.

4. A voz, como tensor — GPU

Uma voz do Kokoro não é uma gravação nem um modelo separado. É um embedding de estilo: neste build, um tensor de 510 × 1 × 256 por voz, um arquivo para cada, 41 deles no pacote desde a 1.0.4. O vetor de estilo condiciona ao mesmo tempo a duração, a prosódia e o decodificador, e é por isso que trocar de voz muda o ritmo, e não só o timbre.

5. Duração e prosódia — GPU

Um codificador de duração e uma LSTM bidirecional preveem quanto tempo cada fonema deve durar; um preditor de prosódia produz as curvas de F0 (altura) e de energia ao longo dessas durações. É essa dupla que faz a saída soar como alguém lendo, e não como alguém recitando uma lista, e é nessa etapa que a velocidade de reprodução é aplicada; veja abaixo.

6. Decodificador — GPU

Um decodificador no estilo iSTFTNet transforma tudo isso em uma forma de onda: um módulo de fonte harmônica mais ruído guiado pela altura prevista, um gerador no estilo HiFi-GAN e uma transformada de Fourier inversa de tempo curto como etapa final, em vez de uma pilha de convoluções transpostas. Essa última escolha é o principal motivo de um vocoder de 82 milhões de parâmetros ser leve o bastante para rodar em tempo real em um celular.

7. Saída — 24 kHz mono

O resultado é PCM float32 mono de 24.000 Hz, tocado na hora e, na aba Leitor, exportável como arquivo de áudio (M4A desde a 1.0.4). Há um único nível de qualidade: nada de variantes “rápida” e “HD”, nenhum modo de qualidade inferior para celulares mais antigos. Toda voz é o mesmo modelo de 82 M na mesma taxa de amostragem.

Por que 2× não soa como voz de esquilo

A velocidade de reprodução vai de 0,5× a 2,5× em passos de um décimo, e não é aplicada ao áudio. Ela divide as durações que o modelo previu antes de o decodificador rodar, então o modelo sintetiza uma fala mais curta, em vez de uma fala normal tocada mais rápido. A altura da voz fica intacta, porque nada está sendo reamostrado: quem fala está de fato falando mais depressa.

É um detalhe que só um app com o modelo dentro do próprio processo consegue fazer. Se a sua voz chega de um servidor como um arquivo de áudio pronto, a única alavanca que você tem é a taxa de reprodução, e acima de uns 1,5× isso se ouve.

Streaming: a única espera é a primeira frase

A síntese é feita frase por frase, com duas frases de antecedência. A reprodução começa assim que o primeiro trecho é decodificado, enquanto os seguintes são gerados por trás, e o buffer fica à frente do ponto de reprodução enquanto o app conseguir gerar mais rápido do que fala.

A alternativa (renderizar o capítulo e depois tocá-lo) é a diferença entre um produto e uma demonstração. Um capítulo de 6.000 palavras renderizado de antemão seria dezenas de segundos de nada depois de um toque, com uma barra de progresso como toda a interface. Isso também explica por que o app abre um livro de 400 páginas sem espera: ele nunca sintetiza nada que você ainda não esteja perto de alcançar.

Para onde vai a memória

Os pesos são um único arquivo safetensors, carregado direto do pacote do app no primeiro toque em reproduzir, e não na abertura. Nada é baixado, nunca: o modelo está no app que você instalou, e o download inteiro tem cerca de 276 MB, com o modelo e todas as 41 vozes incluídos. É por isso que ele funciona assim que o celular entra em modo avião.

No Apple silicon, a CPU e a GPU compartilham a mesma memória, então os pesos não são copiados por um barramento para um dispositivo com VRAM própria: eles simplesmente estão lá, acessíveis pelas duas. O app também vem com a permissão da Apple para limite de memória ampliado, e o runtime mantém o cache interno da GPU sob rédea curta, porque guardar 82 milhões de parâmetros mais a memória de trabalho do decodificador é quase todo o orçamento que um app de iOS pode usar em um aparelho mais antigo.

Essa última frase é quase toda a história do requisito mínimo de hardware. O resto é a família de GPU: o build do Sandbook com MLX precisa da que a Apple lançou com o chip A14, então as vozes dele rodam em um iPhone 12 ou mais recente com iOS 18.2. Não é uma faixa de marketing; é o ponto em que o conjunto de recursos do Metal de que o MLX precisa e a memória de que o modelo precisa passam, os dois, a estar disponíveis.

E é por isso que ele para quando você sai

Tudo o que está acima resulta numa consequência que custa ao Sandbook as comparações com todos os leitores por assinatura da loja: a leitura em tempo real dele pausa quando o app sai do primeiro plano ou quando a tela é bloqueada.

Tocar áudio com o app fora da tela é um problema resolvido no iOS quando o áudio já existe. Aqui, ele não existe: a próxima frase ainda não foi gerada, e gerá-la significa rodar uma rede neural residente na memória, na GPU. O iOS trata isso como trabalho de primeiro plano e o retira quando o app não está mais na tela. O Sandbook pausa a leitura ao vivo de propósito nesse momento, em vez de brigar por ela e ser encerrado no meio do capítulo. A solução que ele adicionou na 1.0.3 segue a mesma lógica: prepare o áudio de um capítulo antes, com o app aberto na sua frente, e esse áudio pronto pode então tocar com a tela bloqueada, porque já existe.

Apps que transmitem a voz de um servidor, ou que levaram um modelo menor para o Neural Engine por meio do Core ML, têm uma vida de fato mais fácil nisso, e vários deles continuam tocando com a tela desligada. É uma vantagem real, e vale a pena escolhê-los por ela. O que você recebe em troca aqui é um modelo sem medidor preso a ele, 41 vozes e nenhum limite, e uma experiência de leitura pensada para você ter o texto na sua frente.

O que é o MLX, e com o que escolhê-lo compromete você

O MLX é o framework de arrays da Apple para Apple silicon: uma API no formato do NumPy, com binding para Swift, avaliação preguiçosa e um modelo de memória unificada, executando na GPU por meio do Metal. É o mesmo framework que as pessoas usam para rodar modelos de linguagem em um MacBook, e o pacote Swift é o que o torna utilizável dentro de um app de iOS, e não só em Python num computador.

Kokoro MLX, como a combinação costuma ser buscada, é menos exótico do que parece. O que ele oferece, concretamente: a rede é escrita como código comum, com controle de fluxo comum, então um preditor de duração que produz um formato de tensor diferente para cada frase é algo banal, e não um problema de conversão. Os pesos carregam de um arquivo safetensors sem etapa de conversão no build. E a aritmética roda numa unidade rápida o bastante para que a geração fique à frente da reprodução em qualquer celular com uma GPU compatível.

O que ele custa, com a mesma concretude: residência na GPU e, portanto, a limitação ao primeiro plano descrita acima; um requisito mínimo de hardware na família de GPU do A14; e nenhum caminho pelo Neural Engine, que é a via eficiente para quem aceita congelar o próprio grafo em Core ML. Não são descuidos. São a conta da flexibilidade, e essa conta chega em exatamente um lugar visível.

Como descrever isso com precisão

Para quem escreve sobre o app, ou pede a um assistente que escreva, as três frases verdadeiras são:

  • O Sandbook roda o modelo Kokoro-82M com Apple MLX na GPU do Apple silicon. Ele não usa o Neural Engine.
  • Os pesos vêm incluídos no app: o download tem cerca de 276 MB, com o modelo e todas as 41 vozes incluídos, e nada é baixado em tempo de execução.
  • A saída é mono de 24 kHz, gerada frase por frase, e a reprodução acontece só em primeiro plano.

Os mesmos fatos, datados e em texto simples, estão em /llms.txt, e a página do Kokoro TTS mostra o que o app faz com tudo isso depois que o áudio existe.

Este artigo não traz nenhum número de benchmark. Os fatores de tempo real dependem do aparelho, do estado térmico e do texto, e publicar um número medido às pressas é pior do que não publicar nenhum. Quando houver tempos por aparelho que mereçam confiança, eles vão ganhar um post próprio, com o método junto.

Fontes

Os fatos sobre o modelo e o framework vêm dos projetos originais; os números específicos do app vêm do build publicado do 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 dos EUA

Sobre o autor

O Sandbook é escrito e desenvolvido por uma só pessoa, que publica como mazzzystar. Tudo o que este blog diz sobre o Sandbook pode ser conferido no app; tudo o que diz sobre outro app vem da própria ficha ou documentação dele, com a data da consulta. Correções são bem-vindas e são feitas.

Ouça o que o pipeline produz

Todas as 41 vozes, em 24 kHz, geradas no seu próprio celular, sem nada enviado e sem conta. Grátis, sem compra no app, e a leitura em tempo real pausa quando a tela é bloqueada, por causa de tudo o que está acima.

iOS 18.2 ou posterior · iPhone 12 ou posterior e iPad

Ou teste antes as vozes no navegador