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

Qwen3.8-Flash-Next в llama.cpp: как VRAM, PLE и контекст меняют скорость на практике

Разбираем, почему Qwen3.8-Flash-Next в llama.cpp ускоряется при загрузке в 96 ГБ VRAM, сближает результаты на длинном контексте и неожиданно теряет скорость при

Коротко

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

  1. 01

    Короткий ответ: почему скорость меняется не только из-за GPU

  2. 02

    Qwen3.8-Flash-Next VRAM: что дает переход от CPU-only к полной загрузке

  3. 03

    Длинный контекст: почему результаты конфигураций начинают сближаться

  4. 04

    PLE в CUDA: откуда может взяться странный провал скорости

Короткий ответ: почему скорость меняется не только из-за GPU

В описанном benchmark Qwen3.8-Flash-Next в llama.cpp показывает почти линейный рост скорости при переходе от режима CPU-only к полной загрузке в 96 ГБ VRAM. Для этого сценария наблюдение указывает на высокую цену обмена между CPU и GPU: чем больше нужных для работы данных помещается в видеопамять, тем меньше системе приходится обращаться к оперативной памяти.

На длинном контексте преимущество отдельных конфигураций заметно сокращается. В нагрузке начинают сильнее проявляться обработка большого входа, расход памяти под KV-кэш и пропускная способность подсистемы памяти. Отдельная аномалия связана с PLE: перенос PLE-таблицы в CUDA сопровождается резким падением скорости. Причина такого провала по имеющемуся описанию не установлена.

На картину влияют и режим загрузки модели, то есть mmap или RAM-resident loading, и организация KV-кэша, unified или non-unified. При одном запросе, длинном документе и высокой конкуренции система может упираться в разные компоненты. Ниже разобраны наблюдения конкретного benchmark, а не независимое тестирование редакции. Точные значения скорости, версии llama.cpp и CUDA, характеристики процессора и видеокарт в доступных данных не приведены.

Какие четыре узких места нужно разделять

Одна цифра в токенах в секунду скрывает несколько разных процессов. Для диагностики локального запуска их нужно разводить:

  • Вычисления модели. Сюда входят операции над весами и активациями. Их скорость зависит от GPU, CPU, используемых ядер и настроек backend.
  • Перемещение данных. При частичном GPU offload часть весов или служебных структур может находиться в RAM. Обмен по шине добавляет задержку и расходует пропускную способность.
  • KV-кэш. Он хранит промежуточные состояния уже обработанного контекста. При росте длины последовательности кэш занимает больше памяти и чаще обращается к ней.
  • Параллельные запросы. Несколько последовательностей конкурируют за VRAM, RAM, вычислительные ресурсы и операции планировщика. Настройка, удачная для одного запроса, может дать другой результат при высокой нагрузке.

Одинаковая скорость генерации может получиться у двух разных конфигураций. В одной узким местом станут вычисления GPU, в другой, обмен с CPU или KV-кэш. Поэтому сравнивать нужно не только итоговые токены в секунду, но и профиль памяти, prefill, decode и поведение при заданном числе запросов.

Qwen3.8-Flash-Next VRAM: что дает переход от CPU-only к полной загрузке

Переход от CPU-only к GPU offload меняет место выполнения части операций и расположение данных. Объем VRAM задает предел для такого размещения, но сам по себе не гарантирует пропорциональный прирост. В описанном тесте рост оказался почти линейным до полной загрузки модели в 96 ГБ VRAM. Это полезный ориентир для конкретной нагрузки, но не универсальная формула для любой видеокарты и сборки llama.cpp.

CPU-only как контрольная точка

CPU-only нужен как базовая точка сравнения. Он показывает, сколько времени занимает запуск без участия видеокарты и насколько меняется результат после переноса части работы на GPU.

Для такой точки нужно записать скорость обработки входного контекста, скорость генерации, объем занятой оперативной памяти, время до первого токена и стабильность нескольких повторов. Если benchmark публикует только одну метрику, она не описывает поведение модели во всех режимах. Длинный prefill и последующая генерация создают разную нагрузку, поэтому их полезно измерять раздельно.

Отсутствие конкретного значения CPU-only в доступном описании не позволяет подставлять условные токены в секунду. Корректный вывод звучит уже сейчас: CPU-only служит контрольным режимом, а не готовой рекомендацией для любого сценария.

Частичный offload: промежуточный режим с собственными компромиссами

Частичный offload нужен, когда доступной VRAM не хватает для полной загрузки. Часть модели работает на GPU, остальная часть остается в RAM и обрабатывается CPU. Итоговая скорость зависит от того, как часто выполнение переходит между этими областями.

