Assistant vocal temps réel
Source: 11_realtime_voice_assistant
Un assistant vocal qui transcrit l’audio du microphone avec Whisper local et envoie chaque segment à un modèle de langage pour obtenir une réponse. Deux points d’entrée permettent de choisir entre un LLM distant (tokens en streaming) ou un Mistral 7B entièrement local (pas de clé d’API).
Exécution
Avec un LLM distant (GPT-4o) :
melodium run 11_realtime_voice_assistant/Compo.toml --openai_key sk-...Entièrement local (pas de clé d’API, nécessite ~14 Go de RAM) :
melodium run 11_realtime_voice_assistant/Compo.toml localonly[…] info: assistant: ready — speak into the microphone
[…] info: you: What time is it in Tokyo?
[…] info: assistant: Tokyo est en heure standard du Japon (JST), soit UTC+9…Fonctionnement
Les deux points d’entrée partagent la même séquence de chargement Whisper. La différence réside uniquement dans le backend LLM utilisé en aval.
main — Whisper local + LLM distant
See in Compositeur Studio
Chaque segment transcrit est transmis en fan-out à deux consommateurs simultanément :
asrDecode.transcribed -> logQuestion.messages
asrDecode.transcribed -> remoteAnswer.questionremoteAnswer utilise llmStream qui émet les tokens un par un en tant que Stream<string>, affichés dans le journal en temps réel sans attendre la réponse complète.
localonly — Whisper local + Mistral local
See in Compositeur Studio
Le point d’entrée localOnly charge Mistral 7B en parallèle avec Whisper. Son sous-traitement localAnswer utilise generate au lieu de llmStream, mais expose la même interface de sortie Stream<string> — la logique de fan-out et de journalisation dans le point d’entrée est inchangée.
Interface partagée, backends différents
remoteAnswer et localAnswer acceptent tous deux Stream<string> et émettent Stream<string>. Le point d’entrée ne sait pas et n’a pas besoin de savoir lequel il appelle — changer de backend est purement une préoccupation au niveau du modèle.
Dépendances
[dependencies]
std = "0.10.1" # flux de base, journalisation, structures de données
audio = "0.10.1" # décodage / encodage / rééchantillonnage audio
record = "0.10.1" # capture microphone
ml = "0.10.1" # inférence LLM, STT, TTS et modèles locaux