Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Chto novogo v localai 48
Dev48

© 2026 · All rights reserved.

Что нового в LocalAI 4.8

Источник: LocalAI

Что нового в LocalAI 4.8

Источник: LocalAI

LocalAI — это движок ИИ с открытым исходным кодом. Запускайте любые модели: LLM, зрение, голос, изображения и видео на любом оборудовании. GPU не требуется.

25 сентября 2026 г.

Вышла версия LocalAI 4.8.0, спустя двадцать два дня и 386 принятых пулл-реквестов. В LocalAI появилось четыре новые функции, а также проделана большая работа по исправлению уже существующих.

Полный список изменений доступен в примечаниях. В этой статье рассматриваются части, которые влияют на повседневную работу, с указанием номеров пулл-реквестов, чтобы вы могли ознакомиться с изменениями в коде.

Веб-интерфейс стал в 3,48 раза легче

Откройте интерфейс через медленное соединение, и теперь вы будете ждать примерно в три раза меньше. Три отдельные проблемы HTTP были исправлены одновременно в #11056, все замеры проводились на работающем развертывании.

Сервер не отправлял Content-Encoding вообще, независимо от того, что запрашивал клиент. Теперь добавлено промежуточное ПО gzip, включенное по умолчанию, с параметрами --disable-http-compression и --http-compression-min-length (по умолчанию 1024), если вы хотите изменить настройки. Потоковые ответы явно пропускаются, так как буферизация SSE-потока за gzip-враппером нарушает инкрементальную передачу данных и выглядит для клиента как зависший запрос. Пути completion, realtime, speech, transcription, agent-job и log-tail находятся в списке исключений, как и уже сжатые форматы, которые gzip делал лишь незначительно больше.

Vite добавляет контентные хеши к именам файлов бандла, поэтому URL /assets/ никогда не должен менять содержимое, однако ассеты поставлялись без заголовков Cache-Control, ETag или Last-Modified. Теперь они содержат public, max-age=31536000, immutable, а index.html явно помечен как no-cache, чтобы обновления развертывания всегда подхватывались.

Третья проблема заключалась в том, что /api/traces возвращал 21 МБ непагинированного блоба, который интерфейс опрашивал каждые пять секунд. Оба эндпоинта трассировки теперь принимают параметры limit (по умолчанию 50, макс. 1000, 0 для всех), offset и full, а также по умолчанию суммируют данные, отбрасывая тела и заголовки, но сохраняя счетчики байтов, чтобы интерфейс мог отобразить, что было отброшено. Каждая трассировка имеет идентификатор времени жизни процесса, а GET /api/traces/{id} возвращает полную запись при развертывании строки.

Одна запись в галерее, несколько сборок

Установка модели больше не означает необходимость читать список квантований и угадывать, какое из них потянет ваша карта. Запись в галерее теперь может объявлять variants: — список ссылок на другие записи, которые являются альтернативными сборками тех же весов:

Во время установки LocalAI отбрасывает варианты, которые этот хост не может запустить, определяя это по имени бэкенда, а не по аппаратным условиям, которые автору пришлось бы прописывать вручную. Так, MLX исчезает на Linux, а CUDA — на Mac. Затем он отбрасывает те, что не помещаются, используя VRAM на хостах с GPU и системную оперативную память с учетом cgroup на хостах с CPU, чтобы контейнер видел свой собственный лимит, а не лимит всей машины. Из оставшихся выбирается самый большой, исходя из предположения, что больший объем — это лучшая сборка тех же весов. Собственная сборка записи всегда участвует в выборе и никогда не фильтруется, поэтому процесс выбора всегда заканчивается чем-то устанавливаемым.

Размеры берутся из существующего оценщика pkg/vram, который считывает удаленный заголовок GGUF, при необходимости переключается на HTTP HEAD, затем на объявленный size:, а затем на листинг репозитория Hugging Face. Ничего не скачивается для принятия решения, и неудачная проверка никогда не приводит к сбою установки.