Больший объем GPU-размещения обычно уменьшает число обращений к CPU, но прирост может замедляться, если оставшиеся операции требуют регулярного обмена данными. На результат влияют размер батча, длина входа, выбранная квантизация и число активных последовательностей. Без этих параметров нельзя оценить частичный offload по одному объему VRAM.

Полезный пример настройки параметров распределения модели и длинного контекста приведен в материале о Qwen3.8 в llama.cpp на двух RTX 3090. Его нельзя переносить на описанный benchmark как готовую конфигурацию, но сам подход к проверке tensor split и KV-кэша применим: меняется одна группа параметров, остальные фиксируются.

Полная загрузка в 96 ГБ VRAM

В тестовой шкале полная загрузка в 96 ГБ VRAM сопровождается почти линейным ростом скорости относительно CPU-only и промежуточных вариантов. Наблюдение показывает пользу устранения обмена с CPU в конкретных условиях.

Эта формулировка не раскрывает точный главный ограничитель. Им могла быть пропускная способность системной памяти, задержка обмена, размещение весов или сочетание нескольких факторов. Сам факт наличия 96 ГБ VRAM не объясняет, почему прирост выглядит именно так. Для ответа потребовались бы логи памяти, параметры offload и отдельные измерения prefill и decode.

Полная загрузка полезна там, где видеопамять действительно удерживает все необходимые для выбранной нагрузки данные. При длинном контексте в тот же ресурс конкурирует KV-кэш. При нескольких запросах свободный запас VRAM сокращается еще быстрее.

Почему объем VRAM нельзя использовать как единственный прогноз

VRAM отвечает за вместимость, а скорость зависит еще от пропускной способности памяти, вычислительных блоков, CUDA backend, поведения KV-кэша и обмена с CPU. Две видеокарты с одинаковым объемом памяти могут по-разному обрабатывать одну и ту же модель.

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

Практический прогноз нужно строить по нескольким точкам: CPU-only, частичный offload, максимально доступный GPU offload и полная загрузка, если она помещается. Для каждой точки фиксируются одинаковые модель, контекст, входные данные и число повторов.

Длинный контекст: почему результаты конфигураций начинают сближаться

Короткий запрос хорошо показывает разницу между CPU и GPU-размещением весов. Длинный контекст добавляет другой слой нагрузки: системе приходится обработать больше входных токенов и хранить больше состояний в KV-кэше. Поэтому конфигурация с максимальной скоростью на коротком запросе не обязана сохранять такой же отрыв на длинной последовательности.

Что меняется при росте контекста

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

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

Для локального пользователя это означает простой контроль: короткий чат, анализ большого документа, RAG-запрос и продолжительный диалог нужно считать разными тестами. Один короткий промпт не описывает работу с контекстом, который модель будет получать каждый день.

Сближение результатов не означает одинаковую архитектуру

В описанном кейсе результаты конфигураций сближаются на длинном контексте. Это указывает на смену доминирующего узкого места в проверенном диапазоне. Выигрыш от размещения весов на GPU может частично перекрываться затратами на prefill, KV-кэш или обмен данными.

Сближение не означает, что VRAM перестает влиять на скорость и что все режимы становятся равноценными. Оно говорит только о том, что на определенной длине контекста разница между конфигурациями выражается слабее. Для надежного вывода нужны несколько длин контекста, одинаковые входы и отдельные результаты для prefill и decode.

Связь между длинным контекстом и скоростью подробно разбирается в статье о сравнении ускорения локальных LLM на длинном контексте. Заявленные там результаты нельзя считать доказательством поведения Qwen3.8-Flash-Next в llama.cpp, поскольку runtime и условия теста могут отличаться.

Контекст как часть расчета требований к локальному запуску

Для коротких запросов обычно важны задержка до первого токена и скорость decode. Для больших документов на первый план выходит время обработки входа и объем памяти под активную последовательность. В RAG добавляются найденные фрагменты, а в длительном диалоге контекст накапливается между сообщениями.

Требования нужно оценивать по рабочей длине, а не по максимальному числу, которое поддерживает интерфейс. Запустите один и тот же сценарий с коротким контекстом, типичным размером документа и верхней границей, которая реально нужна пользователям. Запишите пик VRAM и RAM, prefill, decode и число ошибок.

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

PLE в CUDA: откуда может взяться странный провал скорости

