Вы говорите вслух — ассистент отвечает голосом. Без подписки, без передачи данных в облако, без зависимости от серверов 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

Цепочка работает так:

  1. STT (Speech-to-Text) — микрофон захватывает аудио, Whisper переводит его в текст за ~0.5 секунды
  2. LLM — языковая модель обрабатывает запрос и генерирует ответ (~1–1.5 секунды)
  3. 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-tiny39M~1000×базовая~1 ГБ
whisper-base74M~700×удовлетворительная~1 ГБ
whisper-small244M~400×хорошая~2 ГБ
whisper-large-v31550M~40×отличная~6 ГБ
whisper-large-v3-turbo809M~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-фильтр обязателен
Параметр 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
⚠ Русский язык — критичный параметр
Для голосового ассистента на русском языке Qwen3 от Alibaba показывает лучшее качество среди локальных моделей. Llama 4 также хорош, но может иногда переключаться на английский в сложных запросах. Mistral в базовой версии с русским справляется слабо.

Подключение к 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"]
ℹ System prompt для голоса — особый случай
В системном промпте обязательно укажи, что ответ будет озвучен. Это заставит модель избегать markdown-разметки, списков с дефисами и ссылок — всё это плохо звучит через TTS. Просите “говорить естественно, как в разговоре”.

Компонент 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()
💡 Piper для русского языка
Для русского TTS используйте модель 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 Pro18–36 ГБ unified0.5–1 сек~₽200,000
CPU only (Ryzen 7)8–15 сек
⚠ Распределение VRAM
При одновременной загрузке faster-whisper (large-v3-turbo) + Qwen3:7b + Kokoro вам нужно минимум 8–9 ГБ VRAM. Если памяти не хватает, загружайте модели последовательно или используйте более лёгкие варианты: whisper-small + Mistral:7b + Piper.

Быстрый старт через 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, чтобы ассистент активировался по ключевому слову, а не по нажатию кнопки. Но это уже тема отдельного гайда.