В последних сборках llama.cpp произошло изменение, напрямую влияющее на потребление памяти при запуске популярных моделей. Тензоры MTP/NextN, встроенные в GGUF-файлы, теперь загружаются автоматически при каждом запуске, даже если вы не используете спекулятивное декодирование. Результат - дополнительный расход VRAM или RAM, сопоставимый с одним слоем Mixture of Experts (MoE).
Раньше эти тензоры просто игнорировались, если вы явно не указывали флаг --spec-type draft-mtp. Теперь логика изменилась: загрузка происходит по умолчанию. Для систем с ограниченными ресурсами это может стать критичным фактором при планировании развертывания.
В этом разборе - какие модели затронуты, как оценить прирост потребления памяти и как вернуть контроль над VRAM без потери функциональности.
Что произошло: изменение в llama.cpp и его последствия
Суть изменения - унификация загрузки весов моделей из формата GGUF. Разработчики llama.cpp перешли к схеме, при которой все тензоры, присутствующие в файле, загружаются в память. Тензоры MTP (Multi-Token Prediction) и NextN - это дополнительные веса, предназначенные для спекулятивного декодирования: модель генерирует несколько вариантов продолжения текста параллельно, а затем верифицирует их основным телом модели.
До обновления эти тензоры оставались на диске, если пользователь не активировал спекулятивное декодирование флагом --spec-type draft-mtp. Теперь они загружаются всегда, независимо от параметров запуска. Дополнительное потребление памяти эквивалентно примерно одному слою MoE - это не катастрофа для мощных GPU, но ощутимо для конфигураций на грани возможностей.
Изменение затрагивает всех пользователей llama.cpp, работающих с определенными моделями. Если вы используете последние сборки и замечаете неожиданный рост VRAM - причина с высокой вероятностью именно в этом.
Какие модели затронуты: список и особенности
Автоматическая загрузка MTP/NextN тензоров касается моделей, чьи GGUF-файлы содержат эти веса. Проверенный список включает:
- GLM-5.2 - серия моделей от Tsinghua University с нативной поддержкой MTP
- hy_v3 - модель с архитектурными особенностями, включающими спекулятивные тензоры
- qwen35moe - MoE-версия Qwen с 35B общих параметров
- step35 - еще одна MoE-модель со встроенными MTP-тензорами
Эти модели объединяет архитектурная поддержка спекулятивного декодирования на этапе обучения или конвертации. Тензоры MTP/NextN встраиваются в GGUF при конвертации из исходных весов - они не являются обязательными для базового инференса, но присутствуют в файле для удобства активации функции.
Если вы не уверены, содержит ли ваш GGUF-файл MTP-тензоры, проверьте его содержимое утилитой gguf-dump или скриптом на Python с библиотекой gguf. Ищите ключи, содержащие подстроки "mtp" или "nextn".
Как это влияет на потребление памяти: цифры и контекст
Дополнительный расход памяти сопоставим с одним слоем MoE. Для моделей с 35B общих параметров и ~3-5B активных это означает прирост в диапазоне 200-400 МБ VRAM при типичных квантизациях Q4_K_M. Точное значение зависит от размера тензоров MTP в конкретной модели и выбранного типа квантизации.
Сравните с общим потреблением: qwen35moe в Q4_K_M занимает около 20 ГБ VRAM. Добавка в 200-400 МБ - это 1-2% от общего объема. На GPU с 24 ГБ это незаметно. На конфигурации с 16 ГБ, где модель уже балансирует на грани с контекстом 4096 токенов, лишние 400 МБ могут вызвать Out of Memory.
Пример: GLM-5.2 и qwen35moe
Рассмотрим два сценария на RTX 4090 (24 ГБ VRAM):
- GLM-5.2 Q4_K_M: базовое потребление ~18 ГБ. С автоматической загрузкой MTP - ~18.3 ГБ. Контекст 8192 токенов все еще помещается, но запас сокращается.
- qwen35moe Q4_K_M: базовое потребление ~20 ГБ. С MTP - ~20.35 ГБ. Контекст 4096 токенов может стать недоступен при параллельных нагрузках.
Для систем с 12 ГБ VRAM и ниже запуск этих моделей уже требует тщательной оптимизации. Дополнительные 200-400 МБ могут стать последней каплей. В таких случаях удаление MTP-тензоров из GGUF - не прихоть, а необходимость.
Почему это произошло: техническая подоплека
Тензоры MTP/NextN - это механизм Multi-Token Prediction, реализованный в llama.cpp для спекулятивного декодирования. Вместо генерации одного токена за шаг, модель предсказывает несколько вариантов параллельно. Основное тело модели верифицирует эти варианты, принимая или отклоняя их. Результат - рост скорости генерации на 20-50% без потери качества, что подтверждено тестами на Gemma4-26B и Qwen3.6-27B.
Встраивание MTP-тензоров в GGUF изначально задумывалось для удобства: пользователь получает один файл со всеми необходимыми весами. Раньше требовался явный флаг для загрузки, что создавало дополнительную точку отказа - многие не знали о существовании тензоров или забывали их активировать.
Логика изменения - упрощение кодовой базы и унификация загрузки. Разработчики llama.cpp убрали условную логику, которая проверяла наличие флага --spec-type draft-mtp перед загрузкой. Теперь загрузка происходит всегда, а использование тензоров для спекулятивного декодирования по-прежнему требует явной активации.
Патч для llama.cpp, восстанавливающий работу MTP на устаревших GPU Kepler, Maxwell, Pascal и Turing, также мог повлиять на логику загрузки. Исправление добавляет интеллектуальную проверку форматов BF16/FP16/FP32, но не затрагивает сам факт загрузки тензоров в память.
Как избежать лишнего потребления памяти: практические решения
Основной способ вернуть контроль над VRAM - удалить MTP-тензоры из GGUF-файла. Это лишит возможности использовать спекулятивное декодирование в будущем, но для систем с ограниченной памятью приоритет - стабильный запуск.
Альтернативные варианты: использовать старую версию llama.cpp (до внесения изменения), дождаться возможного отката или переключиться на другой бэкенд - exllamav2, vllm. Каждый из этих путей имеет свои ограничения: старые версии не получают новых оптимизаций, а смена бэкенда требует перенастройки пайплайна.
Инструкция: удаление тензоров MTP из GGUF
Для удаления потребуется Python с установленной библиотекой gguf. Скрипт ниже читает GGUF-файл, находит тензоры с ключами, содержащими "mtp" или "nextn", и сохраняет новый файл без них.
from gguf import GGUFReader, GGUFWriter
import sys
def remove_mtp_tensors(input_path, output_path):
reader = GGUFReader(input_path)
writer = GGUFWriter(output_path, reader.arch)
# Копируем метаданные
for key in reader.fields:
if key not in reader.tensors:
writer.add_field(key, reader.fields[key])
# Копируем тензоры, пропуская MTP/NextN
removed_count = 0
for tensor_name in reader.tensors:
if 'mtp' in tensor_name.lower() or 'nextn' in tensor_name.lower():
removed_count += 1
continue
tensor = reader.get_tensor(tensor_name)
writer.add_tensor(tensor_name, tensor.data, tensor.shape, tensor.tensor_type)
writer.write_to_file()
print(f"Удалено тензоров: {removed_count}")
if __name__ == "__main__":
remove_mtp_tensors(sys.argv[1], sys.argv[2])
Запуск: python remove_mtp.py model.Q4_K_M.gguf model_no_mtp.Q4_K_M.gguf. Перед удалением проверьте список тензоров: gguf-dump model.Q4_K_M.gguf | grep -E "mtp|nextn".
После удаления MTP-тензоров модель запускается с обычным потреблением памяти. Флаг --spec-type draft-mtp перестанет работать - llama.cpp сообщит об отсутствии необходимых тензоров.
Что дальше: перспективы и рекомендации
Реакция сообщества на изменение неоднозначна. Разработчики llama.cpp могут добавить опциональный флаг для пропуска загрузки MTP-тензоров в будущих версиях - подобные дискуссии уже идут в issues репозитория. Пока этого не произошло, выбор за пользователем.
Рекомендации зависят от вашего сценария:
- Память критична: удалите MTP-тензоры из GGUF. Это разовое действие, которое возвращает потребление VRAM к прежнему уровню.
- Память не критична, но важна скорость: оставьте тензоры и используйте спекулятивное декодирование. MTP дает прирост до 50% t/s на MoE-моделях, что подтверждено тестами на Gemma4-26B-A4B-IT-QAT.
- Хотите гибкости: храните две версии GGUF - полную и без MTP. Переключайтесь между ними в зависимости от доступных ресурсов.
Мониторинг обновлений llama.cpp остается обязательной практикой. Оптимизации памяти, подобные KVarN и mixed-precision KV cache precision tail, сокращают VRAM на 34% без потери точности - комбинация таких техник с контролем над MTP-тензорами дает максимальную эффективность на ограниченном железе.
Для тех, кто ищет альтернативы: exllamav2 и vllm предлагают собственные реализации спекулятивного декодирования с более гибким управлением памятью. Переход на другой бэкенд оправдан, если проблема с VRAM становится хронической, а llama.cpp не предоставляет нужных рычагов контроля.