В описанном benchmark перенос PLE-таблицы в CUDA сопровождается заметным падением скорости. Это наблюдение нужно фиксировать отдельно от общего эффекта GPU offload. Перемещение структуры в VRAM не гарантирует ускорения: результат зависит от того, как часто к ней обращаются, каким образом читаются элементы и где выполняются соседние операции.

Что именно нужно уточнить про PLE-таблицу

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

До сравнения следует записать:

  • где таблица находилась в контрольном режиме, в RAM, VRAM или другом буфере;
  • какой объем памяти она занимала;
  • какие операции читали таблицу и как часто это происходило;
  • какие kernel или backend обрабатывали связанные с ней вычисления;
  • какая метрика просела, prefill, decode, latency или суммарный throughput.

Без этих полей фраза «PLE в CUDA медленнее» описывает симптом, но не объясняет механизм.

Почему CUDA-размещение не гарантирует ускорения

Для провала есть несколько проверяемых гипотез. Их нельзя выдавать за установленную причину:

  • Обмен и синхронизация. GPU может ждать данные или CPU может ждать завершения операции, если схема доступа требует частых переходов между устройствами.
  • Невыгодный шаблон чтения. Таблица может читаться с низкой локальностью, поэтому нахождение в VRAM не превращается в эффективный доступ.
  • Неподходящий размер операций. Мелкие обращения и частые запуски kernel способны съесть выигрыш от переноса данных.
  • Конфликт за память. PLE может конкурировать за кэш или пропускную способность с весами и KV-кэшем.
  • Особенность конкретной сборки. Падение может быть связано с кодом backend, драйвером, CUDA или регрессией, а не со свойством модели.

Общий принцип простой: ускоряет не адрес размещения сам по себе, а эффективный путь от данных к операции. Если перенос добавляет копирование или ожидание, результат может стать хуже.

Как диагностировать аномалию без догадок

  1. Зафиксируйте одну модель, один набор входов, одинаковую длину контекста, число запросов и все параметры запуска.
  2. Повторите каждый режим несколько раз. Отделите холодный запуск от прогретого, чтобы page cache и первичная загрузка не смешались с инференсом.
  3. Снимите логи RAM и VRAM до старта, после загрузки и во время теста. Зафиксируйте пиковые значения.
  4. Измерьте отдельно обработку входного контекста и генерацию. Провал только в decode и провал в prefill указывают на разные группы причин.
  5. Проверьте соседние версии llama.cpp, CUDA и драйвера при неизменной аппаратной конфигурации.
  6. Используйте профилировщик, если он доступен: ищите копирования, простои GPU, частые синхронизации и kernel с необычной длительностью.
  7. Повторите тест с одним запросом и с конкуренцией. Если разница появляется только при нескольких последовательностях, причина может быть связана с памятью или планированием.

Только воспроизводимый результат на контролируемых конфигурациях позволяет говорить о проблеме конкретной сборки. До этого корректное описание звучит как «перенос PLE сопровождается провалом скорости».

mmap или RAM-resident loading: что меняется кроме времени старта

mmap связывает файл модели с виртуальным адресным пространством процесса. Операционная система подгружает нужные страницы по мере обращения и может удерживать их в page cache. RAM-resident loading предполагает предварительное размещение данных модели в оперативной памяти, но фактическое поведение зависит от загрузчика, ОС и состояния памяти.

Эти режимы нельзя честно сравнить как два фиксированных числа. Холодный запуск с mmap и прогретый запуск из RAM обращаются к разным состояниям page cache. После нескольких прогонов разрыв может измениться, а при нехватке RAM система начнет вытеснять страницы и добавит задержки.

Как работает смысл сравнения mmap и RAM-resident

Для mmap важны размер файла, случайность обращений, свободная RAM и состояние page cache. Само отображение файла не означает, что вся модель мгновенно заняла физическую память.

RAM-resident loading может уменьшить зависимость от чтения файла во время работы, если в системе достаточно памяти и данные действительно удерживаются в RAM. Цена такого режима, дополнительный расход памяти и возможное более долгое начало запуска, зависит от способа загрузки.

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

Какая методика делает результаты сопоставимыми

Что зафиксироватьЗачем это нужно
Версию llama.cpp и параметры сборкиИзменения backend могут менять работу с памятью и CUDA
Файл модели и его квантизациюРазмер и тип данных влияют на RAM, VRAM и скорость
Длину контекста и входные данныеИначе меняются prefill и размер KV-кэша
Свободную RAM и состояние page cacheХолодный и теплый запуск дают разные условия
Время загрузки и время до первого токенаРазделяются старт процесса и собственно инференс
Скорость prefill и decodeВидно, какая часть нагрузки реагирует на режим загрузки
Пиковые RAM и VRAMПроверяется запас для контекста и конкурирующих процессов

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

