W pełni offline'owy asystent głosowy potrzebuje trzech lokalnych elementów: Whispera do zamiany mowy na tekst, lokalnego LLM-a w Ollama jako mózgu oraz Pipera do syntezy mowy. Wszystkie trzy działają na jednej niewygórowanej maszynie, nic z tego, co powiesz, nie opuszcza pokoju, a ten poradnik łączy je w działającego asystenta typu push-to-talk w niecałą godzinę.
Ostatnia aktualizacja: lipiec 2026
Architektura (i czego się spodziewać)
Your voice → [Whisper STT] → text → [Local LLM] → reply text → [Piper TTS] → speakerKażdy etap to dojrzały projekt open-source; praca polega na hydraulice, a nie na badaniach. Ustawmy oczekiwania uczciwie: na GPU 8 GB albo Macu z układem serii M od końca wypowiedzi do początku odpowiedzi minie mniej więcej 1,5–3 sekundy. To wolniej niż gotowe formułki Alexy, ale mądrzej — i działa przy odłączonym internecie, czym nie może pochwalić się żaden komercyjny asystent.
Minimum sprzętowe: każda maszyna, która wygodnie uruchamia model 7–8B (8 GB VRAM albo Mac z Apple Silicon i 16 GB pamięci), udźwignie cały stos — sprawdź swoją w analizatorze sprzętu.
Krok 1 — Lokalna zamiana mowy na tekst z faster-whisper
faster-whisper to praktyczna implementacja Whispera — ta sama dokładność co w oryginale od OpenAI, kilka razy szybciej:
pip install faster-whisper sounddevice numpy requestsWybór modelu to pokrętło między prędkością a dokładnością:
| Model Whisper | Rozmiar | Prędkość transkrypcji | Kiedy stosować |
|---|---|---|---|
| tiny.en | 39 MB | Natychmiast, nawet na CPU | Proste komendy |
| base.en | 74 MB | Niemal natychmiast | Właściwy wybór domyślny |
| small.en | 244 MB | ~1 s na wypowiedź (GPU) | Głośne pomieszczenia, akcenty |
| large-v3 | 1,5 GB | Wymaga prawdziwego GPU | Dokładność na poziomie dyktowania |
base.en transkrybuje pięciosekundową wypowiedź w znacznie mniej niż sekundę na czymkolwiek nowoczesnym. (Jeśli wypowiadasz tylko komendy, tiny.en naprawdę wystarczy).
Krok 2 — Mózg: szybki mały model w Ollama
Jeśli budujesz to na Macu i sięgasz po MLX dla szybkości, najpierw zrób test natywnego Pythona — interpreter x86 pod Rosettą to zwykły powód, dla którego MLX nie chce się zainstalować.
Interakcja głosowa jest wrażliwa na opóźnienia — żwawy model 3–8B bije mądrzejszy model, który każe Ci czekać:
ollama pull llama3.2:3b # najszybsze dobre odpowiedzi
ollama pull llama3.1:8b # mądrzejszy, na GPU wciąż szybkiDaj mu prompt systemowy dopasowany do głosu (odpowiedzi wypowiadane na głos muszą być krótkie — zobacz Prompty systemowe od podstaw):
FROM llama3.2:3b
SYSTEM You are a voice assistant. Answer in 1-3 short conversational sentences. Never use markdown, lists, or code blocks - your output is spoken aloud.ollama create voice -f ModelfileLinijka o zakazie markdownu ma znaczenie: nic tak nie psuje wypowiadanej odpowiedzi, jak silnik TTS czytający na głos „gwiazdka gwiazdka”.
Krok 3 — Lokalna synteza mowy z Piperem
Piper generuje naturalną mowę szybciej niż w czasie rzeczywistym na Raspberry Pi, a co dopiero na Twoim komputerze:
pip install piper-tts
# Pobierz głos (jeden plik .onnx + jeden .json)
python -m piper.download_voices en_US-lessac-medium
# Przetestuj go
echo "The assistant is alive." | piper -m en_US-lessac-medium -f test.wavDostępne są dziesiątki głosów i języków; warianty -medium to złoty środek między jakością a prędkością. Alternatywy: Coqui XTTS brzmi bardziej naturalnie, ale jest 10× wolniejszy; wbudowane w macOS polecenie say to opcja awaryjna bez żadnej instalacji.
Krok 4 — Połącz wszystko: pętla push-to-talk
Zapisz jako assistant.py — naciskasz Enter, mówisz, dostajesz wypowiedzianą odpowiedź:
import sounddevice as sd
import numpy as np
import requests, subprocess, tempfile, wave
from faster_whisper import WhisperModel
stt = WhisperModel("base.en", compute_type="int8")
SAMPLE_RATE = 16000
def record(seconds=5):
print("Listening...")
audio = sd.rec(int(seconds * SAMPLE_RATE), samplerate=SAMPLE_RATE,
channels=1, dtype="int16")
sd.wait()
return audio
def transcribe(audio):
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
with wave.open(f.name, "wb") as w:
w.setnchannels(1); w.setsampwidth(2); w.setframerate(SAMPLE_RATE)
w.writeframes(audio.tobytes())
segments, _ = stt.transcribe(f.name)
return " ".join(s.text for s in segments).strip()
def ask_llm(prompt):
r = requests.post("http://localhost:11434/api/chat", json={
"model": "voice", "stream": False,
"messages": [{"role": "user", "content": prompt}],
})
return r.json()["message"]["content"]
def speak(text):
subprocess.run(["piper", "-m", "en_US-lessac-medium", "-f", "reply.wav"],
input=text.encode())
subprocess.run(["aplay", "reply.wav"]) # macOS: use "afplay"
while True:
input("Press Enter to talk...")
heard = transcribe(record())
if not heard:
continue
print(f"You: {heard}")
reply = ask_llm(heard)
print(f"Assistant: {reply}")
speak(reply)Uruchom python assistant.py, naciśnij Enter i o coś zapytaj. Każdy bajt — dźwięk, transkrypcja, odpowiedź — został na Twojej maszynie.
Jak to ulepszyć
- Słowo aktywujące bez użycia rąk: openWakeWord albo Picovoice Porcupine zastępuje klawisz Enter aktywacją w stylu „hej, komputer”, w pełni offline.
- Zatrzymaj nagrywanie, gdy przestaniesz mówić: zamień stałe okno 5 sekund na wykrywanie aktywności głosowej (
silero-vad, jedna instalacja przez pip). - Zmniejsz odczuwalne opóźnienie strumieniowaniem: ustaw
"stream": truew wywołaniu Ollama i przekazuj zdania do Pipera w miarę ich kończenia — asystent zaczyna mówić, jeszcze zanim skończy myśleć. - Daj mu pamięć: przechowuj tablicę wiadomości między turami, żeby działały pytania uzupełniające („…a jak wysoka ona jest?”).
- Wystaw to do sieci: uruchom LLM na swoim domowym serwerze, a pętlę mikrofon–głośnik na Raspberry Pi w innym pokoju.
Najczęściej zadawane pytania
Czy to zadziała na Raspberry Pi?
Części odpowiedzialne za STT i TTS tak — bez trudu. Wąskim gardłem jest LLM: Pi 5 wyciąga ~2–4 t/s na modelu 3B, co w mowie brzmi ospale. Standardowy schemat to Pi jako satelita z mikrofonem i głośnikiem oraz Ollama na prawdziwej maszynie w sieci LAN (zobacz Uruchamianie na laptopach i Raspberry Pi).
Czym to się różni od potoku głosowego w Home Assistant?
Stos Assist w Home Assistant używa pod spodem tych samych komponentów (Whisper + Piper przez protokół Wyoming), ale celuje w komendy inteligentnego domu. Pętla z tego poradnika to minimalna, ogólnego przeznaczenia wersja, którą w pełni kontrolujesz — i lepszy punkt wyjścia, by zrozumieć, co Home Assistant automatyzuje za Ciebie.
Ile miejsca na dysku i VRAM to wszystko zajmuje?
Mniej więcej: Whisper base.en 74 MB, głos Pipera ~60 MB, Llama 3.2 3B ~2 GB / Llama 3.1 8B ~4,9 GB na dysku. W czasie działania zestaw z modelem 8B chce ~6 GB VRAM lub pamięci zunifikowanej, a Whisper spokojnie dzieli je z nim.
Czy działa w językach innych niż angielski?
Tak — użyj wielojęzycznego modelu Whisper (pomiń przyrostek .en), głosu Pipera dla swojego języka i wielojęzycznego LLM-a (Qwen 2.5 i Gemma 3 to mocne wybory). Wszystkie trzy etapy obsługują offline dziesiątki języków.