Перейти к содержанию
Новое AiManual теперь в MAX Подписаться
Публикация AiManual

llama.cpp: автоматическая загрузка тензоров MTP увеличивает потребление VRAM — что изменилось и как с этим работать

В новых сборках llama.cpp тензоры MTP/NextN загружаются автоматически, даже без спекулятивного декодирования. Расход VRAM растет на объем слоя MoE. Разбираем за

Коротко

Что будет в материале

  1. 01

    Что произошло: изменение в llama.cpp и его последствия

  2. 02

    Какие модели затронуты: список и особенности

  3. 03

    Как это влияет на потребление памяти: цифры и контекст

  4. 04

    Почему это произошло: техническая подоплека

В последних сборках 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 не предоставляет нужных рычагов контроля.

Подписаться на канал