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

© 2026 · All rights reserved.

Что нового в LocalAI 4.9

Источник: LocalAI

Что нового в LocalAI 4.9

Источник: LocalAI

LocalAI is the open source AI engine. Run any model, LLMs, vision, voice, image and video, on any hardware. No GPU required.

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

Вышла версия LocalAI 4.9.0, спустя тринадцать дней и 146 объединенных pull-реквестов. В этот раз новых движков нет. Работа была сосредоточена на улучшении существующих функций LocalAI, включая исправление безопасности, с которым стоит ознакомиться перед обновлением.

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

Прочитайте это перед обновлением: маршруты теперь закрыты по умолчанию

До этого релиза промежуточное ПО (middleware) аутентификации решало, что защищать, сопоставляя префиксы путей. Маршрут, путь которого не был в этом списке, считался публичным.

Это было приемлемо до тех пор, пока у маршрута не появлялся псевдоним. /mcp/chat/completions, /moderations, /models, /backends и /import-model существовали без префикса, который искал классификатор, поэтому глобальная аутентификация к ним не применялась. Любой маршрут, добавленный позже, по умолчанию наследовал ту же проблему, так как отсутствие в списке защищенных префиксов — это состояние, к которому легко прийти случайно.

Теперь промежуточное ПО учитывает методы и закрывает доступ по умолчанию. Маршрут является публичным только в том случае, если его метод и путь присутствуют в явном реестре. Публичными остаются только необходимые элементы: инструкции API, GET-маршруты Swagger, хорошо известный документ LocalAI, а также потоки здоровья, входа в систему, OAuth, SPA, активов, брендинга и начальной загрузки токена регистрации узла. Покрытие всего маршрутизатора подтверждается тестами, поэтому новый маршрут не может стать публичным из-за того, что о нем забыли (#11602).

Если вы используете аутентификацию через базу данных или настроенные устаревшие ключи API, изменятся две вещи. /version теперь требует учетные данные. То же самое касается URL-адресов, которые LocalAI возвращает для сгенерированного аудио, изображений, видео и 3D-активов, что означает, что клиент, который получал эти URL анонимно, должен отправлять ключ. Встроенные развертывания по-прежнему могут открывать узкие префиксы через ApplicationConfig.PathWithoutAuth, а флаги исключения устаревших GET-запросов по-прежнему существуют как явные переопределения совместимости.

Спасибо Наору Яакову за сообщение об этом классе уязвимостей обхода защиты.

Чат теперь может сжимать свою историю

Длинный разговор в конечном итоге перестает помещаться в контекстное окно, и обычный ответ — отбросить самые старые сообщения. Этот релиз позволяет вместо этого их сжимать.

Сжатие включается для каждой модели отдельно через блок compression в конфигурации модели. Когда оно включено, старые завершенные диалоги прогоняются через выбранную вами модель LocalAI и заменяются результатом перед выводом. По умолчанию оно выключено, и для моделей, где оно не настроено, ничего не меняется (#11556).

Некоторые вещи намеренно оставлены без изменений. Начальные системные промпты и промпты разработчика сохраняются, поэтому промпт безопасности не будет удален при суммаризации. Самые новые сообщения сохраняются. Пары вызовов инструментов и их результатов остаются целыми, поэтому сжатая история никогда не содержит вызов, результат которого был потерян. Сжатие выполняется после фильтрации PII и после внедрения промптов Assistant и MCP, включая последующие итерации MCP, поэтому сжатие видит промпт, который был бы отправлен на самом деле. Схемы инструментов и запас, необходимый для завершения, учитываются с консервативным ограничением токенов в автономном режиме.

Ответы без потоковой передачи содержат метаданные сжатия, потоковые ответы содержат их в трейлере использования, а события сжатия, коэффициенты и длительность экспортируются как метрики. Конфигурация прокси-сервера облака отклоняет сжатие, так как LocalAI не может безопасно перезаписать непрозрачную полезную нагрузку провайдера; режим перевода работает. Если сжатие завершается неудачно во время уже начатого потока, вы получите ошибку SSE внутри канала, за которой последует [DONE], вместо обрезанного ответа.

Модели и бэкенды теперь имеют по одной странице

У моделей была галерея и отдельная поверхность управления в разделе Host. У бэкендов был вложенный вид Host для установленных бинарных файлов. Это означало, что местоположение ресурса зависело от того, ищете ли вы его или управляете им, а общие действия находились на уровень глубже, чем нужно.

Теперь /app/models содержит разделы Explore и Installed, а /app/backends — Catalog и Installed. Оба сохраняют состояние поиска, фильтрации и выбора в URL, поэтому отфильтрованный вид — это ссылка, которую можно отправить кому угодно. Бэкенды сохраняют свои варианты, сборки для разработки и область действия целевого узла. Explore предлагает действия по установке Open и Manage с учетом возможностей, в то время как деструктивные элементы управления остаются в Installed, где вы уже просматриваете то, что вам принадлежит. Обзор работы считывает емкость хоста из общего опросчика сводок, который у него уже был, а вложенный пункт назначения Host удален (#11548).

API не изменился. Существующие закладки /app/manage по-прежнему работают через перенаправление, которое сохраняет состояние запроса модели и бэкенда.

Форма импорта скрывала ответ за шевроном

Страница импорта получила новую палитру, но сохранила старую компоновку: столбец шириной 760 пикселей, содержащий поле URI, руководство по форматам, десять чипов модальности, девять полей предпочтений, повторитель «ключ-значение» и редактор YAML, при этом основная кнопка была отделена от формы, которую она отправляла.

Две из проблем были явными ошибками. Кнопка «Импорт» вообще не имела className, поэтому она переходила к кнопке пользовательского агента и отображалась в системном стиле с неправильным шрифтом и без рамки фокуса. Рядом с ней class="btn btn-primary fas fa-save fa-upload" устанавливал Font Awesome в качестве семейства шрифтов самой кнопки, которое наследовал текст метки, в то время как два класса иконок боролись за один ::before.

Переработка переходит к более широкой компоновке и помещает справочник форматов рядом со столбцом работы. Этот справочник отвечает на единственный вопрос, который есть у администратора-новичка: что разрешено вставлять, и раньше он находился за шевроном, который по умолчанию был закрыт. При ширине менее 1024 пикселей он сворачивается в раскрывающийся список и остается доступным. Поле источника является главным и содержит собственную кнопку «Импорт», что позволило удалить скрытую кнопку отправки, которая существовала только потому, что реальное действие находилось вне <form>. Простой и расширенный режимы исчезли: они были идентичны примерно на 80%, и их сохранение означало переключение режима, ключ localStorage и диалог «Сохранить/Отменить», чьей единственной задачей была защита состояния, которое переключение скрыло бы. Что действительно отличается, так это тип ввода, поэтому теперь это две вкладки: источник или YAML (#11461).

Ошибка со строкой классов не была единичной. Последующая проверка обнаружила восемь элементов управления заголовками на семи страницах, где классы двух или трех элементов были объединены в одну строку (#11462).

Модель на 35 ГБ, которая выглядела постоянно сломанной

На фронтенде с двумя репликами загрузка GGUF объемом 35,7 ГБ на недавно добавленный рабочий узел Jetson Thor делала модель недоступной для загрузки с места оператора. Каждая повторная попытка в пользовательском интерфейсе воспроизводила это. При этом промежуточная стадия (staging) все время проходила нормально.

Реплика A установила консультативную блокировку для каждой модели и начала передачу, которая занимала около двадцати минут. Реплика B получила запрос на ту же модель, заблокировалась на pg_advisory_lock и была завершена через шестьдесят секунд из-за statement_timeout для роли localai:

Здесь объединились две ошибки. Route обернул всю холодную загрузку в advisorylock.WithLockCtx, поэтому блокировка удерживалась во время установки бэкенда, многогигабайтного стейджинга и загрузки чекпоинта. Блокировка существует для того, чтобы мешать двум репликам загружать одну и ту же модель одновременно — на принятие этого решения уходят миллисекунды. При этом WithLockCtx переопределял lock_timeout, но не statement_timeout, хотя оба прерывают один и тот же блокирующий вызов. Из-за этого шестидесятисекундный таймаут стал латентной проблемой для каждой advisory-блокировки в кодовой базе, а не только для этой.

Теперь холодные загрузки выполняются как долговечные задачи, поэтому блокировка захватывается и освобождается вокруг проверки дедупликации, а не во время передачи (#11514).

vllm-cpp теперь собирается для карт, отличных от Blackwell

CUDA-образы vllm-cpp собирались для 120a;121a на amd64 и только для 121a на arm64 из десяти архитектур, для которых собирается собственный релизный архив vllm.cpp.

Неподдерживаемая карта не работает медленнее — она падает при первом запросе с ошибкой «no kernel image is available for execution on the device» («для устройства недоступен образ ядра для выполнения»), спустя много времени после того, как установка бэкендов в local-ai отчиталась об успехе vllm-cpp. Эта проблема была обнаружена на узле Jetson Thor, где бэкенд был установлен, но ничего не мог обслуживать.

Разделение зависит от наличия кремния. Jetson работает только на arm64: 87 для Orin и 110 для Thor. Десктопный 120a работает только на amd64. 90a и 100a поддерживаются на обеих архитектурах из-за компонентов SBSA. Это добавляет поддержку A100, A10 и 3090, L4, 4090 и RTX 6000 Ada, H100 и H200, B200, B300, Jetson Orin и Jetson Thor. Защита CUDA 13 теперь также охватывает ветку arm64, а Triton-AOT остается включенным (#11512).

Видео со звуком и TTS в матрице llama.cpp

В vllm-cpp появилась поддержка видеомодальности. В C ABI vllm.cpp появился срез для видео в v12, и когда конфигурация модели объявляет набор чекпоинтов MiniMax-H3, Load открывает видеодвижок вместо текстового, а GenerateVideo обслуживает существующий эндпоинт /video в LocalAI. Видео и аудио генерируются совместно, поэтому MP4 возвращается с реальной дорожкой AAC вместо тишины, а если в промпте запрашивается речь, модель синхронизирует движения губ с ней (#11424).

Есть две детали, о которых стоит знать, если вы решите разобраться. H3 — это не каталог моделей: DiT, текстовый энкодер и два VAE являются отдельными артефактами, поэтому parameters.model указывает на DiT, а остальная часть набора перечисляется в options:. При этом раздел DiT должен быть явно объявлен, а не определяться автоматически, поскольку комьюнити-квантования удаляют метаданные релиза, а DiT-модели FL2VA и Ref2VA имеют идентичную структуру на диске. Передача эталонной кондиции в FL2VA DiT приводит к рендерингу в течение нескольких часов и возврату цветной решетки, поэтому такая комбинация отклоняется до вызова движка. Эндпоинты галереи minimax-h3-fl2va-q4 и minimax-h3-ref2va-q4 устанавливают эти два набора.

Кроме того, Qwen3-TTS теперь работает через бэкенд llama-cpp, что добавляет синтез речи на ту же матрицу ускорителей, которая уже используется для генерации текста: CUDA, ROCm, SYCL, Vulkan, Metal и L4T с использованием собственной конвертации GGUF из апстрима. Это реализовано как слотовая задача SERVER_TASK_TYPE_TTS, а не как обработчик gRPC, управляющий циклом генерации, поскольку server_context владеет llama_context и запускает планировщик слотов в своем собственном потоке, а обработчик со своим собственным циклом создал бы состояние гонки. Серверная обвязка в апстриме все еще находится на стадии драфта, поэтому она поставляется в виде патча, который будет удален при слиянии ggml-org/llama.cpp#26603. Эндпоинты в галерее: qwen3-tts-llamacpp и qwen3-tts-llamacpp-q4. Существующий бэкенд qwen3-tts-cpp остается без изменений, так что они работают параллельно (#11392).

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

HTTP-контроль допущенных запросов (admission control) теперь работает в масштабе всего процесса, а не для каждого бэкенда по отдельности, что также предотвращает бесконечный рост списка трейсов. Кроме того, выполняющиеся операции бэкенда теперь отображаются во время их полета со ссылками прямо на их логи (#11560).

PII-мидлваре теперь может восстанавливать то, что она маскировала. При включенном параметре pii.reverse_in_response замаскированное значение становится уникальным детерминированным псевдонимом в рамках запроса: два адреса отображаются как EMAIL_001 и EMAIL_002 там, где раньше было два одинаковых маркера [REDACTED:EMAIL], и каждый из них восстанавливается, если бэкенд возвращает его обратно. Восстановление корректно обрабатывает SSE-токены, разделенные между записями ответов. Карта подставок локальна для запроса и никогда не записывается на диск, а необратимая маскировка по-прежнему используется по умолчанию (#11272).

Материализация снепшотов Hugging Face теперь скачивает файлы параллельно до заданного лимита, поэтому репозиторий с большим количеством шардов больше не обрабатывается по одному файлу за раз. Параллельно загружаются только целые файлы, но никогда не их части, поэтому возобновление .partial и верификация SHA для каждого файла работают точно так же, как и раньше, а два вызывающих кода вне конвейера артефактов сохраняют свою последовательную очередность через обертку с лимитом в единицу (#11162).

KNN стал роутером запросов первого уровня, а не просто кэшем для классификатора. classifier: knn голосует на основе сходства по размеченным примерам промптов, поэтому ему не нужна модель классификатора, а знания о метках хранятся в корпусе, который вы наполняете через API администратора. Записи ниже knn.similarity_threshold не могут участвовать в голосовании, и если ни одна не проходит порог, роутер возвращается к резервному поведению и не угадывает, при этом nearest_similarity в любом случае фиксируется в решении. Корпус сохраняется в виде одного файла JSONL на один роутер по пути <data path>/router-corpus, а записи, сохраненные под другой моделью эмбеддингов, пересчитывают эмбеддинги при загрузке (#10652).

Реальное время WebRTC теперь можно закрепить за одним портом UDP с помощью переменной LOCALAI_WEBRTC_UDP_PORT, поэтому для контейнера или файрвола требуется одно правило вместо диапазона (#11436). Последующее исправление устранило проблему взаимодействия между двумя настройками. Переменная LOCALAI_WEBRTC_ICE_INTERFACES молча игнорировалась всякий раз, когда был задан порт, поскольку мультиплексор с подстановочными знаками заставляет pion самостоятельно перечислять интерфейсы без фильтрации. На хосте с мостами Docker браузеру передавались адреса вроде 172.18.0.1 и им подобные, происходило подключение по подходящей паре, а затем соединение обрывалось, когда проверки согласия ICE завершались неудачей на остальных интерфейсах (#11466).

В двух macOS-бэкендах отсутствовала поддержка Metal. В stablediffusion-ggml флаги Metal были привязаны к переменной OS=Darwin, которую раннер Darwin не определяет, поэтому BUILD_TYPE=metal создавал сборку без встроенной библиотеки (#11531). parakeet-cpp вообще никогда не передавал BUILD_TYPE=metal в PARAKEET_GGML_METAL; на M1 Air выполнение того же пятиминутного семпла сократилось с 82,57 секунд до 50,18 секунд при идентичном на уровне байтов выходе (#11492).

При падении бэкенда теперь сообщается причина. Неожиданный выход во время выполнения раньше логировал свой вывод ошибок (stderr) только на уровне debug, поэтому при стандартном уровне логирования операторы видели код выхода и ничего более; теперь последняя непустая строка stderr добавляется к предупреждению (#11532), а неудачная проверка готовности gRPC сохраняет код выхода процесса вместе с последними 4 КиБ диагностических данных (#11447). MCP-серверы уровня моделей больше не исчезают из Chat при сбое обнаружения, что раньше скрывало проблемы с доступностью DNS контейнера и VPN; они остаются в списке в виде строк ошибок с прикрепленной причиной (#11495). Несоответствие контрольных сумм после скачивания теперь рассматривается как временный сбой передачи и повторяется, поэтому устаревший ответ CDN больше не приводит к сбою установки, при этом не верифицированные байты по-прежнему отклоняются (#11536).

Веб-интерфейс теперь поддерживает еще два языка: португальский (Бразилия) — полный перевод всех 14 пространств имен (#11427), а также индонезийский для строк администратора, медиа и навигации (#11493).

Количество записей в галерее увеличилось с 1622 до 1707. Появились модели Qwen3.8 в версиях 9B, 27B, Ridge и small, а также Gemma 4 agentic и Scotoma 2, DeepSeek V4 Pro 0813, Ling 3.0 Flash, Nemotron 3.5 Lightning 30B, Tess 4 27B, Ornith 1.0 и 1.5, LFM2.5 в версиях 230M и VL 1.6B, HunyuanOCR, OvisOCR2, Higgs Audio v3 и первое семейство моделей для геномики. В этом релизе приняли участие десять человек, трое из которых — впервые.

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

← Все статьи