Transcription en streaming sur votre CPU : intégrer NVIDIA Nemotron à une application de bureau
Comment OpenWhispr affiche le texte pendant que vous parlez — grâce à un modèle en streaming avec cache sur un WebSocket local, sans GPU ni cloud — et le travail nécessaire pour rendre l’ensemble fiable.
OpenWhispr
Ingénierie
Table des matières
La transcription en streaming traite l’audio pendant que vous parlez, sans attendre la fin de l’enregistrement. Depuis la version 1.7.6, OpenWhispr le fait entièrement sur l’appareil : les modèles Nemotron en streaming de NVIDIA (600M paramètres, quantifiés en INT8) s’exécutent sur votre CPU via un serveur WebSocket sherpa-onnx local ; l’aperçu de dictée évolue avec les résultats partiels et, dès que vous arrêtez, le texte du flux est validé comme transcription. Pas de GPU, pas d’environnement Python, aucun audio envoyé hors de votre machine.
Voici le compte rendu technique : pourquoi notre ancien aperçu semblait lent, ce que signifie concrètement le streaming avec cache, comment le pipeline s’insère dans une application Electron, le défaut d’épinglage de version qui faussait tout le décodage et comment nous sommes passés du redécodage de chaque enregistrement à la validation du flux lui-même. Pour la comparaison entre modèles, consultez Parakeet vs Whisper vs Nemotron.
Dernière mise à jour le 18 juillet 2026. Les détails d’implémentation concernent la transcription en streaming livrée dans OpenWhispr 1.7.6 ; tout ce qui est décrit ici peut être vérifié dans le dépôt open source.
Vérification rapide (sources primaires)
- Le FastConformer avec cache de Nemotron ne traite que le nouvel audio et réutilise le contexte de l’encodeur mis en cache, avec des segments configurables à l’exécution de 80ms à 1.12s. Fiche du modèle Nemotron Streaming EN · NVIDIA sur le streaming avec cache
- Le modèle anglais atteint en moyenne 6.93% WER en streaming avec des segments de 1.12s ; le modèle multilingue 3.5 couvre 40 combinaisons langue-région avec détection automatique. Fiche du modèle Nemotron 3.5 ASR
- Toute l’inférence passe par sherpa-onnx, un runtime ONNX natif sans dépendance à Python, au moyen de son serveur WebSocket online (streaming). Nous épinglons et intégrons la version 1.13.4. sherpa-onnx sur GitHub
- Les modèles occupent 632MB (anglais) et 650MB (multilingue) sur disque au format ONNX INT8, sont téléchargés une seule fois et conservés dans le cache local. Registre des modèles OpenWhispr (open source) · Page des modèles OpenWhispr
Le problème : un aperçu en direct construit sur un modèle par lots
OpenWhispr a toujours proposé un aperçu de la transcription : une petite fenêtre qui montre ce que le modèle a entendu pendant la dictée. Avant 1.7.6, il suivait la seule méthode permettant de donner une impression de direct avec un modèle par lots : mettre en mémoire environ 1.5 seconde d’audio du micro, transcrire entièrement ce segment, ajouter le texte, puis recommencer.
Cette approche souffre de trois problèmes structurels. D’abord la latence : les mots ne peuvent apparaître avant que le tampon soit rempli, si bien que l’aperçu accuse toujours une seconde et demie de retard, plus le temps d’inférence. Ensuite les limites : un mot à cheval sur deux segments est coupé et aucun ne peut le corriger, puisqu’ils sont transcrits séparément. Enfin le contexte : le cinquième segment ignore le quatrième et le modèle doit résoudre à nouveau les mêmes ambiguïtés toutes les 1.5 secondes.
Réduire les segments accélère l’affichage, mais fait chuter la précision : moins de contexte et davantage de coupures. Les faire se chevaucher corrige les limites, mais transcrit deux fois le même audio. Il faut en réalité un modèle entraîné à transcrire un flux. C’est précisément le rôle de Nemotron.
Ce que signifie vraiment le streaming avec cache
Un modèle en streaming avec cache conserve son état interne entre les segments. À l’arrivée de la portion audio suivante, l’encodeur ne relit pas tout ce qui précède : il traite uniquement les nouvelles trames en consultant le contexte déjà calculé et mis en cache. C’est le principe qui accélère les chatbots (cache KV), appliqué à un encodeur vocal.
Deux conséquences en découlent. Le calcul ne croît plus avec la durée de l’enregistrement : chaque segment coûte autant après dix secondes qu’après dix minutes, ce qui rend viable le streaming uniquement sur CPU. Et le contexte se propage : le modèle utilise tout ce qui a été dit pour lever une ambiguïté et révise des mots antérieurs quand la suite apporte de meilleurs indices. Voilà pourquoi le texte se « stabilise » un instant après la parole : ce n’est pas un bug, mais une décision corrigée à partir de meilleures informations.
Le budget de latence est réglable : Nemotron propose des segments de 80ms (le plus rapide, avec moins de contexte par étape) à 1.12s (la meilleure précision : 6.93% WER moyen sur les jeux du leaderboard, à environ un point des meilleurs modèles par lots). L’entraînement repose sur le FastConformer avec cache de NVIDIA et un décodeur transducteur ; leur article technique détaille la théorie.
L’architecture au cœur d’OpenWhispr
Le parcours de streaming en direct dans OpenWhispr
- •One persistent stream for the whole recording — the encoder cache carries context across chunks.
- •Everything is on-device: the WebSocket server is a local sherpa-onnx binary, not a cloud endpoint.
- •A clean flush at stop commits the streamed text as the final transcript; anything less falls back to a full re-decode.
Le pipeline est volontairement banal. Un AudioWorklet capture le PCM du micro à 16kHz. Les trames sont converties au format float32 puis envoyées par WebSocket à un serveur online sherpa-onnx : un binaire natif lancé localement par OpenWhispr et joint sur 127.0.0.1, avec une connexion persistante par enregistrement. Le serveur exécute Nemotron avec des poids INT8 et renvoie des résultats partiels JSON ; l’aperçu remplace son texte au lieu de l’ajouter.
Pourquoi un processus serveur séparé plutôt qu’une inférence intégrée ? Pour l’isolation. Les runtimes natifs peuvent planter ; une mauvaise allocation dans un noyau ONNX ne doit pas fermer toute l’application. Avec un processus auxiliaire, un crash entraîne une reconnexion, pas la perte de la dictée. Le code natif reste aussi entièrement hors du processus principal d’Electron : l’application parle le protocole, l’auxiliaire calcule.
Le même schéma alimente notre diarisation locale des locuteurs — une chaîne sherpa-onnx, plusieurs tâches, le tout sur l’appareil.
Ce qui a cassé en chemin
La version du runtime comptait plus que prévu. Les modèles Nemotron exigent sherpa-onnx 1.13.4 ou une version ultérieure pour décoder correctement. Avec l’ancien runtime intégré pour Parakeet, ils n’échouaient pas franchement : ils transcrivaient mal. La correction était ordinaire — mettre à niveau puis réépingler les binaires de chaque plateforme — mais la leçon est générale : pour un runtime de modèle, « ça tourne » et « le résultat est correct » sont deux tests distincts, et seul le second compte.
Les flux échouent, nous avons donc conservé l’ancienne voie. Un port peut être occupé, un fichier de modèle absent ou un serveur s’arrêter en cours d’enregistrement. Si le flux persistant ne démarre pas, l’aperçu revient automatiquement aux segments en mémoire tampon : plus lent, mais jamais vide. Les modèles offline (Parakeet, Whisper) gardent ce mode par conception ; chaque modèle du registre déclare son runtime online ou offline, et l’application choisit la bonne voie.
Les résultats partiels demandaient un rendu différent. La voie par segments ajoute le texte ; une hypothèse en streaming se corrige, l’interface remplace donc tout l’aperçu à chaque résultat partiel. Ajouter une hypothèse qui se révise produit des doublons saccadés : la version en une phrase d’un vrai défaut d’UX corrigé très tôt.
Valider le flux : de deux passes à une
Notre première version considérait le streaming comme un aperçu, pas comme le résultat : à la fin de la dictée, l’application redécodait tout l’enregistrement depuis zéro et collait ce nouveau texte. C’était sûr — la passe finale disposait de tout le contexte — mais chaque dictée payait deux décodages et, après avoir vu le texte se stabiliser, il fallait attendre un second avis presque toujours identique.
Dans la même version, nous avons donc fait du flux la source de vérité. La dictée utilise la connexion persistante même si la fenêtre d’aperçu est fermée et, à l’arrêt, l’application vide la fin du modèle puis valide directement le texte du flux, sans second décodage. La latence finale se réduit à cette vidange et le coût CPU par dictée est à peu près divisé par deux.
Le filet de sécurité n’a pas disparu : il est devenu la solution de repli. La vidange finale détecte les troncatures et prolonge son délai tant que des résultats arrivent. Au moindre problème — connexion perdue ou résultat tronqué —, l’application abandonne le flux et exécute le traitement classique consistant à enregistrer puis transcrire tout l’audio. La voie rapide n’est utilisée que lorsqu’elle est aussi correcte.
Performances et empreinte
- Modèles : Nemotron Speech Streaming EN 0.6B (632MB) et Nemotron 3.5 ASR Streaming 0.6B (650MB, 15 langues prêtes pour la transcription, détection automatique) — ONNX INT8, téléchargés une fois et mis en cache localement.
- Runtime : sherpa-onnx 1.13.4, un binaire natif autonome. Aucun besoin de Python, PyTorch ou CUDA.
- Matériel : streaming en temps réel sur le CPU d’un ordinateur portable moderne ; Apple Silicon comme les x86 récents suivent aisément le rythme de la parole.
- Ressenti : le texte partiel arrive bien moins d’une seconde après la voix ; à l’arrêt, une seule vidange valide la transcription, sans second décodage.
Cette voie ne touche jamais Internet. L’application communique avec le serveur sur 127.0.0.1 (sous Windows, une règle de pare-feu limitée ferme également le port au réseau), les modèles restent dans le cache local et l’audio ne quitte jamais la machine : la même protection que le reste de notre pile de transcription locale.
Les limites, sans détour
- Le streaming échange un peu de précision contre l’immédiateté. ~6.9% en streaming contre 5.91% pour le meilleur modèle anglais par lots de NVIDIA sur les mêmes benchmarks. Puisque la transcription validée vient désormais du flux, c’est le compromis accepté. Si seul le résultat final compte, un modèle Parakeet offline reste le meilleur choix pour la précision.
- La couverture linguistique est plus étroite que celle de Whisper. 15 langues prêtes pour la transcription dans le modèle multilingue, contre 99 pour Whisper. Le streaming en mandarin ou en thaï n’est pas encore disponible.
- Le texte partiel évolue. L’hypothèse se révise avec le contexte. Voir le texte se stabiliser nous semble utile ; si cela vous distrait, désactivez l’aperçu et la dictée fonctionnera exactement comme avant.
- Cela ajoute 650MB sur le disque si vous possédez déjà un modèle offline : le coût d’un second moteur optimisé pour une autre tâche.
Choisir un modèle dans OpenWhispr
| Votre besoin | Choix |
|---|---|
| Aperçu en direct en anglais pendant la dictée | Nemotron Speech Streaming EN 0.6B |
| Aperçu en direct en espagnol, japonais, arabe, hindi… | Nemotron 3.5 ASR Streaming 0.6B |
| Précision maximale en anglais, sans besoin de texte en direct | Parakeet Unified EN 0.6B |
| Une langue hors de l’ensemble NVIDIA | Whisper (turbo ou large) |
Tous sont accessibles dans une liste des Réglages ; le catalogue complet, avec tailles et compromis, figure sur la page des modèles. OpenWhispr est gratuit, open source et disponible sur macOS, Windows et Linux.
Questions fréquentes
Qu’est-ce que la transcription vocale en streaming ?
La transcription en streaming (ou « online ») traite l’audio pendant que la personne parle encore et produit des résultats partiels dans un budget de latence fixe, généralement de 80 millisecondes à environ une seconde. Les modèles par lots (« offline ») comme Whisper attendent la fin de l’enregistrement avant de tout traiter. Le streaming rend possibles les sous-titres en direct, les agents vocaux et l’aperçu de dictée qui s’affiche à mesure que vous parlez.
Puis-je exécuter une transcription en streaming localement, sans GPU ?
Oui. Les modèles Nemotron en streaming de NVIDIA comptent 600M paramètres, sont fournis sous forme de fichiers ONNX quantifiés en INT8 d’environ 650MB et tournent en temps réel sur un CPU moderne via sherpa-onnx, un binaire natif qui n’exige ni Python ni PyTorch. OpenWhispr fournit cette configuration sur macOS, Windows et Linux.
Qu’est-ce que l’ASR en streaming avec cache ?
C’est une architecture — le FastConformer avec cache de NVIDIA — dans laquelle le modèle conserve l’état interne de son encodeur entre les segments audio. Chaque nouveau segment n’est traité qu’une fois, à partir du contexte déjà mis en cache, au lieu de réencoder des fenêtres audio qui se chevauchent. Le streaming à faible latence devient ainsi assez léger pour un CPU d’ordinateur portable.
Pourquoi le texte de l’aperçu change-t-il après son apparition ?
Les modèles en streaming révisent leur hypothèse à mesure que l’audio arrive : seul le contexte ultérieur permet parfois de trancher une limite de mot ou un homophone, donc les résultats partiels sont remplacés sur place. C’est voulu. Lorsque vous arrêtez, OpenWhispr vide la fin du modèle et valide le texte stabilisé comme transcription ; si cette opération est interrompue ou tronquée, l’application redécode automatiquement l’enregistrement complet. Un flux instable ne devient donc jamais le texte collé.
La transcription en streaming est-elle moins précise que le traitement par lots ?
Légèrement, et pour une raison simple : un modèle en streaming ne connaît pas l’audio à venir. Le modèle anglais en streaming de Nemotron affiche en moyenne 6.93% de taux d’erreur par mot avec des segments de 1.12 seconde sur les jeux de données de l’Open ASR Leaderboard. Il se rapproche fortement des modèles par lots, tout en restant derrière les 5.91% du meilleur modèle anglais par lots de NVIDIA. Le streaming échange ce petit écart contre du texte en direct et une transcription immédiate à l’arrêt ; si la précision maximale prime, choisissez plutôt un modèle Parakeet offline.
Quelles langues le streaming prend-il en charge dans OpenWhispr ?
Deux modèles Nemotron sont proposés : un modèle réservé à l’anglais et Nemotron 3.5, avec 15 langues prêtes pour la transcription (anglais, espagnol, français, italien, portugais, néerlandais, allemand, turc, russe, arabe, hindi, japonais, coréen, vietnamien et ukrainien) et détection automatique. Les modèles offline comme Parakeet et Whisper couvrent davantage de langues, mais leur aperçu repose sur des segments mis en mémoire tampon plutôt que sur un flux en direct.