NLP embarqué : confidentialité, vitesse et la frontière du navigateur
Quand un utilisateur s’adresse à un assistant virtuel, le chemin le plus rapide vers une réponse est celui qui ne quitte jamais l’appareil. Le NLP embarqué supprime l’aller-retour vers un serveur distant, réduisant la latence perçue de plusieurs centaines de millisecondes à presque zéro. Plus important encore, cela signifie que les mots qu’un utilisateur tape ou prononce sont traités localement et supprimés localement — ils ne sont jamais transmis, jamais enregistrés, et ne dépendent jamais de la politique de conservation des données d’un tiers. Pour les applications qui traitent des domaines sensibles comme la santé, la finance ou la productivité personnelle, il ne s’agit pas d’un avantage accessoire, mais d’une exigence fondamentale.
Faire tourner des modèles d’inférence dans le navigateur ou sur un appareil mobile est véritablement difficile. Le bac à sable du navigateur restreint l’accès aux fils d’exécution natifs, le calcul GPU est conditionné par WebGL ou l’API WebGPU encore en cours de maturation, et les budgets mémoire sont serrés. Sur mobile, on entre en concurrence avec le système d’exploitation, les processus en arrière-plan et la limitation thermique. Les bibliothèques NLP traditionnelles conçues pour Node.js ou Python côté serveur embarquent des dépendances transitives qui font exploser la taille des bundles au-delà de ce qu’une WebView mobile peut charger confortablement. Le défi d’ingénierie ne consiste pas seulement à faire fonctionner un modèle, mais à le faire tourner assez vite, assez petit et assez fiable pour que les utilisateurs n’en perçoivent jamais l’existence.
Le moteur NLP d’Actor.dev, @noondra/nlp, a été conçu dès le départ en tenant compte de ces contraintes. C’est un package TypeScript pur avec une seule dépendance à l’exécution (budoux, pour la segmentation des limites de mots en japonais). Aucun addon natif, aucun blob WASM récupéré depuis un CDN, aucune surface d’API Node.js — il fonctionne de manière identique dans V8, JavaScriptCore et Hermes. Le moteur gère la classification des intentions, l’extraction d’entités, le remplissage de slots et la gestion de l’état du dialogue entièrement en mémoire. Les poids du modèle sont sérialisés sous forme de structures JSON compactes, chargées une fois en mémoire pour toute la session, ce qui garantit des temps de première réponse déterministes quelles que soient les conditions réseau.
Le compromis honnête est précision contre taille. Un classifieur d’intentions basé sur les transformers surpassera un modèle TF-IDF à ingénierie de caractéristiques sur des entrées hors distribution, mais il implique aussi entre 50 et 200 Mo de poids à télécharger et à conserver en RAM, sans compromis possible. Pour la plupart des cas d’usage d’assistants conversationnels, la distribution des entrées utilisateur est bornée par le domaine couvert par l’assistant. Un modèle léger bien entraîné avec une bonne couverture de ce domaine surpasse un grand modèle généraliste qui dilapide sa capacité sur des sujets que l’utilisateur n’abordera jamais. L’approche d’Actor.dev mise sur cela : les projets NLP sont entraînés par agent, les modèles résultants sont petits et spécialisés, et la précision sur les entrées du domaine est compétitive avec des architectures bien plus grandes. Quand une requête tombe réellement en dessous du seuil de confiance du modèle, le runtime cède gracieusement la main à un LLM de secours — maintenant le chemin rapide tout en préservant la qualité là où cela compte.