Любая поверхность может переопределить выбор: variant в POST /models/apply, local-ai models install --variant, инструмент MCP install_model и кнопка с выпадающим списком в таблице моделей. Явный выбор учитывается, даже если он не помещается (с предупреждением), так как это осознанное решение оператора. Старые клиенты читают тот же живой gallery/index.yaml, игнорируют непонятный им ключ и устанавливают все как раньше.

Один нюанс, о котором стоит знать: в распределенном режиме InstallModel разрешается относительно фронтенда, а не воркера, который будет обслуживать модель, поэтому кластер с маленьким фронтендом и большими воркерами выбирает консервативно. PR #10943, #10983, #10992, #11027 и #11139.

Новый движок: vllm.cpp (альфа)

vllm.cpp распространяется по лицензии Apache-2.0 и поддерживается командой LocalAI. Мы хотим, чтобы это был проект, ориентированный на сообщество, а не только на LocalAI, поэтому он живет в собственном репозитории со своей документацией, результатами бенчмарков и трекером задач, и работает без участия LocalAI. Он начинался как порт vLLM на C++20. Здесь он поставляется как бэкенд vllm-cpp (#11100). Он реализует архитектуру V1 от vLLM: постраничный KV-кэш, непрерывное пакетирование (continuous batching), кэширование префиксов, планировщик и сэмплер на переносимом тензорном рантайме без Python, PyTorch и ggml при инференсе. vLLM остается эталонной реализацией: корректность проверяется сравнением вывода с ним, а таблица результатов бенчмарков ведется относительно него.

Он обзавелся функциями, которых нет в vLLM, что является основной причиной существования порта. Он загружает как GGUF, так и safetensors, работает на CPU, Apple Metal и Vulkan наряду с CUDA 12 и 13, а также L4T для GB10, и поддерживает спекулятивную декодировку и выгрузку KV. Его страница бенчмарков теперь сравнивает результаты с llama.cpp, MLX-LM и DwarfStar, а также с vLLM, потому что на этом оборудовании именно с этими движками он конкурирует. Ожидается, что проект будет переименован, новое название еще не выбрано; он уходит достаточно далеко, поэтому vllm.cpp в конечном итоге будет вводить в заблуждение.

Вызов инструментов (tool calling) по своей структуре находится на уровне паритета с llama.cpp, так как чат намеренно повторно использует тот же путь автопарсера: полные шаблоны чата minja, tool_choice: auto, сведенный к ограничению ленивого декодирования структурных тегов, 30 диалектов инструментов, 7 парсеров рассуждений и потоковые ChatDelta и ToolCallDelta.

Цифры из собственной таблицы результатов проекта, где ничьи называются ничьими, а поражения — поражениями. Значение выше 1.0 означает, что vllm.cpp впереди:

Страница выше по течению осторожна в отношении собственного шума: на сетке 27B разброс между запусками составляет 0,5%, а результаты от c2 до c32 попадают в диапазон от 0,7% до 1,7%, поэтому проект считает эти пять случаев ничьими, а не победами. Результат concurrency-1 — это тот, на котором он настаивает.

Строка DeepSeek-V4-Flash показывает, насколько далеко проект ушел от простого порта vLLM. Он запускает DeepSeek-V4-Flash примерно на 2 бита (IQ2_XXS mixed, около 80 ГБ) на одном DGX Spark, декодируя со скоростью 18,69 ток/с против 16,33 у DwarfStar. При общем количестве параметров более 300B даже 4-битный чекпоинт весит 156 ГБ или больше, поэтому 2-битный GGUF — это то, что помещается в объединенный пул Spark объемом 119 ГиБ, и чтение GGUF — это то, что делает это возможным.

Это число менялось дважды за неделю, и второе изменение произошло благодаря одному рычагу. Плотная проекционная башня Q8_0 считывалась из mmap GGUF через объединенную память, которую GB10 читает примерно на 20% медленнее на GEMV, чем память устройства. Размещение этой 6-гигабайтной башни в памяти устройства один раз при загрузке (те же байты и те же ядра) увеличило скорость декодирования с 16,23 до 18,69, генерируя те же токены и не используя больше пиковой памяти. То же изменение позволило Laguna-XS-2.1 подняться с 87% от уровня vLLM до 1,03x впереди него.

Спекулятивная декодировка находится в похожем состоянии: MTP на Qwen3.6-27B NVFP4 генерирует те же токены, что и MTP в vLLM, и работает примерно на 4% быстрее при concurrency 1.

Конфигурация — это обычная установка бэкенда:

Относитесь к этому как к альфа-сборкам для разработки, а не как к выпущенному бэкенду. vllm.cpp находится на ранней стадии, и его включение в 4.8 предназначено для того, чтобы дать возможность попробовать его тем, кому это интересно, а не для рекомендации к использованию в критически важных задачах. llama-cpp остается стандартом для реального использования.

CPU-путь прошел сквозную проверку с использованием Qwen3.5-2B-UD-Q8_K_XL.gguf и полным набором тестов Ginkgo, охватывающим блокировку и потоковую передачу байтов, жадную детерминированность, стоп-слова, генерацию с ограничениями GBNF, параллельные потоки, разделение рассуждений, а также обязательные и автоматические вызовы инструментов. GPU-образы собираются и поставляются, но их поведение во время выполнения еще не проходило через этот фильтр. Сравнение пропускной способности с upstream vLLM не заявляется. Ожидайте шероховатостей и, пожалуйста, сообщайте о любых сбоях.

На Apple Silicon образ теперь поставляется с провайдером MLX GEMM для vllm.cpp (#11137). Upstream оставляет его выключенным по умолчанию, так как он добавляет около 124 МБ, поэтому мы провели замеры перед его включением. Qwen3-1.7B-bf16 на M4, p=512 g=128, оба варианта были переключены в одном бинарном файле, поэтому разница в сборке не может объяснить разрыв:

Два повтора, при этом разброс результатов достигает 9,4%, поэтому воспринимайте множители как +/-10%. Время до первого токена сокращается примерно вдвое во всем диапазоне.

LocalAI теперь генерирует 3D-модели

3D-генерация — это новая модальность, поэтому ее пришлось интегрировать во весь стек: RPC Generate3D в backend.proto, возможность FLAG_3D, чтобы загрузчик знал, какие бэкенды могут ее обслуживать, и POST /v1/3d/generations.

Первым движком для этого стал trellis2cpp, бэкенд для преобразования изображения в 3D на базе TRELLIS.2. Вы даете ему изображение, получаете GLB. В веб-интерфейсе есть страница с нативным просмотрщиком GLB, так что вы можете вращать результат прямо в браузере, вместо того чтобы скачивать его для проверки. История сохраняется в IndexedDB, поэтому перезагрузка не приведет к потере генераций, а также доступна предварительная печатная оптимизация сетки для вывода, который вы действительно собираетесь отправить на принтер (#10979).

Чат local-ai перестал быть REPL

Раньше local-ai chat представлял собой чат-промпт в терминале. Теперь это агент, встроенный прямо в бинарный файл: использование инструментов за фильтром подтверждения, субагенты, MCP-серверы, плагины и навыки, автоматически настроенные под ваш экземпляр. Ничего дополнительного устанавливать не нужно.

Последний выводит скрипт интеграции с оболочкой (zsh, bash или fish), поэтому вы можете вызвать агента, где бы вы ни находились, вместо того чтобы открывать что-то еще.

Теперь он запускает команды оболочки, поэтому каждый вызов инструмента проходит через промпт подтверждения, который вы контролируете, а команды только для чтения, такие как ls и cat, выполняются без запроса. Если у вас были привычки, связанные со старым REPL, некоторые вещи изменились: /clear больше нет, а /compact — это ближайший аналог, /models и /model <name> означают то же, что и всегда, а переключение модели сохраняет контекст беседы, вместо того чтобы начинать все сначала (#11291).

Один бэкенд, шесть аудио-эндпоинтов

Обычно для аудио используется один бэкенд на семейство моделей, что означает отдельный процесс для каждой возможности и отдельный файл конфигурации. audio-cpp обертывает audio.cpp, мультисемейный аудиодвижок ggml. Один процесс бэкенда обслуживает несколько несвязанных семейств через единый словарь времени выполнения и определяет, к какому семейству принадлежит чекпоинт, по ключу метаданных audiocpp.model_spec.family в самом GGUF. В конфигурации модели не нужно писать ничего специфичного для бэкенда.

В комплекте поставляется тринадцать записей галереи, по одной на каждый тип задачи, который движок может реально выполнить. Там, где он не может честно поддержать RPC, он возвращает UNIMPLEMENTED с указанием причины, а не пустой успех, а неудачная загрузка является ошибкой gRPC, а не success: false, что важно, так как жадный зонд загрузчика в противном случае выбрал бы его для модели, которую он не может обслужить.

Два изменения выходят за рамки самого бэкенда. AudioTransformResult получил поле stems, поэтому разделение источников может вернуть весь набор дорожек вместо одного микса. А /audio/transform больше не сводит все загрузки к 16 кГц моно: это сведение делало 4-дорожечное разделение невозможным по определению, поэтому оно стало возможностью для конкретного бэкенда, при этом существующие бэкенды сохраняют его явно, а по умолчанию для незарегистрированного бэкенда загрузка остается без изменений (#11141).

Три новых бэкенда для речи и малых квантований

magpie-tts-cpp обертывает magpie-tts.cpp, порт C++17 и ggml для NVIDIA Magpie TTS Multilingual 357M со встроенным вокодером NanoCodec. Пять голосов, девять и более языков, 22.05 кГц моно, из одного самодостаточного GGUF. Движок upstream проверяется на соответствие NeMo по компонентам, с максимальной абсолютной разницей при принудительном обучении (teacher-forced) в 3.6e-5.

moss-tts-cpp обертывает moss-tts.cpp и обслуживает MOSS-TTS-Local v1.5 в формате 48 кГц стерео, с опциональным клонированием голоса по эталонному аудио. Образы охватывают CPU, CUDA 12 и 13, Intel SYCL, Vulkan, ROCm, L4T и Darwin Metal. Оба добавлены в #11115, #10860 и #10877.

Бэкенд bonsai обслуживает 1-битные (Q1_0) и тернарные (Q2_0) квантования Bonsai для Qwen3 8B и Qwen3.6-27B, начиная примерно с 1.15 ГБ. В стандартном llama.cpp нет ядер для этих форматов, поэтому бэкенд собирается с форком PrismML через оберточный Makefile, который меняет только LLAMA_REPO и LLAMA_VERSION, повторно используя тот же grpc-server.cpp без патчей. С ним поставляется восемь записей галереи. Если Q1_0 и Q2_0 попадут в основную ветку llama.cpp, этот бэкенд будет переведен в режим обычного обновления версий (#10834, #10866).

Панель операций стала страницей

Старая панель операций отображала одну строку на каждую выполняемую операцию над каждой страницей. Поставьте в очередь четыре установки моделей и бэкенд, и она занимала большую часть экрана на каждом маршруте, пока не завершалась последняя. Она выполняла две задачи одновременно. Глобальному сигналу «что-то происходит» нужна только одна строка, а детали того, что происходит, требуют отдельной страницы.

Полоса теперь состоит из одной строки, постоянно отображая сначала ошибку, а затем наименее продвинутую выполняемую операцию с плашкой «+N еще». Ее значок ✕ скрывает полосу и больше ничего не отменяет. Это преднамеренное изменение поведения, о котором стоит знать, прежде чем нажимать его по привычке: тот же символ раньше отменял загрузку 17 ГБ в одной строке и закрывал сообщение в другой. Отмена переместилась на новую страницу, за кнопку, которая прямо об этом говорит.

Страница активности по адресу /app/activity доступна только администраторам и содержит то, что пришлось убрать с полосы: фазу, байты, вычисленное оставшееся время и разбивку по узлам для кластерных установок. Она также ведет журнал. /api/operations удалял операцию в момент ее завершения, поэтому, если вы запускали большую установку и уходили, не было способа узнать, завершилась ли она, провалилась или даже не начиналась. Этот журнал представляет собой ограниченное кольцо на 50 записей, и отклонение ошибки перемещает ее в журнал вместо удаления.

Несколько давних ошибок интерфейса были исправлены в ходе переписывания: повторная попытка удаления после сбоя приводила к повторной загрузке модели, операции в очереди отображались как «Установка» со спиннером, длинное сообщение об ошибке сдвигало каждую страницу примерно на 270 пикселей за пределы области просмотра и добавляло горизонтальную полосу прокрутки всему приложению, а ETA исчезало для всех операций, когда любая из них проходила проверку (#11163).

Бюджеты VRAM, на узел

Теперь вы можете ограничить объем памяти карты, который разрешено использовать LocalAI, в процентах или абсолютном значении (#10833):

Везде, где LocalAI считывает VRAM для принятия решения о выделении памяти, теперь используется значение min(detected, budget). Проценты выше 100 отклоняются, а абсолютные значения, превышающие физический объем, ограничиваются, поэтому верхний предел может только уменьшать доступный объем VRAM. В автономном режиме это жесткое ограничение на процесс, которое наследуется аппаратными настройками по умолчанию, автоматической подгонкой контекста, предупреждениями GGUF и механизмом контроля (watchdog). В распределенном режиме это предел размещения: воркер сообщает необработанный объем VRAM плюс свою строку бюджета, реестр узлов преобразует это в байтовый предел при регистрации и отправке heartbeat, а планировщику SQL не потребовалось изменений запросов. Переопределения администратора через PUT и DELETE /api/nodes/:id/vram-budget сохраняются после перезапуска воркера, и то же самое доступно в виде инструмента MCP set_node_vram_budget. Отсутствие значения означает использование всей обнаруженной VRAM, поэтому существующие развертывания не меняются.

Распределенный режим больше не удаляет работающие бэкенды

Модель, которая отображалась как загруженная на главной странице, но не появлялась ни на одном узле в кластере, оказалась результатом четырех отдельных ошибок, исправленных в этом цикле.

Механизм очистки (reaper) удалял строки node_models для бэкендов, которые были активны и работали. Функция probeLoadedModels удаляла строку после единственной неудачной односекундной проверки работоспособности gRPC, а занятый бэкенд не может на нее ответить, так как однопоточный бэкенд на Python блокируется на минуты во время выполнения запроса. Воркер порождает бэкенд и удерживает дескриптор процесса, поэтому его ответ не блокируется тем, что делает бэкенд. Новый запрос-ответ models.running опрашивает воркер напрямую, а механизм согласования (reconciler) сравнивает ключи процессов воркера со строками реестра до запуска проверки портов. Воркер, который не отвечает, пропускается, а не считается пустым, поэтому сбой в NATS не может привести к удалению строк узла. Там, где проверка портов все еще выполняется, она больше не смешивает режимы сбоя: DeadlineExceeded означает занятость, Unavailable означает отсутствие, и только второй вариант учитывается при достижении порога, который теперь требует трех последовательных пропусков.

Каждая маршрутизируемая модель также оставляла внутрипроцессную заглушку в ModelLoader фронтенда, а пути удаления очищали только запись в базе данных, поэтому заглушка переживала реплику, и модель вечно отображалась как загруженная. Хук удаления реплики стал списком, а новый механизм инвалидации удаляет локальную заглушку, как только в кластере не остается ни одной работоспособной реплики.

Наряду с этим, счетчики in_flight больше не завышаются и не блокируют VRAM реплики от вытеснения, сроки загрузки моделей масштабируются в зависимости от размера контрольной точки и прогресса, а не от реального времени, проверка промежуточного этапа считается прогрессом, а не простоем, обнаружение бэкендов перестало скрывать установленные воркером и GPU-only бэкенды за файловой системой контроллера, а планировщик не будет размещать модель на узле, который не может ее вместить. Полный список находится в #11142 и восемнадцати связанных PR.

Исправление безопасности, с которым стоит ознакомиться

POST /api/fine-tuning/jobs принимал reward_functions[].code — встроенный код на Python, который выполнялся на основе самодельного списка разрешенных функций. Этот список не являлся границей безопасности. Стандартная интроспекция CPython позволяет получить доступ к реальному модулю os изнутри, что означает произвольное выполнение кода на хосте, причем выполнение происходило во время дымового теста при запуске задания на эндпоинте, который по умолчанию не требует аутентификации.

Встроенный код вознаграждения теперь отклоняется, если оператор не установит LOCALAI_TRL_ALLOW_INLINE_REWARD=true на бэкенде. Встроенные функции вознаграждения это не затрагивает, и они не требуют настройки. Документация больше не описывает список разрешенных функций как «песочницу» (#11068).

В том же цикле были внесены еще два исправления для повышения безопасности. Жесткие ссылки tar, выходящие за пределы корня извлечения, теперь отклоняются: экстрактор архивов предварительно сканировал элементы и отклонял символические ссылки, но запись жесткой ссылки tar имеет режим обычного файла и проходила эту проверку, а Header.Linkname никогда не проверялся, поэтому архив мог ссылаться на путь вне целевой директории (#11266). А циклические $ref в грамматике JSON-схемы теперь отклоняются, а не вызывают рекурсию, приводящую к переполнению стека (#11041). Этот релиз также включает hono 4.12.25 для устранения CVE-2026-54290 (#11023).

Остальное, кратко

Артефакты моделей Hugging Face теперь представляют собой управляемый поток снимков: неизменяемое разрешение снимков, аутентифицированные загрузки с реальным прогрессом, материализация при установке из галереи и предварительной загрузке, привязка во время выполнения к промежуточным артефактам и возобновление прерванной загрузки для каждого файла вместо начала с нуля. Бэкенды на Python повторно используют путь загрузки Go вместо того, чтобы скачивать файлы самостоятельно.

Панель трассировки получила сортируемый столбец «Пользователь», а также IP-адрес клиента и агент пользователя в развернутой строке, взятые из RealIP() в echo, поэтому доверенный прокси учитывается.

Документация прошла капитальный ремонт, основанный на аудите каждой страницы: одна модель, qwen3-4b, теперь используется в примерах установки, веб-интерфейса и вызова curl; добавлено новое пошаговое руководство по созданию вашего первого агента; а новый справочник ошибок времени выполнения привязан к буквальным строкам ошибок, которые видят пользователи.

Valkey Search присоединяется к списку вариантов векторного хранилища в качестве бэкенда valkey-store (#11196). local-ai можно запускать по требованию через активацию сокетов systemd, принимая прослушиватель, который он наследует, вместо привязки к собственному, при этом обычное поведение --address остается неизменным, если прослушиватель активации отсутствует (#11169). История трассировки теперь сохраняется после перезапуска, хранясь в виде ограниченного JSON для каждой записи по пути данных без зависимости от базы данных (#11203). Вы можете редактировать сохраненные сообщения чата на месте, не вызывая новый запрос на вывод (#11189). А бэкенд Intel SYCL llama.cpp теперь является самодостаточным, поэтому он работает без соответствующей среды выполнения oneAPI на хосте (#10991).

Это также релиз, в котором localai.io разделился на две части: сайт проекта в корне и документация в /docs/. Каждый URL, который был опубликован ранее, по-прежнему работает благодаря 214 сгенерированным заглушкам перенаправления, поскольку GitHub Pages не имеет серверных правил перезаписи для правильной реализации этого (#11243).

Двадцать пять человек внесли свой вклад в этот релиз, одиннадцать из них — впервые. Галерея выросла с 1221 до 1515 записей.

Чтобы обновиться, выполните pull localai/localai:latest или запустите скрипт установки заново. Полный список изменений содержит все, что не вошло в эту публикацию.

← Все статьи