Faire tourner un agent vocal sur l’appareil
un pipeline, trois budgets mémoire.
Un agent vocal local n’est pas un modèle — c’est un pipeline de quatre : détection d’activité vocale, reconnaissance vocale, un modèle de langage et synthèse vocale, reliés par une machine à états qui gère les tours de parole. Le pipeline est le même sur un téléphone et sur un portable. Ce qui change, c’est quel modèle va dans chaque case, et cela se décide à deux chiffres : combien de mémoire tu as, et quel accélérateur tu alimentes.
Le chiffre à retenir, c’est la boucle entière, pas un seul modèle : perception de la parole (STT) + génération de la réponse (LLM) + synthèse vocale (TTS) tiennent toutes dedans — ~1,2 Go sur iPhone, ~1,5 Go sur un Galaxy S23, et sous ~4 Go sur un Mac avec un vrai cerveau de conversation.
Le pipeline, c’est la partie portable.
L’orchestration vit dans speech-core, une machine à états en C++ pur, agnostique au modèle : les quatre étapes sont des interfaces où tu branches n’importe quel backend — ONNX, LiteRT, CoreML/MLX sur l’appareil, ou même une API cloud — si bien que le même pipeline fait tourner un appeleur d’outils de 270M sur un téléphone et un cerveau Gemma 4 sur un Mac.
Une boucle, quatre étapes. Un mot de réveil, l’AEC et le rehaussement sont des étapes optionnelles avant le VAD ; ce sont les appels d’outils du LLM qui lui permettent d’agir, pas seulement de répondre.
L’orchestrateur est VoicePipeline dans speech-core. Il gère la détection des tours, l’interruption, l’historique de conversation, la boucle d’appels d’outils et la file d’attente vocale — mais aucun modèle propre. Chaque étape est remplaçable derrière une interface (VADInterface, STTInterface, LLMInterface, TTSInterface) que tu implémentes avec ONNX Runtime, LiteRT, CoreML/MLX (via la bibliothèque sœur speech-swift), ou même une API cloud. Il existe aussi des modes plus légers — Echo (VAD → STT → TTS) et TranscribeOnly (VAD → STT → texte).
La NPU d’abord, et toute la boucle tient dans ~1,5 Go.
Sur un téléphone, la contrainte, c’est la mémoire, la batterie et la chaleur — pas la puissance brute. La bonne cible, c’est l’unité de traitement neuronal (NPU) : le Neural Engine d’Apple sur iOS, NNAPI / Hexagon sur Android. Elle exécute des transformers quantifiés à une fraction de l’énergie du CPU ou du GPU et laisse le CPU libre pour l’audio et l’interface.
Pourquoi la NPU et pas le CPU ou le GPU ? Une NPU est un moteur de flux de données à fonction fixe, bâti pour une seule tâche — la multiplication-accumulation basse précision dont sont faits les réseaux neuronaux. Elle garde les poids en SRAM sur puce, juste à côté des unités de calcul, et évite le fetch/décodage d’instructions et les larges chemins de données généralistes qui consomment l’essentiel de l’énergie d’un CPU ou d’un GPU. Déplacer les données coûte bien plus que calculer, donc garder les deux en local, c’est le gain : les mêmes multiplications matricielles tournent à une fraction des watts — pas de throttling thermique, pas de décharge de batterie, et le CPU reste libre pour tout le reste.
Le pipeline mobile, ce sont donc des modèles petits, quantifiés et adaptés à la NPU : Silero VAD, Parakeet-EOU 120M (STT en streaming léger avec détection de fin d’énoncé intégrée), FunctionGemma 270M (le cerveau qui appelle les outils) et Kokoro-82M ou Supertonic-3 pour la voix. Mesuré sur l’appareil :
| Étape · modèle | iPhone 16 Pro (CoreML / ANE) | Galaxy S23 (LiteRT / ONNX, CPU) |
|---|---|---|
| STT · Parakeet-EOU 120M | 0.04 RTF · 297 MB | 0.21 RTF · 232 MB |
| STT · Omnilingual 300M | 0.28 RTF · 495 MB | 0.15 RTF · 831 MB |
| TTS · Kokoro-82M | 0.08 RTF · 676 MB | 0.53 RTF · 640 MB |
| TTS · Supertonic-3 99M | 0.15 RTF · 956 MB | 0.34 RTF · 832 MB |
| LLM · FunctionGemma 270M | 128 tok/s · 236 MB | 118 tok/s · 611 MB |
RTF = temps réel ÷ secondes d’audio (plus bas = plus rapide ; <1,0 est plus rapide que le temps réel). La mémoire crête est par modèle, isolé.
Chaque étape bat le temps réel. Chargés ensemble pour un agent en direct, l’ensemble résident est de ~1,2 Go sur l’iPhone et ~1,5 Go sur le Galaxy S23 — l’écart, c’est presque entièrement le LLM : FunctionGemma prend 236 Mo sur l’ANE contre 611 Mo sur le CPU du S23. iOS tourne déjà sur la NPU (d’où les 0,04 RTF du STT et 128 tok/s du LLM) ; Android est aujourd’hui temps réel sur CPU, les délégués NNAPI/Hexagon en bonus, pas en prérequis.
Essaie : Examples/iOSEchoDemo fait tourner Parakeet + Silero + Kokoro en boucle d’écho complète sur un iPhone ; le côté Android vit dans speech-android, qui enveloppe le même pipeline. (Examples/iOSBenchmark est l’outil derrière les chiffres iPhone ci-dessus.)
Un vrai LLM qui pilote la machine — toujours sous 4 Go.
Sur un Mac, la contrainte se relâche : mémoire unifiée partagée entre le CPU et un GPU Metal. Les mêmes quatre étapes, des modèles plus gros et surtout un vrai cerveau de conversation à la place d’un appeleur d’outils de 270M — et toute la boucle tient encore dans ~4 Go.
Le LLM est le cerveau, et c’est là que la taille du modèle cesse d’être optionnelle. Après tests, deux modèles ont gagné leur place : FunctionGemma 270M en mobile (assez pour émettre un appel d’outil, tout ce dont un agent de téléphone a besoin) et Gemma 4 E2B/E4B (4-bit MLX) sur le bureau (une vraie conversation multitour et un raisonnement qui tiennent, tout en restant léger). Le tentant entre-deux — un modèle de chat compact sous 1B — semble gratuit en empreinte mais vacille en vraie conversation multitour, donc il n’a pas été retenu. Le saut qui compte n’est pas 0,27B → 0,8B ; c’est des appels d’outils de FunctionGemma à la conversation de Gemma 4.
Le reste de la pile monte aussi d’un cran : sur le bureau, le léger Parakeet-EOU laisse place à Parakeet-TDT (multilingue complet), et le TTS reste partout sur Supertonic-3 — rapide, 44,1 kHz, stable. On saute exprès les modèles de TTS de clonage zero-shot plus lourds ; le clonage n’est pas assez fiable pour vivre dans un agent toujours actif.
| Étape | Mobile | Bureau (Mac / MLX) |
|---|---|---|
| VAD | Silero v6.2.1 | Silero v6.2.1 |
| STT | Parakeet-EOU (streaming) | Parakeet-TDT (multilingual) |
| LLM | FunctionGemma 270M | Gemma 4 E2B/E4B |
| TTS | Kokoro-82M / Supertonic-3 | Supertonic-3 |
| Resident set | iPhone ~1.2 GB · S23 ~1.5 GB | ~4 GB |
Ce parcours bureau, c’est ce que livre Runner Agent — une app macOS notariée qui exécute Mic → VAD → Parakeet-TDT → Gemma 4 → Supertonic TTS entièrement en local, un DMG de 47 Mo avec toute la boucle autour de ~4 Go sur Apple Silicon. Et parce que le cerveau émet des appels d’outils, Runner ne fait pas que répondre — il pilote la machine à la voix : ouvrir un navigateur et exécuter des opérations sur le DOM, ouvrir Telegram ou WhatsApp pour lire les messages entrants et taper des réponses, lancer et contrôler des apps — le tout depuis des commandes vocales, le tout en local. C’est la vraie raison pour laquelle le bureau veut Gemma 4 et pas un appeleur d’outils de 270M : agir sur la machine demande un vrai raisonnement, pas juste remplir des champs.
Un pipeline, ajusté au budget.
VAD → STT → LLM → TTS est identique partout. Tout l’intérêt est d’ajuster chaque étape à l’accélérateur et à la mémoire de l’appareil.
Batterie et chaleur choisissent les modèles. L’ANE rend iOS quasi gratuit côté CPU ; Android est aujourd’hui temps réel sur CPU, avec de la marge NPU à venir.
Toute la boucle tient dans ~4 Go, et ce budget achète le raisonnement de Gemma 4 qui pilote la machine à la voix, plus Parakeet-TDT multilingue.
L’audio et l’état de la conversation ne quittent jamais l’appareil — perception, raisonnement et synthèse tournent sur le métal devant toi.
À lire ensuite.
Les chiffres Mac, iPhone et Galaxy S23 derrière ce billet.
Le compagnon vocal local macOS qui pilote ta machine.
Compose VAD, STT, LLM et TTS en une boucle temps réel.
D’autres billets sur la voix sur l’appareil au fil de leur parution.
