GUÍA

Ollama con texto a voz: que tu modelo local hable, sin conexión

Ollama ejecuta modelos de lenguaje en tu propio equipo, y su API de chat responde con texto. Para oír las respuestas hace falta un paso de texto a voz, y si elegiste Ollama por privacidad, ese paso también debería funcionar en local.

Esta guía lo añade con el motor gratuito de SuperClonica: un breve script de Python envía tu pregunta a Ollama, lee la respuesta a medida que llega y dice cada frase en cuanto está completa, así que la voz empieza mucho antes de que el modelo termine de escribir. Nada sale de tu equipo.

Instalación

Instala Ollama, descarga un modelo y arráncalo; después instala los dos paquetes de Python:

ollama pull llama3.2

pip install requests superclonica-cpu

En el primer arranque el motor descarga el modelo Supertonic 3, unos 400 MB; después funciona sin conexión en una CPU normal, y una tarjeta gráfica NVIDIA solo lo acelera. En Linux el script reproduce el sonido con aplay de alsa-utils.

El script

Guárdalo como ollama_voice.py y ejecútalo. Escribe una pregunta; la respuesta se muestra y se oye a la vez, y la conversación conserva su historial:

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})

El script corta el flujo al final de cada frase y la convierte en voz mientras Ollama sigue escribiendo. Quita los símbolos de Markdown, como los asteriscos, que a los modelos les gusta usar y que suenan raros en voz alta.

Que suene bien

Pide al modelo que hable, no que escriba: empieza el historial con un mensaje de sistema como «Responde con frases habladas cortas, sin listas, tablas ni formato». Pon en lang de say el idioma de la conversación, por ejemplo "es"; el motor habla 31 idiomas, pero todavía no chino. VOICE admite una de las diez voces de serie, M1 a M5 y F1 a F5, o la ruta de un archivo de voz del catálogo de SuperClonica, por ejemplo una voz de asistente al estilo de una IA de película.

Háblale con la voz

Para hablar en lugar de escribir, pon un reconocedor de voz local delante del script, por ejemplo Whisper con el paquete faster-whisper, y pasa su texto donde el script llama a input. Así todo el asistente, oídos, cerebro y voz, funciona en tu propio equipo.