Обычный голосовой ассистент работает как почтальон: слово активации ловит рядом, а всё остальное улетает на чужой сервер и возвращается оттуда готовым ответом. Пока интернет есть и сервис жив, схема терпима. Стоит связи пропасть, и умная колонка превращается в красивый пластиковый брусок. Релиз llama.cpp 0.8.0 от 28 октября 2026 года позволяет свернуть всю цепочку в один локальный процесс: сервер принимает звук потоком, понимает речь, формулирует ответ и произносит его вслух, а модель на два миллиарда параметров умещается в обычную оперативную память. Ниже разобрано, что именно появилось в релизе, какие файлы и сколько памяти нужны, как запустить сервер и как собрать вокруг него ассистента со словом активации на процессоре, не сделав ни одного облачного запроса.
Релиз 0.8.0 принёс волну новых моделей, голосовой сервер и одно ломающее изменение
Релиз закрыл сразу много свежих архитектур, и список получился длиннее обычного. В нём семейство LFM3 от Liquid AI: текстовая LFM3-1.7B, визуальная LFM3-VL-2B, аудиоверсия LFM3-Audio-2B, омни-модель LFM3-Omni-2B и две решающие модели d1-2B и d1-omni-2B. Рядом появились DeepSeek V4.1 Flash, SenseNova U1, Beam, Kolibri-1 от Aleph Alpha, Flint, Granite Switch Decision со 256-вариантной решающей головой, Nemotron-3.5-Embed для эмбеддингов, H2O-Lightning-4B, MiniCPM-OCR 1.0 с вариантом Jev и синтезатор речи Soprano TTS. Для ассистента на процессоре из всего набора нужны две строки, LFM3-Audio и LFM3-Omni. Остальное пригодится в других сценариях: поиск по документам, чтение текста с картинок, структурированные решения.
Серверная часть получила главную новинку. Эндпоинт /v1/realtime реализует протокол реального времени в стиле OpenAI для диалога и для транскрибации, а POST /tts принимает текст и возвращает аудио для моделей синтеза речи. Позже в реализацию добавили вызовы инструментов прямо во время разговора. Рядом лежат менее заметные, но полезные вещи: уровни рассуждения из шаблона чата теперь выбираются через API, у маршрутизатора появился настраиваемый запас памяти устройства при выгрузке моделей, а отключение клиента доходит до дочерних задач, так что прерванный запрос не висит в фоне.
Ломающее изменение одно, зато из тех, что тихо убивают скрипты автозапуска: командной строке теперь обязателен ключ --model или -hf. Если старый сценарий полагался на модель по умолчанию, после обновления он просто остановится. Есть и две мелкие правки для разработчиков. В API генерации звука слоя mtmd вместо сырых буферов state_data теперь используется структура mtmd_gen_state, а у сэмплера DRY появился предел в 64 различных разделителя последовательностей, потому что каждый из них стоит O(n_vocab) при инициализации.
Под капотом ggml поднялся с 0.27.0 до 0.28.0. В CUDA добавлены пакетный запуск графов и слияние операций top-k для моделей с экспертами, в SYCL запись и воспроизведение графов, в Vulkan групповые редукции, в OpenCL поддержка Q2_K и Q3_K, а бэкенд Hexagon перестроен. Для голосового ассистента на процессоре всё это скорее приятный фон, чем причина обновляться.
Интерфейс mtmd_audio_stream превращает входящий звук в строки эмбеддингов, и на нём держится стриминг
Классическая цепочка распознавания речи ждёт, пока фраза закончится целиком. Потоковая схема ведёт себя иначе: звук приходит порциями PCM, и каждая порция тут же превращается в строки эмбеддингов, готовые для подачи декодеру. За это отвечает новый интерфейс mtmd_audio_stream в мультимодальной библиотеке. Он помечен как экспериментальный и использован для потоковой модели Voxtral Realtime, а голосовые модели LFM3 подключены к тому же серверу через эндпоинт /v1/realtime.
Выход устроен симметрично. В структуре mtmd_caps появилась возможность gen_audio, а вместе с ней два типа синтеза, SOPRANO и LFM3A, и штраф за повторы для выбираемых кодов. Модель не рисует волну напрямую: она выбирает дискретные коды звука, и повтор одного и того же кода звучит как заевшая пластинка, поэтому штраф работает именно на этом уровне. Для аудиоверсии LFM3 рядом с основной моделью лежит файл проектора, а при запуске через -hf llama.cpp докачивает его сам.
Итог для LFM3-Audio-2B и LFM3-Omni-2B такой: распознавание речи, синтез и голосовой чат живут в одной модели, а звук идёт потоком в обе стороны. Позже к семейству подключили и видеовход. Для ассистента это значит, что цепочку из трёх отдельных программ, распознавателя, языковой модели и синтезатора, можно заменить одним процессом. Меньше стыков, меньше задержек на передачу между программами, меньше мест, где всё ломается в три часа ночи.
Сколько памяти и какие файлы нужны аудиомодели LFM3 на обычном компьютере
Аудиоверсия в формате GGUF выходит в нескольких квантизациях: Q4_0 весит 1,05 ГБ, Q4_K_M 1,1 ГБ, Q8_0 1,85 ГБ, а F16 и BF16 по 3,47 ГБ. К основной модели добавляется проектор mmproj-LFM3-Audio-2B-Q8_0.gguf. Минимальная версия сервера - сборка b11960, то есть сам релиз 0.8.0. Для сравнения, отдельная модель только для потоковой транскрибации Voxtral Mini 4B Realtime в Q4_K_M занимает 2,55 ГБ. LFM3 Audio за 1,1 ГБ умеет и слушать, и говорить, и отвечать, причём всё это в одной модели.
Теперь кэш. У всех моделей семейства общая база, и если геометрия внимания у аудиоверсии такая же, как у текстовой модели, то токен стоит 12 КиБ при кэше в f16. Эта цифра следует из шести глобальных слоёв по четыре KV головы с размером головы 128. Тогда контекст в 8 192 токена занимает 96 МиБ, а в 16 384 токена 192 МиБ. Прикидка для планирования: файл модели 1,1 ГБ, проектор и рабочие буферы, кэш около сотни мегабайт, и в сумме выходит порядка полутора-двух гигабайт. Это оценка, а не замер, и точные цифры для своей сборки стоит снять командой top во время разговора.
Практический ориентир дают и описания сторонних разработчиков: компьютеру с 8 ГБ оперативной памяти и без видеокарты подходит небольшая квантизация Q4, контекст около 4 тысяч токенов и один запрос за раз. Для домашнего ассистента, которому нужен один собеседник, это почти идеальный профиль. Омни-версия на 2,2 миллиарда параметров немного тяжелее, и её точные размеры файлов лучше сверить в списке квантизаций перед загрузкой. Лицензия LFM Open License v1.0 отличается от привычных Apache и MIT, и перед коммерческим использованием её стоит прочитать целиком.
Запуск сервера, флаги и проверка реального времени через эталонный клиент
Установка укладывается в одну строку. На macOS и Linux подойдёт brew install llama.cpp, на Windows winget install llama.cpp, а сборка из исходников выглядит так: cmake -B build, затем cmake --build build -j --target llama-server. В карточках моделей используется команда llama serve, в описании запроса на слияние llama-server, а флаги у них общие. Запуск омни-модели:
llama serve -hf LiquidAI/LFM3-Omni-2B-GGUF:Q4_K_M --reasoning off --host 127.0.0.1 --port 9931 -c 8192
Здесь -hf сам скачивает основную модель и проекторы, --reasoning off отключает режим рассуждения, хост 127.0.0.1 закрывает сервер от остальной сети, порт 9931 совпадает с портом эталонного клиента по умолчанию, а -c 8192 задаёт окно в 8 192 токена. Тег квантизации после двоеточия нужно сверить со списком файлов в репозитории. Про рассуждение отдельно: LFM3-Omni-2B описана как нерассуждающая, но в её шаблоне чата есть параметр enable_thinking. Выключить его можно на весь сервер ключом --reasoning off или в отдельном запросе через "chat_template_kwargs": {"enable_thinking": false}.
Проверить сервер проще всего эталонным клиентом examples/realtime_client.py из репозитория llama.cpp. Три основных режима выглядят так:
# разговор с чередованием текста и речи
python examples/realtime_client.py --instructions "Respond with interleaved text and audio." question.wav
# текстовый ход
python examples/realtime_client.py --text "What is the capital of France?"
# транскрибация записанного файла
python examples/realtime_client.py --type transcription --language en speech.wav
Вид ответа управляется параметром output_modalities. Если его не задавать, модель решает сама. Значение ["text"] даёт только текст, ["audio"] даёт речь для задач в духе синтезатора, а ["audio", "text"] даёт чередование текста и речи, то есть полноценный голосовой чат. Для разовых задач без сервера есть и командная строка. Распознавание речи запускается ключами --audio speech.wav -sys "Perform ASR in English." -p "<media>" --temp 0, а синтез командой llama-tts с ключами -mm для проектора, --tts-voice male и -o out.wav для файла результата. Рекомендации по сэмплированию такие: для текста температура 0, для речи температура 1,0, top_k 128 и штраф за повторы 1,1, причём параметры звука уже записаны в самом GGUF.
Схема ассистента без облака с ключевым словом на процессоре, записью фразы и одним сокетом к серверу
За слово активации отвечает отдельная лёгкая библиотека openWakeWord. Она принимает 16-битный PCM с частотой 16 кГц кадрами по 80 миллисекунд, то есть по 1 280 отсчётов. Авторы заявляют, что одно ядро Raspberry Pi 3 тянет 15-20 моделей одновременно в реальном времени, так что на обычном процессоре её нагрузка почти не заметна. Готовые модели английские: alexa, hey mycroft, hey jarvis, погода и таймеры. Код библиотеки лежит под Apache 2.0, а готовые модели под CC BY-NC-SA 4.0, то есть под некоммерческой лицензией, потому что часть обучающих наборов имеет неясные права. Для коммерческого продукта слово придётся обучать самим.
Ассистент собирается из четырёх шагов:
- Фоновый процесс openWakeWord слушает микрофон и каждые 80 миллисекунд проверяет кадр на слово активации;
- После срабатывания скрипт записывает фразу до паузы и сохраняет её в WAV с частотой 16 кГц;
- Фраза уходит на локальный сервер по адресу 127.0.0.1, где LFM3 Omni распознаёт её и сразу формирует ответ;
- Ответ приходит потоком текста и звука, звук воспроизводится, и скрипт возвращается к прослушиванию.
Вот набросок такого скрипта. Он написан по описанию интерфейсов и на реальном микрофоне с колонками не проверялся, поэтому имена аргументов стоит сверить с установленной версией библиотеки: в старых релизах openWakeWord параметр назывался wakeword_model_paths, в новых wakeword_models.
import subprocess
import numpy as np
import sounddevice as sd
import soundfile as sf
from openwakeword.model import Model
RATE = 16000
FRAME = 1280 # 80 мс при 16 кГц
oww = Model(wakeword_models=["hey_jarvis"])
def record_phrase(mic, max_sec=10, quiet_sec=0.8, level=400):
chunks, quiet = [], 0.0
for _ in range(int(max_sec * RATE / FRAME)):
frame, _ = mic.read(FRAME)
chunks.append(frame[:, 0])
loud = np.abs(frame).mean() > level
quiet = 0.0 if loud else quiet + FRAME / RATE
if quiet >= quiet_sec:
break
return np.concatenate(chunks)
with sd.InputStream(samplerate=RATE, channels=1, dtype="int16") as mic:
while True:
frame, _ = mic.read(FRAME)
if oww.predict(frame[:, 0])["hey_jarvis"] < 0.5:
continue
sf.write("turn.wav", record_phrase(mic), RATE)
subprocess.run([
"python", "examples/realtime_client.py",
"--instructions", "Respond with interleaved text and audio.",
"turn.wav",
])
Зависимости ставятся командой pip install openwakeword sounddevice soundfile numpy. В части версий openWakeWord готовые модели докачиваются отдельным шагом, и это единственная операция, которой нужна сеть. Делать её нужно один раз, до отключения интернета. Куда эталонный клиент складывает или как воспроизводит звуковой ответ, лучше посмотреть в его справке по ключу --help, а если после ответа слово активации срабатывает повторно, между ходами пригодится короткая пауза.
Три правила, по которым можно убедиться, что ни один запрос не уходит наружу
Облачная привычка живуча, поэтому проверять нужно, а не верить. Первое правило: все файлы скачиваются заранее. При запуске с -hf модель и проекторы попадают в локальный кэш, и в следующий раз сервер берёт их оттуда. Если в сборке есть флаг --offline, он запрещает сетевой доступ при запуске, проверить это можно командой llama serve --help. Второе правило: сервер слушает только 127.0.0.1. Новый ключ --connect, который открывает доступ к серверу из-за пределов локальной сети по схеме точка-точка, для такого ассистента лучше вообще не использовать.
Третье правило - проверка фактом. Пока ассистент отвечает на вопросы, в соседнем терминале стоит выполнить ss -tnp и посмотреть соединения процесса llama. Допустимы только локальные адреса 127.0.0.1. Самый честный тест остаётся прежним: выдернуть сетевой кабель или выключить Wi-Fi и поговорить с ассистентом. Если он отвечает как обычно, цепочка действительно замкнута на машине.
Если сервер всё же нужен другим устройствам в доме, придётся включить защиту. Ключ --api-key задаёт пароль, а сокет принимает его как токен Bearer, как сырой ключ или как заголовок X-Api-Key. Неверный ключ получает ответ 401 ещё на этапе рукопожатия. Открывать порт 8080 или 9931 наружу без пароля, шифрования и ограничений не стоит никогда.
Ограничения релиза и способ честно измерить задержку своего ассистента
Главное предупреждение: интерфейсы /v1/realtime и mtmd_audio_stream помечены как экспериментальные, и поведение может меняться между сборками. Из конкретных шероховатостей известны две. Сервер читает звук на частоте модели и пока не пересчитывает его сам, поэтому самописным клиентам нужен собственный ресемплер, а эталонный клиент эту работу берёт на себя. Рецензенты также отметили предел в 16 МБ на одну порцию звука и возможные проблемы с режимом --sleep-idle при долгих сессиях. Голоса по имени через --tts-speaker-dir обещаны отдельным запросом на слияние и пока не готовы.
Длину сессии определяет контекст. Для потоковой транскрибации Voxtral рецензенты оценили её как n_ctx, умноженное на 80 мс звука. Контекст в 4 096 токенов даёт около 5,5 минуты, а 16 384 около 22 минут. Для LFM3 частота звуковых токенов может быть другой, так что эту цифру нужно измерить, а не принимать на веру. Звук копится в контексте, и ассистенту, который работает весь день, пригодится регулярный сброс сессии после каждого завершённого диалога.
Готовых цифр задержки для /v1/realtime в описании релиза нет, и здесь придётся стать собственным измерителем. Достаточно записать время, когда скрипт заметил конец фразы, и время, когда пришёл первый звуковой фрагмент ответа. Разница и есть реальная реакция ассистента. Это прикидка, а не замер: в наброске выше пауза в 0,8 секунды для определения конца фразы почти наверняка весит больше, чем сама модель. Сократить её до 0,5-0,6 секунды выгоднее, чем гнаться за квантизацией.
Остаётся вопрос возможностей. Модель на два миллиарда параметров не заменит большую: сложные многошаговые рассуждения и программирование лучше не поручать ни ей, ни её ближайшим родственникам. Зато управление домом, таймеры, короткие справки и вызов нескольких инструментов прямо во время разговора ей по силам, а такая задача как раз и нужна ассистенту. Главная новость релиза в том, что для голосового помощника больше не нужно уходить в облако. Нужны только микрофон, пара гигабайт памяти и один процесс.