Почему 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 delta3TTS: 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 bytes4WebSocket-сервер: склеиваем всё воедино
Сервер на 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 — статья). Но пока они не умеют кастомизировать голос и контекст, тривиальный пайплайн остаётся королём.