Для каких сценариев важен каждый режим

mmap логичнее проверять при ограниченной RAM, частых запусках и хранении нескольких моделей на диске. Это условная рекомендация: при активной конкуренции page cache может вытесняться, а обращения к файлу начнут влиять на задержку.

RAM-resident loading имеет смысл проверять при длительном непрерывном инференсе, достаточном объеме оперативной памяти и необходимости уменьшить зависимость от чтения файла после старта. Если параллельно работают другие процессы, запас RAM нужно считать отдельно.

Для обоих вариантов измеряйте не одну скорость генерации. Пользователю локального сервера важны время запуска, время до первого токена, стабильность после прогрева, пик памяти и поведение при двух или нескольких одновременных запросах.

Unified и non-unified KV: почему конкуренция меняет итоговую пропускную способность

KV-кэш хранит состояния активных последовательностей. Его организация влияет на то, как память распределяется между запросами и как планировщик обслуживает их. При одном пользователе разница между unified и non-unified KV может выглядеть иначе, чем при нескольких одновременных задачах.

Доступное описание не содержит точного определения этих режимов для использованной сборки, поэтому нельзя приписывать unified или non-unified KV универсальные свойства. Названия нужно сопоставить с документацией конкретной версии и с параметрами запуска benchmark.

Что означает unified и non-unified KV в рамках теста

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

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

Задача редакционного разбора здесь ограничена наблюдением: unified и non-unified KV способны менять суммарную пропускную способность при конкуренции. Конкретный победитель по имеющимся данным не установлен.

Один запрос и высокая конкуренция дают разные ответы

Один запрос в основном показывает latency и скорость генерации конкретной последовательности. Несколько запросов добавляют конкуренцию за VRAM, RAM, вычислительные блоки и пропускную способность памяти.

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

Тестировать нужно хотя бы два режима: последовательные запросы и параллельные. Число запросов, длину входа и объем генерации следует держать одинаковыми между unified и non-unified KV. Иначе сравнение покажет различие сценариев, а не режимов кэша.

Какие метрики нужны для AI-сервера, а не только для демо

  • Latency до первого токена. Показывает, сколько пользователь ждет начала ответа.
  • Скорость decode. Описывает темп выдачи токенов после обработки входа.
  • Скорость prefill. Показывает, как система обрабатывает входной контекст.
  • Суммарный throughput. Нужен для оценки нескольких одновременных запросов.
  • Пиковые RAM и VRAM. Помогают понять, останется ли запас под KV-кэш и системные процессы.
  • Ошибки и стабильность. OOM, зависания и сильный разброс времени важнее небольшого выигрыша в идеальном прогоне.

В отчет нужно добавить число одновременных запросов и их типичный контекст. Запись «модель выдает X токенов в секунду» без этих условий мало помогает выбрать конфигурацию для сервера.

Qwen3.8-Flash-Next в llama.cpp: как выбрать конфигурацию под свою нагрузку

Выбор начинается с нагрузки, а потом уже с объема VRAM. Для короткого диалога, анализа документов и нескольких параллельных запросов нужны разные измерения. Наблюдение о почти линейном росте до 96 ГБ VRAM полезно как ориентир конкретного benchmark, но переносить его на другую систему без повторной проверки нельзя.

Если важна максимальная скорость коротких интерактивных ответов

Сравните три точки: CPU-only, частичный offload и полную загрузку в доступную VRAM. В описанном тесте полная загрузка в 96 ГБ дала самый высокий результат на соответствующей шкале, а CPU-only использовался как нижняя контрольная точка.

Проверяйте отдельно время до первого токена и decode. Быстрый decode не компенсирует долгий prefill, если пользователь отправляет большие промпты. Для разработки и чата измерьте несколько типичных запросов, а не один короткий шаблон.

Если полная загрузка не помещается, частичный offload может оказаться рабочим компромиссом. Его результат определяют не проценты занятой VRAM, а цена обмена между устройствами и профиль конкретной модели.

Если важнее длинный контекст и большие документы

Сначала определите реальный размер контекста для документов, RAG и диалогов. Затем измерьте prefill, decode, пик KV-кэша и свободный запас RAM/VRAM. При длинном входе разрыв между конфигурациями может сокращаться, поэтому преимущество полной загрузки GPU нужно подтверждать именно на рабочем размере контекста.

Для больших документов полезнее стабильная конфигурация с запасом памяти, чем максимальная скорость короткого запроса. Если при добавлении контекста система начинает обращаться к RAM или вытеснять страницы, итоговая задержка может вырасти непропорционально.

