Offline'owy asystent głosowy: Whisper + lokalny LLM + TTS

Autor: Jakub Rusinowski · Ostatnia aktualizacja: 12 lipca 2026

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ą

W tym przewodniku

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] → speaker

Każ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 requests

Wybór modelu to pokrętło między prędkością a dokładnością:

Model WhisperRozmiarPrędkość transkrypcjiKiedy stosować
tiny.en39 MBNatychmiast, nawet na CPUProste komendy
base.en74 MBNiemal natychmiastWłaściwy wybór domyślny
small.en244 MB~1 s na wypowiedź (GPU)Głośne pomieszczenia, akcenty
large-v31,5 GBWymaga prawdziwego GPUDokł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ąż szybki

Daj 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 Modelfile

Linijka 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.wav

Dostę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ć

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.

Powiązane poradniki

← Wszystkie przewodniki | Sprawdź zgodność GPU