Голосовой AI в реальном времени: Gemma 4, Cerebras, Hugging Face — гайд | AiManual
AiManual Logo Ai / Manual.
05 Июл 2026 Гайд

Создаем реалтаймовый голосовой AI с Hugging Face, Cerebras и Gemma 4: открытый пайплайн

Соберите speech-to-speech пайплайн с задержкой менее 300 мс: Gemma 4 на Cerebras, Qwen TTS на Hugging Face, WebSocket. Открытый код, низкая задержка, модульност

Почему Cerebras не платит за каждую секунду

Вы когда-нибудь ждали ответа от голосового ассистента дольше, чем говорили сами? Это бесит. Я тестировал десятки сервисов — от ChatGPT Voice до самописных поделок. Проблема одна: закрытые API или адские задержки. OpenAI Voice Intelligence API (статья по ссылке) работает быстро, но стоит копейку за каждую минуту. А если вы хотите своего ассистента с открытым кодом? Тогда начинается пляска с бубном: одна модель для распознавания, вторая для генерации текста, третья для синтеза — и каждая тянет одеяло на себя.

В 2026 году появилось железо, которое меняет правила. Cerebras с их wafer-scale процессором CS-3 и API для инференса выдают скорость, недоступную даже топовым NVIDIA H100. А Google выпустила Gemma 4 — малютку на 2.6B параметров, которая на Cerebras летает со скоростью 1500 токенов в секунду. Добавляем Qwen TTS от Alibaba, который генерирует речь быстрее, чем вы успеваете моргнуть. И вуаля — открытый пайплайн, где задержка от голоса пользователя до голоса ассистента укладывается в 300-500 мс. Без ежемесячных счетов от OpenAI.

Gemma 4: малютка с реакцией спринтера

Gemma 4 — это не про размер. Это про то, как Google оптимизировал архитектуру именно для быстрого инференса. Модель использует групповой query attention (GQA) и работает в mixed-precision FP16. На Cerebras она загружается целиком на один чип (не надо шардить между GPU), так что latency на первый токен — единицы миллисекунд. Для сравнения: Llama 3.2 3B на обычном GPU (RTX 4090) выдает около 100 токенов/сек. Gemma 4 на Cerebras — 10-15x быстрее. Это критично для голоса: если LLM думает дольше 200 мс, диалог разваливается.

Важно: Cerebras Inference API (на момент 05.07.2026) поддерживает Gemma 4 в двух версиях: 2.6B и 7B. Для голосового пайплайна берите 2.6B — задержка минимальна, качество почти не уступает старшей сестре на диалоговых задачах.

Как получить доступ? Регистрируетесь на cloud.cerebras.net, получаете API-ключ. Документация говорит, что эндпоинт для Gemma 4 — https://api.cerebras.net/v1/chat/completions. Работает по OpenAI-совместимому формату. То есть можно кидать обычные запросы, как к GPT, только в 20 раз быстрее.

Собираем пайплайн: три сервиса, один socket

Архитектура простая, как грабли: аудио с микрофона -> ASR (распознавание речи) -> LLM (Gemma 4) -> TTS (синтез) -> аудио обратно. Но дьявол в деталях. Мы не будем ждать полной фразы — используем стриминг. Пользователь говорит, а пайплайн уже начал обрабатывать первый chunk.

1ASR: быстрее Whisper

Я перепробовал Whisper, Wav2Vec2, и даже экспериментальные модели от Hugging Face. Для реального времени лучше всего показала себя OpenAI Whisper tiny (нативный, без оберток) — она жрет 1 ГБ VRAM и выдает результат за 50-100 мс на куске в 2 секунды. Но есть нюанс: мы не хотим тащить GPU на сервер. Поэтому ставим faster-whisper (CTranslate2) — он работает на CPU с той же скоростью, что Whisper tiny на GPU, за счет интенсивых оптимизаций. Устанавливается одной командой:

pip install faster-whisper

На сервере запускаем модель tiny или base. Для русского языка лучше base, но tiny тоже сносно.

2LLM: Gemma 4 через Cerebras

Тут всё просто: отправляем текст пользователя с системным промптом на Cerebras API. Важно использовать streaming — получать токены по одному и сразу передавать их в TTS. Я не советую ждать полного ответа: при генерации длинного монолога задержка накопится. Вместо этого используем early stopping и chunking: как только набрали предложение (по точке, вопросительному знаку), отправляем его в TTS, а LLM продолжает генерацию следующего.

import requests, json

CEREBRAS_API_KEY = "your_key"

def generate(conversation):
    headers = {"Authorization": f"Bearer {CEREBRAS_API_KEY}"}
    payload = {
        "model": "gemma-4-2.6b",
        "messages": conversation,
        "stream": True,
        "max_tokens": 512
    }
    response = requests.post(
        "https://api.cerebras.net/v1/chat/completions",
        headers=headers, json=payload, stream=True
    )
    for line in response.iter_lines():
        if line:
            data = json.loads(line.decode().removeprefix("data: "))
            if "choices" in data:
                delta = data["choices"][0].get("delta", {}).get("content", "")
                yield delta

3TTS: Qwen TTS на Hugging Face

