Ollama avec synthèse vocale : faites parler votre modèle local, hors ligne
Ollama fait tourner des modèles de langage sur votre propre ordinateur, et son API de chat répond en texte. Pour entendre les réponses, il faut une étape de synthèse vocale, et si vous avez choisi Ollama pour la confidentialité, cette étape doit elle aussi tourner en local.
Ce guide l’ajoute avec le moteur gratuit SuperClonica : un court script Python envoie votre question à Ollama, lit la réponse au fil de l’eau et prononce chaque phrase dès qu’elle est complète, si bien que la voix démarre bien avant que le modèle ait fini d’écrire. Rien ne quitte votre ordinateur.
Installation
Installez Ollama, téléchargez un modèle et lancez-le, puis installez les deux paquets Python :
ollama pull llama3.2
pip install requests superclonica-cpu
Au premier lancement, le moteur télécharge le modèle Supertonic 3, environ 400 Mo ; ensuite il fonctionne hors ligne sur un processeur ordinaire, et une carte graphique NVIDIA ne fait que l’accélérer. Sous Linux, le script joue le son avec aplay d’alsa-utils.
Le script
Enregistrez-le sous ollama_voice.py et lancez-le. Tapez une question : la réponse s’affiche et se fait entendre en même temps, et la conversation garde son historique :
import json, os, re, subprocess, sys, tempfile
import requests
from superclonica import Superclonica
OLLAMA = "http://localhost:11434/api/chat"
MODEL = "llama3.2" # any model you pulled with ollama pull
VOICE = "F1" # M1..M5, F1..F5 or a voice file from the catalog
SENTENCE_END = re.compile(r"[.!?]\s+")
tts = Superclonica()
def play(path):
if sys.platform == "win32":
import winsound
winsound.PlaySound(path, winsound.SND_FILENAME)
elif sys.platform == "darwin":
subprocess.run(["afplay", path], check=True)
else:
subprocess.run(["aplay", "-q", path], check=True)
def say(sentence):
sentence = re.sub(r"[*#`_]", "", sentence).strip()
if sentence:
audio, _ = tts.synthesize(sentence, voice=VOICE, lang="en")
path = os.path.join(tempfile.gettempdir(), "ollama-say.wav")
tts.save(path, audio)
play(path)
history = []
while True:
history.append({"role": "user", "content": input("You: ")})
answer = buffer = ""
body = {"model": MODEL, "messages": history, "stream": True}
with requests.post(OLLAMA, json=body, stream=True, timeout=300) as response:
response.raise_for_status()
for line in response.iter_lines():
if not line:
continue
piece = json.loads(line).get("message", {}).get("content", "")
print(piece, end="", flush=True)
answer += piece
buffer += piece
while match := SENTENCE_END.search(buffer):
say(buffer[:match.end()])
buffer = buffer[match.end():]
say(buffer)
print()
history.append({"role": "assistant", "content": answer})Le script coupe le flux à la fin de chaque phrase et la lit pendant qu’Ollama continue d’écrire. Il retire les symboles Markdown comme les astérisques, que les modèles aiment utiliser et qui sonnent bizarrement à voix haute.
Pour que ça sonne juste
Demandez au modèle de parler, pas d’écrire : commencez l’historique par un message système comme « Réponds par de courtes phrases parlées, sans listes, tableaux ni mise en forme. » Mettez dans lang de say la langue de la conversation, par exemple "fr" ; le moteur parle 31 langues, mais pas encore le chinois. VOICE accepte l’une des dix voix de base, M1 à M5 et F1 à F5, ou le chemin d’un fichier de voix du catalogue SuperClonica, par exemple une voix d’assistant façon IA de cinéma.
Lui parler à voix haute
Pour parler au lieu de taper, placez une reconnaissance vocale locale devant le script, par exemple Whisper avec le paquet faster-whisper, et passez son texte là où le script appelle input. Tout l’assistant, oreilles, cerveau et voix, tourne alors sur votre machine.