Ollama 텍스트 음성 변환: 로컬 모델이 완전히 오프라인으로 말하게
Ollama는 내 컴퓨터에서 언어 모델을 돌리고, 채팅 API는 텍스트로 답합니다. 답을 들으려면 음성 변환 단계가 필요하며, 개인 정보 때문에 Ollama를 골랐다면 그 단계도 로컬에서 돌아야 합니다.
이 가이드는 무료 SuperClonica 엔진으로 그 단계를 더합니다. 짧은 Python 스크립트가 질문을 Ollama에 보내고, 스트리밍으로 오는 답을 읽다가 문장이 완성될 때마다 바로 읽어 줍니다. 그래서 모델이 다 쓰기 훨씬 전에 목소리가 시작됩니다. 아무것도 내 컴퓨터 밖으로 나가지 않습니다.
설치
Ollama를 설치하고 모델을 받아 실행한 다음, Python 패키지 두 개를 설치하세요:
ollama pull llama3.2
pip install requests superclonica-cpu
엔진은 처음 실행할 때 Supertonic 3 모델(약 400 MB)을 내려받고, 그다음부터는 일반 CPU에서 오프라인으로 돌아갑니다. NVIDIA 그래픽카드는 속도만 높여 줍니다. Linux에서는 alsa-utils의 aplay로 소리를 재생합니다.
스크립트
ollama_voice.py로 저장하고 실행하세요. 질문을 입력하면 답이 화면에 나오면서 동시에 읽히고, 대화 기록도 유지됩니다:
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})스크립트는 스트림을 문장 끝에서 잘라, Ollama가 계속 쓰는 동안 그 문장을 읽습니다. 모델이 즐겨 쓰지만 소리 내어 읽으면 어색한 별표 같은 Markdown 기호는 지웁니다.
자연스럽게 들리게
모델에게 글이 아니라 말을 하라고 요청하세요. 기록 맨 앞에 "목록, 표, 서식 없이 짧은 구어체 문장으로 답해" 같은 시스템 메시지를 넣습니다. say의 lang에는 대화 언어(한국어는 "ko")를 지정하세요. 엔진은 31개 언어를 말하지만 중국어는 아직 지원하지 않습니다. VOICE에는 기본 목소리 10개(M1~M5, F1~F5) 중 하나나 SuperClonica 카탈로그의 목소리 파일 경로를 넣습니다. 영화 속 AI 같은 어시스턴트 목소리도 있습니다.
목소리로 말 걸기
타이핑 대신 말하려면 스크립트 앞에 로컬 음성 인식(예: faster-whisper 패키지의 Whisper)을 두고, 그 텍스트를 스크립트가 input을 부르는 곳에 넘기세요. 그러면 귀, 두뇌, 목소리까지 어시스턴트 전체가 내 컴퓨터에서 돌아갑니다.