Ollama com texto para fala: faça seu modelo local falar, totalmente offline
O Ollama roda modelos de linguagem no seu próprio computador, e a API de chat dele responde em texto. Para ouvir as respostas você precisa de uma etapa de texto para fala, e se escolheu o Ollama pela privacidade, essa etapa também deve rodar localmente.
Este guia adiciona essa etapa com o motor gratuito da SuperClonica: um script curto em Python envia sua pergunta ao Ollama, lê a resposta conforme ela chega e fala cada frase assim que fica completa, então a voz começa bem antes de o modelo terminar de escrever. Nada sai do seu computador.
Instalação
Instale o Ollama, baixe um modelo e inicie-o; depois instale os dois pacotes de Python:
ollama pull llama3.2
pip install requests superclonica-cpu
Na primeira execução o motor baixa o modelo Supertonic 3, cerca de 400 MB; depois roda offline num processador comum, e uma placa de vídeo NVIDIA só acelera. No Linux o script toca o som com aplay do alsa-utils.
O script
Salve como ollama_voice.py e rode. Digite uma pergunta; a resposta aparece e é falada ao mesmo tempo, e a conversa guarda o histórico:
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})O script corta o fluxo no fim de cada frase e a fala enquanto o Ollama continua escrevendo. Ele remove símbolos de Markdown como asteriscos, que os modelos adoram usar e que soam estranhos em voz alta.
Para soar certo
Peça ao modelo que fale, não que escreva: comece o histórico com uma mensagem de sistema como «Responda em frases faladas curtas, sem listas, tabelas ou formatação». Ponha em lang de say o idioma da conversa, por exemplo "pt"; o motor fala 31 idiomas, mas ainda não chinês. VOICE aceita uma das dez vozes padrão, M1 a M5 e F1 a F5, ou o caminho de um arquivo de voz do catálogo da SuperClonica, por exemplo uma voz de assistente no estilo de uma IA de filme.
Fale com ele pela voz
Para falar em vez de digitar, coloque um reconhecedor de fala local na frente do script, por exemplo o Whisper pelo pacote faster-whisper, e passe o texto dele onde o script chama input. Assim o assistente inteiro, ouvidos, cérebro e voz, roda na sua máquina.