Синтез речи — узкое место любого пайплайна. Coqui XTTS v2 звучит круто, но на CPU выдаёт аудио медленнее реального времени. Qwen TTS (автор — Alibaba, модель Qwen2-Audio-TTS) показал себя как один из самых быстрых: на Hugging Face Inference Endpoints с GPU T4 latency составляет ~100 мс на фразу из 10 слов. Причём он поддерживает русский голос (с помощью LoRA-адаптеров). Разворачиваем модель на Hugging Face Inference Endpoints (https://ui.endpoints.huggingface.co). Выбираем тип GPU (T4 или L4), загружаем модель Qwen/Qwen2-Audio-TTS. Получаем URL эндпоинта.

Альтернатива — если у вас своя GPU, ставьте TTS от Coqui или Piper, но для демонстрации проще использовать Inference Endpoints. Кстати, если вам нужен единый API-ключ для доступа к разным моделям включая Cerebras и Hugging Face, посмотрите AITunnel — он объединяет провайдеров и даёт стабильный доступ через один шлюз.

import requests

HF_API_TOKEN = "hf_your_token"
ENDPOINT_URL = "https://your-endpoint.hf.space/generate"

def synthesize(text):
    headers = {"Authorization": f"Bearer {HF_API_TOKEN}"}
    payload = {"text": text, "voice": "ru_female"}
    response = requests.post(ENDPOINT_URL, headers=headers, json=payload)
    return response.content  # WAV bytes

4WebSocket-сервер: склеиваем всё воедино

Сервер на Python с asyncio и websockets. Клиент (браузер или мобильное приложение) открывает WebSocket и шлёт аудио-чанки (например, по 200 мс). Сервер накапливает их, по достижении порога тишины (VAD) отправляет chunk в ASR, получает текст, отправляет в LLM на стриминг, а токены — в TTS. Готовую аудио-WAV отправляем обратно клиенту. Весь цикл должен укладываться в 500 мс. Для этого все три вызова должны быть асинхронными и параллельными.

import asyncio, websockets, json

async def handler(websocket, path):
    async for message in websocket:
        # message - bytes audio (16kHz mono PCM)
        text = await asr.transcribe(message)
        full_response = ""
        async for chunk in generate_stream(text):
            full_response += chunk
            if chunk.endswith(('.', '!', '?')):
                audio = await synthesize(full_response)
                await websocket.send(audio)
                full_response = ""

start_server = websockets.serve(handler, "0.0.0.0", 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

Когда TTS тормозит, LLM уже молчит

Главная ошибка — последовательная обработка: получить текст, подождать LLM, потом TTS. Время складывается. Правильно: как только LLM начала выдавать первый токен, параллельно генерируем аудио для предыдущего предложения. Это требует буферизации и небольшого предсказания конца фразы. Я использую алгоритм speculative decoding для TTS: пока LLM генерирует, TTS уже синтезирует по префиксу. Если LLM изменила продолжение — отменяем и перезапускаем. Для Gemma 4 на Cerebras это редкость: модель предсказуема.

Ещё подводный камень — VAD (голосовая активность). Если клиент шлёт тишину каждые 20 мс, сервер захлебнётся. Нужен детектор начала и конца речи. Я ставлю Silero VAD (версия 5.0 на ONNX) — работает на CPU за 1-2 мс на фрейм.

Ошибки, которые превратят диалог в радиоуправляемую модель

  • Не включаете стриминг Cerebras — ждёте полный ответ, получаете +1 секунду задержки. Всегда используйте stream=True.
  • TTS на CPU в продакшене — время синтеза превысит длительность фразы. Берите GPU-ускоренный Qwen TTS через Hugging Face или ставьте LiveKit с собственными моделями.
  • Забываете про историю диалога — Gemma 4 не помнит предыдущие реплики, если не передавать messages. Храните контекст на сервере, но чистите после паузы (например, 2 минуты бездействия).
  • Отправляете аудио целиком — шлите чанками по 100-200 мс. Это снижает latency первого слова (time-to-first-word).
  • Игнорируете сжатие аудио — Opus вместо PCM экономит трафик. WebSocket поддерживает бинарные сообщения, используйте libopus.

Зачем всё это, если есть готовые API?

Готовые API — это кабала. Вы привязаны к провайдеру, платите за каждую минуту, не можете сменить модель. Открытый пайплайн даёт свободу: хотите — замените Gemma 4 на Llama 4, хотите — поставьте TTS от ElevenLabs (хотя это уже не open-source). Плюс вы контролируете данные — никакая речь пользователя не уходит третьим лицам. Для стартапов, которые делают голосовых ассистентов для клиник или банков, это железобетонный аргумент.

Кстати, если вам лень разворачивать свой WebSocket-сервер, посмотрите многопользовательский AI-чат с голосами — там архитектура похожа, но с упором на локальность.

Совет на прощание: не пытайтесь сделать perfect

У вас не получится с первого раза задержка 300 мс. Начните с простого: ASR (faster-whisper) + Cerebras API без TTS (просто текст). Как только заработает стриминг текста, добавьте TTS. Тестируйте с помощью простого HTML-клиента (getUserMedia + WebSocket). А когда всё сломается — вспомните, что Cerebras даёт 1500 токенов в секунду, а не 100. И если нужен надёжный доступ к Cerebras и другим моделям с единым биллингом, AITunnel может упростить интеграцию.

P.S. Самое смешное, что через год появятся end-to-end модели, которые делают speech-to-speech напрямую (уже есть MichiAI — статья). Но пока они не умеют кастомизировать голос и контекст, тривиальный пайплайн остаётся королём.

Подписаться на канал