Голосовой AI-ассистент: Whisper + LLM + TTS на своём сервере
Пошаговый гайд по сборке приватного голосового AI-ассистента из трёх компонентов: Whisper для распознавания речи, локальный LLM и TTS — без облаков.
Вы говорите вслух — ассистент отвечает голосом. Без подписки, без передачи данных в облако, без зависимости от серверов OpenAI или Google. Всё работает локально на вашем железе, со скоростью, которая ощущается как живой разговор.
Это не фантастика 2027 года. Это реальный стек, который собирают разработчики прямо сейчас: faster-whisper для распознавания речи, Ollama для запуска LLM, Kokoro или Piper для синтеза голоса. В этом гайде — архитектура, выбор компонентов, код и реальные цифры производительности.
Как устроен голосовой пайплайн
Система состоит из трёх последовательных компонентов. Каждый делает одно дело — и делает его хорошо.
graph LR
A[🎤 Микрофон] --> B[STT: faster-whisper]
B -->|текст| C[LLM: Ollama]
C -->|ответ| D[TTS: Kokoro / Piper]
D --> E[🔊 Динамик]
style A fill:#4a9eff,color:#fff
style B fill:#7c4dff,color:#fff
style C fill:#00c853,color:#fff
style D fill:#ff6d00,color:#fff
style E fill:#4a9eff,color:#fff
Цепочка работает так:
- STT (Speech-to-Text) — микрофон захватывает аудио, Whisper переводит его в текст за ~0.5 секунды
- LLM — языковая модель обрабатывает запрос и генерирует ответ (~1–1.5 секунды)
- TTS (Text-to-Speech) — движок синтезирует голос из текста (~0.3–0.5 секунды)
Итог: от конца вашей фразы до первого слова ответа — 1.5–3 секунды на среднем GPU. На Apple M3 Pro реальные тесты показывают sub-second latency для коротких запросов.
Ключевое преимущество локального стека — не только приватность, но и отсутствие сетевых задержек. Облачный API добавляет 200–800мс на каждый запрос ещё до начала обработки.
Компонент 1: распознавание речи (STT)
Какой Whisper выбрать
OpenAI выпустил несколько версий Whisper, и выбор модели критически влияет на скорость и качество.
| Модель | Параметры | Скорость (RTFx) | Точность | VRAM |
|---|---|---|---|---|
| whisper-tiny | 39M | ~1000× | базовая | ~1 ГБ |
| whisper-base | 74M | ~700× | удовлетворительная | ~1 ГБ |
| whisper-small | 244M | ~400× | хорошая | ~2 ГБ |
| whisper-large-v3 | 1550M | ~40× | отличная | ~6 ГБ |
| whisper-large-v3-turbo | 809M | ~216× | ≈ large-v2 | ~3 ГБ |
Рекомендация: large-v3-turbo — оптимальный баланс. OpenAI урезал decoder с 32 до 4 слоёв, получив ускорение в 6–8 раз при сопоставимой точности с large-v2.
faster-whisper вместо оригинала
Библиотека faster-whisper заменяет PyTorch-рантайм на CTranslate2 — C++ движок для трансформеров. Результат: в 4 раза быстрее оригинала при той же точности, и существенно меньше потребление памяти.
from faster_whisper import WhisperModel
# Загружаем модель один раз при старте
model = WhisperModel(
"large-v3-turbo",
device="cuda", # или "cpu", или "mps" (Apple Silicon)
compute_type="float16" # int8 для CPU, float16 для GPU
)
def transcribe(audio_path: str) -> str:
segments, info = model.transcribe(
audio_path,
language="ru", # явно указываем язык для скорости
beam_size=5,
vad_filter=True # фильтр тишины — важно для реального применения
)
return " ".join(segment.text for segment in segments)
vad_filter=True включает Voice Activity Detection — модель не будет обрабатывать тишину и фоновый шум. Без него на коротких паузах между словами Whisper может генерировать галлюцинации вроде “Спасибо за просмотр!” или музыкальных описаний.Компонент 2: языковая модель (LLM)
Ollama — проще не бывает
Ollama — стандарт де-факто для запуска LLM локально. Устанавливается одной командой, управляет моделями через CLI, предоставляет OpenAI-совместимый REST API.
# Установка (Linux/macOS)
curl -fsSL https://ollama.com/install.sh | sh
# Скачать и запустить модель
ollama pull llama4:scout # Llama 4 Scout — 17B MoE, ~8 ГБ VRAM
ollama pull qwen3:14b # Qwen3 14B — отличный русский язык
ollama pull gemma3:12b # Gemma 3 12B — сбалансированный вариант
Выбор модели под вашё железо
| Модель | VRAM | Русский | Скорость ответа | Рекомендуется для |
|---|---|---|---|---|
| Llama 4 Scout | ~8 ГБ | хороший | быстро | GTX 3080+ |
| Qwen3:14b | ~10 ГБ | отличный | средне | RTX 4070+ |
| Qwen3:7b | ~5 ГБ | хороший | быстро | GTX 1080 Ti+ |
| Gemma 3:12b | ~8 ГБ | хороший | средне | RTX 3080+ |
| Mistral:7b | ~5 ГБ | базовый | быстро | CPU / слабые GPU |
Подключение к Ollama через Python
import requests
OLLAMA_URL = "http://localhost:11434/api/generate"
def ask_llm(prompt: str, system: str = "") -> str:
payload = {
"model": "qwen3:7b",
"prompt": prompt,
"system": system or "Ты голосовой помощник. Отвечай кратко и по делу — твой ответ будет озвучен. Избегай списков, скобок и специальных символов.",
"stream": False,
"options": {
"temperature": 0.7,
"num_predict": 256 # ограничиваем длину для TTS
}
}
response = requests.post(OLLAMA_URL, json=payload)
return response.json()["response"]
Компонент 3: синтез речи (TTS)
Топ-3 движка для локального использования
Kokoro-82M — победитель по соотношению скорость/качество. 82 миллиона параметров, Apache 2.0 лицензия, 96× real-time на обычном GPU. Размер модели — около 82 МБ. Единственный минус: ограниченный набор голосов (21 вариант).
Piper TTS — лучший выбор для слабого железа. 75 МБ, 904 голоса на десятках языков, отлично работает даже на Raspberry Pi 4. Именно Piper используется в Home Assistant для локального голоса.
Coqui XTTS-v2 — если нужно клонирование голоса. Поддерживает 17 языков, способен воспроизвести голос из 6-секундного аудиофрагмента. Требует больше ресурсов, но качество звучания на уровне коммерческих решений.
# Пример с Kokoro (через kokoro-onnx)
from kokoro_onnx import Kokoro
import sounddevice as sd
kokoro = Kokoro("kokoro-v1.0.onnx", "voices.bin")
def speak(text: str, voice: str = "af_bella"):
samples, sample_rate = kokoro.create(
text,
voice=voice,
speed=1.0,
lang="en-us" # для русского: используйте Piper с ru-моделью
)
sd.play(samples, sample_rate)
sd.wait()
# Пример с Piper (через subprocess — самый простой способ)
import subprocess
import tempfile
import sounddevice as sd
import soundfile as sf
def speak_piper(text: str):
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
output_path = f.name
subprocess.run([
"piper",
"--model", "ru_RU-ruslan-medium.onnx",
"--output_file", output_path
], input=text.encode(), check=True)
data, samplerate = sf.read(output_path)
sd.play(data, samplerate)
sd.wait()
ru_RU-ruslan-medium или ru_RU-irina-medium из официального репозитория Piper. Скачать: piper --download-dir ./models ru_RU-ruslan-medium. Качество достаточное для продуктивного использования.Сборка: полный цикл за 50 строк
Собираем все три компонента в рабочий голосовой ассистент:
import sounddevice as sd
import soundfile as sf
import numpy as np
import tempfile
import time
from faster_whisper import WhisperModel
import requests
import subprocess
# --- Инициализация ---
stt_model = WhisperModel("large-v3-turbo", device="cuda", compute_type="float16")
SYSTEM_PROMPT = """Ты голосовой помощник Уча. Отвечай на русском языке кратко
и естественно — как в живом разговоре. Без списков и разметки."""
def record_audio(duration: int = 5, sample_rate: int = 16000) -> str:
"""Запись с микрофона в временный WAV-файл"""
print("🎤 Слушаю...")
audio = sd.rec(int(duration * sample_rate), samplerate=sample_rate,
channels=1, dtype="float32")
sd.wait()
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
sf.write(f.name, audio, sample_rate)
return f.name
def transcribe(audio_path: str) -> str:
segments, _ = stt_model.transcribe(
audio_path, language="ru", beam_size=5, vad_filter=True
)
return " ".join(s.text for s in segments).strip()
def ask_llm(text: str) -> str:
resp = requests.post("http://localhost:11434/api/generate", json={
"model": "qwen3:7b",
"prompt": text,
"system": SYSTEM_PROMPT,
"stream": False,
"options": {"temperature": 0.7, "num_predict": 200}
})
return resp.json()["response"]
def speak(text: str):
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
subprocess.run(["piper", "--model", "ru_RU-ruslan-medium.onnx",
"--output_file", f.name], input=text.encode(), check=True)
data, sr = sf.read(f.name)
sd.play(data, sr)
sd.wait()
# --- Основной цикл ---
print("Голосовой ассистент запущен. Ctrl+C для выхода.")
while True:
audio_path = record_audio(duration=5)
user_text = transcribe(audio_path)
if not user_text or len(user_text) < 3:
continue
print(f"Вы: {user_text}")
t0 = time.time()
response = ask_llm(user_text)
print(f"Ассистент: {response}")
print(f"⏱ Latency: {time.time() - t0:.2f}s")
speak(response)
Производительность и требования к железу
Минимальные конфигурации
| Конфигурация | VRAM | Полный latency | Стоимость |
|---|---|---|---|
| Слабый GPU (GTX 1070) | 8 ГБ | 4–6 сек | бюджетная |
| Средний GPU (RTX 3080) | 10 ГБ | 2–3 сек | ~₽40,000 |
| Мощный GPU (RTX 4090) | 24 ГБ | 0.8–1.5 сек | ~₽130,000 |
| Apple M3 Pro | 18–36 ГБ unified | 0.5–1 сек | ~₽200,000 |
| CPU only (Ryzen 7) | — | 8–15 сек | — |
Быстрый старт через Open WebUI + Docker
Если не хочется собирать пайплайн вручную, Open WebUI уже содержит встроенную голосовую функцию:
# Запуск с поддержкой Whisper
docker compose --profile whisper up -d
# Переменные окружения
STT_PROVIDER=whisper
TTS_ENGINE=piper
Это даёт полнофункциональный веб-интерфейс с голосовым вводом/выводом через браузер за 5 минут.
Заключение
Голосовой AI-ассистент, работающий полностью локально — это уже не экзотика. Стек faster-whisper + Ollama + Piper/Kokoro стабилен, активно поддерживается сообществом и достигает приемлемой latency даже на потребительском железе.
Главные выводы:
- STT:
faster-whisperс модельюlarge-v3-turbo— лучший выбор для большинства задач - LLM: Qwen3:7b или Llama 4 Scout через Ollama — хороший русский язык, умеренные требования
- TTS: Piper для русского голоса, Kokoro если нужна скорость на английском
- Минимальный порог входа: 8 ГБ VRAM для комфортной работы
Самое ценное в локальном стеке — контроль. Ваши разговоры с ассистентом не логируются, не обучают чужие модели и не зависят от условий использования сторонних сервисов.
Следующий шаг — добавить wake word detection через openWakeWord, чтобы ассистент активировался по ключевому слову, а не по нажатию кнопки. Но это уже тема отдельного гайда.
Источники
- https://www.blog.brightcoding.dev/2026/04/07/local-voice-ai-the-modern-developers-private-assistant
- https://dasroot.net/posts/2026/03/building-voice-enabled-ai-assistant-whisper-local-llm/
- https://dev.to/xadenai/building-a-local-voice-ai-stack-whisper-ollama-kokoro-tts-on-apple-silicon-eo0
- https://github.com/vndee/local-talking-llm
- https://www.insiderllm.com/guides/voice-chat-local-llms-whisper-tts/
- https://markaicode.com/build-local-voice-assistant-whisper-llama4/
- https://huggingface.co/openai/whisper-large-v3-turbo