Сравнение длинного контекста и KV-кэша стоит вести на одной версии llama.cpp. Смена runtime вместе с длиной контекста лишает тест контрольной точки.

Если модель должна обслуживать несколько запросов

Смотрите на unified и non-unified KV как на часть конфигурации сервера. Сравнивайте throughput, latency, пиковую память и стабильность при заданном числе запросов. Рейтинг для одного пользователя не переносится автоматически на многопользовательский режим.

Для домашнего AI-сервера заранее задайте рабочую конкуренцию: два параллельных запроса, несколько задач RAG или одновременный чат и генерация кода. Такой сценарий покажет, хватает ли памяти под KV-кэш и как меняется задержка при планировании батчей.

Сравнивать разные runtime полезно, но результаты нужно разделять по средам. Материал о запуске Qwen3.8-Flash-Next на четырех R9700 через vLLM помогает сформировать список проверок для распределения модели, памяти, prefill и generation. Он не заменяет измерение llama.cpp на собственном железе.

Короткий чек-лист перед выбором железа и параметров

  1. Сколько VRAM реально остается после запуска драйвера, рабочего стола и других процессов?
  2. Нужно ли помещать модель целиком или допустим частичный GPU offload?
  3. Какой контекст нужен в обычной работе, а не в теоретическом максимуме?
  4. Сколько запросов может выполняться одновременно?
  5. Нужна ли быстрая загрузка после перезапуска или важнее длительный непрерывный инференс?
  6. Используется ли mmap, и проверено ли состояние page cache?
  7. Где размещается PLE-таблица, какой режим unified или non-unified KV выбран и как это влияет на память?
  8. Измерены ли отдельно prefill, decode, latency до первого токена и суммарный throughput?
  9. Повторен ли тест на той же версии llama.cpp, CUDA и драйвера, которые будут работать постоянно?

Ответы на эти вопросы дают более надежный выбор, чем сравнение объема VRAM в отрыве от контекста и конкуренции.

Что этот benchmark доказывает, а что остается непроверенным

Описанные результаты полезны как набор наблюдений: GPU-размещение меняет скорость, полная загрузка в 96 ГБ VRAM связана с почти линейным ростом в конкретном тесте, длинный контекст сближает результаты, а перенос PLE в CUDA дает аномальный провал. Каждый пункт требует собственных условий проверки.

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

  • точная версия Qwen3.8-Flash-Next и формат файла модели;
  • квантизация и размер файла;
  • версия llama.cpp, параметры сборки и выбранный backend;
  • версия CUDA, драйвера и операционной системы;
  • модель CPU, GPU, объем RAM и доступный объем VRAM;
  • режим CPU-only, частичный offload или полная загрузка;
  • длина контекста, размер входа и объем генерируемого ответа;
  • настройки mmap и RAM-resident loading;
  • расположение PLE и режим unified или non-unified KV;
  • число параллельных запросов, размер батча и порядок прогрева;
  • единицы измерения, число повторов, prefill, decode, latency и пиковое потребление памяти.

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

Где заканчивается вывод о модели и начинается вывод о runtime

Почти линейный рост при увеличении GPU-размещения описывает поведение связки Qwen3.8-Flash-Next, llama.cpp и конкретного железа. Он не доказывает, что любая модель даст такую же кривую.

Сближение на длинном контексте может быть связано с KV-кэшем, памятью или prefill. Провал PLE может зависеть от CUDA backend, драйвера, способа доступа или конкретного кода. Разница unified и non-unified KV проявляется через организацию памяти и планирование запросов. Ни один из этих эффектов нельзя автоматически приписывать архитектуре самой модели.

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

Как сформулировать итог без необоснованных обещаний

Для описанного benchmark дополнительная VRAM заметно ускоряет Qwen3.8-Flash-Next, когда она убирает обмен с CPU. Длинный контекст меняет профиль нагрузки и способен сократить разрыв между конфигурациями. Провал при переносе PLE в CUDA требует отдельной диагностики. Режим mmap, RAM-resident loading и схема KV-кэша нужно выбирать по длине контекста, числу запросов и доступной памяти.

Практический следующий шаг, собрать собственную таблицу с CPU-only, частичным offload и полной загрузкой, затем повторить ее для короткого и рабочего длинного контекста. В каждой строке фиксируйте версию llama.cpp, параметры памяти, prefill, decode, latency, throughput и пиковые RAM/VRAM. Только такая методика показывает, какая конфигурация подходит именно вашему локальному запуску Qwen3.8-Flash-Next.

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