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

Как ускорить Qwen 3.8 в llama.cpp для harness-режима и длинного контекста на RTX 3090 в 2026

Практическая настройка Qwen 3.8 в llama.cpp на RTX 3090 для harness и длинного контекста. Разбираем batch, ub, cache-prompt, speculative decoding, ctk/ctv, KV-c

Коротко

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

  1. 01

    Короткий ответ: что менять в первую очередь

  2. 02

    Что именно тормозит Qwen 3.8 в llama.cpp

  3. 03

    Batch и ub: первый рычаг для ускорения prefilling

  4. 04

    Cache-prompt в harness-режиме: как не считать одно и то же повторно

Для Qwen 3.8 в llama.cpp на RTX 3090 настройку лучше начинать с batch и ub: они сильнее всего влияют на обработку больших входных промптов. Затем включается cache-prompt, чтобы повторно не считать одинаковые системные инструкции, историю и файлы. После этого отдельно проверяются spec-draft-n-max, spec-draft-p-min и параметры KV-cache ctk/ctv.

В harness-режиме ориентиром служит полный wallclock time, а не одна цифра generation t/s. Агент может тратить больше времени на повторный prefill длинного контекста, чем на сам вывод ответа. Увеличение скорости почти всегда требует дополнительной VRAM, поэтому максимальные значения параметров не считаются целью сами по себе.

Практический порядок такой: зафиксировать GGUF и сборку llama.cpp, измерить базовые prefill и generation, постепенно поднять batch и ub, включить cache-prompt, затем протестировать speculative decoding. Параметры ctk/ctv и асимметричный cache стоит трогать после получения стабильной базовой конфигурации.

Короткий ответ: что менять в первую очередь

Базовый порядок настройки

  1. Зафиксируйте модель, GGUF-квантизацию, версию llama.cpp, размер контекста и число параллельных слотов.
  2. Запишите базовые значения prefill t/s, generation t/s, времени до первого токена и полного времени harness-сценария.
  3. Повышайте batch и ub по одному шагу, пока GPU сохраняет стабильность и не возникает нехватка памяти.
  4. Включите cache-prompt, если вызовы используют общий префикс: системные инструкции, описание проекта, правила агента или неизменяемые файлы.
  5. Подберите spec-draft-n-max и spec-draft-p-min для generation. Каждый параметр меняйте отдельно.
  6. Сравните варианты ctk/ctv и асимметричного cache только на целевой длине контекста и с повторяемым сценарием.

На RTX 3090 нельзя заранее назвать универсальные значения batch, ub, длины чернового блока или коэффициентов KV-cache. На результат влияют размер и квантовка Qwen 3.8, число слоёв на GPU, длина промпта, запас VRAM и конкретная сборка llama.cpp.

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

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

Например, generation на уровне 8-10 токенов в секунду выглядит приемлемо для короткого ответа, но длинный вход может обрабатываться десятки секунд. При повторных вызовах cache-prompt способен сократить именно эту часть задержки, если структура промпта позволяет использовать сохранённый префилл.

Что именно тормозит Qwen 3.8 в llama.cpp

Prefill и generation: разные задачи для GPU

Prefill обрабатывает уже готовую последовательность входных токенов. На этом этапе GPU может работать крупными порциями, поэтому batch и ub заметно влияют на скорость длинного промпта.

Generation создаёт новые токены последовательно. Здесь важны состояние KV-cache, пропускная способность памяти и возможность принять несколько предложенных draft-токенов за один шаг проверки. Speculative decoding относится прежде всего к этому этапу.

Полное время harness складывается из prefill, generation, ожидания между вызовами, обработки tool calling и операций самого рантайма. Ускорение одного этапа не гарантирует сокращение всего сценария.

Как читать логи llama.cpp

В логах llama.cpp ищите размер контекста, строку n_ctx_slot, режим kv_unified, скорость prompt processing и скорость generation. Эти значения помогают отделить проблему входного промпта от медленного декодирования.

В одном из приведённых логов указано n_ctx_slot = 131072 и kv_unified = true. Скорость обработки менялась по мере роста входа: около 78,31 t/s на 2048 токенах, 87,22 t/s на 4096, 59,40 t/s на 4202 и 67,01 t/s на 6238 токенах. Generation в тех же данных держалась примерно в диапазоне 7-10 t/s.

Такой разброс не даёт права объявлять одну цифру характеристикой всей модели. На результат влияют состояние кэша, размер порций, доступная память и текущая нагрузка. Для сравнения нужны одинаковые условия.

Batch и ub: первый рычаг для ускорения prefilling

Почему большие значения ускоряют обработку промпта

batch задаёт общий объём токенов, который рантайм может обрабатывать в одном крупном проходе. ub, или micro-batch, ограничивает размер отдельных порций, передаваемых вычислительным ядрам. На длинных входах увеличение этих параметров помогает лучше загрузить GPU и уменьшить число проходов.

На коротких запросах эффект может быть небольшим: там заметную долю времени занимают запуск ядер, передача данных и подготовка запроса. На больших промптах прирост обычно заметнее. Материалы по llama.cpp указывают на возможность кратного ускорения prefilling при высоких значениях batch и ub, но предупреждают о дополнительном расходе видеопамяти.

Где остановиться на RTX 3090

У RTX 3090 24 ГБ VRAM, и этот объём делят веса модели, рабочие буферы, KV-cache, draft-модель и временные структуры. Большой контекст резко увеличивает расход памяти под KV-cache, поэтому значение, которое запускается на коротком промпте, может завершиться ошибкой при реальной нагрузке.

Повышайте параметры ступенчато. После каждого изменения проверяйте:

  • ошибки выделения памяти и внезапное завершение сервера;
  • переход части вычислений в RAM или mmap;
  • скачок времени до первого токена;
  • скорость на целевой длине контекста;
  • полное время нескольких последовательных harness-вызовов.

Остановиться нужно на последнем стабильном значении, которое сокращает wallclock time. Самое большое число в командной строке не приносит пользы, если сервер начинает выгружать данные в медленную память.

Почему нестабильная конфигурация не считается успешным ускорением

Показателен пример системы с 16 ГБ VRAM, 32 ГБ RAM и NVMe: для неё приводились значения около 20 t/s на prefilling и 10 t/s на generation, но конфигурация оставалась нестабильной. Такой результат нельзя считать рабочим профилем для harness.

Автоматизация создаёт длинные и повторяющиеся нагрузки. Ошибка памяти на шестом запросе, скачок задержки после заполнения KV-cache или падение сервера сводят разовый прирост скорости к нулю. Стабильность должна входить в критерии измерения наравне с t/s.

Cache-prompt в harness-режиме: как не считать одно и то же повторно

Какие части harness-контекста выгодно кэшировать

cache-prompt полезен при повторном использовании большого префикса. В него могут входить системные инструкции, правила агента, описание репозитория, формат ответов, список инструментов и файлы, которые не меняются между вызовами.

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

Когда cache-prompt почти не помогает

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

Кэширование не заменяет настройку batch, ub и контекста. Оно сокращает повторные вычисления, но не ускоряет первый холодный запуск и не уменьшает стоимость уникальной части запроса.

Как сравнивать эффект по wallclock time

Сравните одну и ту же последовательность harness-вызовов в двух режимах: с холодным кэшем и после его заполнения. Зафиксируйте время до первого токена, время полного ответа и суммарное время сценария.

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

Связь между повторяющимися запросами, KV-cache и размещением данных хорошо видна в разборе локального стека Qwen 3.8 на двух RTX 3090: как связаны VRAM, RAM, NVMe и кэширование длинных запросов.

Speculative decoding: настройка spec-draft-n-max и spec-draft-p-min

Что меняет spec-draft-n-max

Speculative decoding использует draft-модель или draft-контур, который предлагает несколько следующих токенов. Основная модель проверяет предложение одним или несколькими проходами. Если кандидаты хорошо совпадают, за шаг принимается больше токенов, и generation ускоряется.

spec-draft-n-max задаёт верхнюю границу длины чернового предложения. Большое значение повышает потенциальное число принятых токенов, но требует дополнительной памяти и не гарантирует ускорение. При слабом совпадении draft и основной модели длинный блок может чаще проверяться с малой пользой.

Что меняет spec-draft-p-min

spec-draft-p-min задаёт минимальный порог, связанный с принятием draft-кандидатов. Слишком строгий порог уменьшает число принятых токенов. Слишком мягкий порог может увеличить число неэффективных предложений и проверок.

Подбирать этот параметр нужно по полному времени ответа. Высокая доля принятых токенов сама по себе не доказывает выигрыш: накладные расходы draft-модели и проверок могут съесть результат.

Как проверять speculative decoding на стабильность

Начните с базового запуска без speculative decoding и сохраните его метрики. Затем включайте draft-контур, меняя только один параметр. Тестируйте несколько последовательных ответов на целевой длине контекста, контролируйте VRAM, RAM, задержки и ошибки сервера.

Если после включения speculative decoding generation ускорилась, но выросло общее время harness, конфигурация не достигла цели. Возврат к базовой точке помогает быстро понять, связан ли провал с n-max, порогом принятия или нехваткой памяти.

Практические компромиссы между batch, MTP, KV-cache и длиной контекста подробно разобраны в статье о запуске Qwen 3.8 27B на 24 ГБ VRAM: разбор конфигурации llama.cpp для RTX 4090.

Длинный контекст и KV-cache: почему 131072 токенов нельзя считать бесплатными

Размер контекста против реально полезной длины

n_ctx_slot = 131072 показывает доступный потолок контекста для слота. Параметр не обещает одинаковую скорость на любой длине и не означает, что 131072 токена станут удобным рабочим размером для RTX 3090.

При выборе контекста оставляйте запас под веса Qwen 3.8, рабочие буферы, batch, ub, KV-cache и speculative decoding. Если harness обычно использует 32K или 64K токенов, выставлять 131K автоматически нерационально: резерв памяти может уйти на неиспользуемый потолок.

Как VRAM, RAM и NVMe меняют поведение системы

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

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

Почему скорость prefilling меняется по мере роста промпта

На длинном входе скорость может меняться неравномерно. В приведённом логе обработка 2048 токенов шла со скоростью 78,31 t/s, 4096 токенов, 87,22 t/s, а на отрезках 4202 и 6238 токенов показатель снижался до 59,40 и 67,01 t/s.

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

ctk и ctv: настройка асимметричного cache без лишней сложности

Зачем разделять настройки cache

KV-cache хранит состояние уже обработанного контекста. Компоненты ключей и значений по-разному участвуют в вычислениях и по-разному влияют на расход памяти, поэтому одинаковый режим для них не всегда даёт лучший результат.

Параметры ctk и ctv позволяют рассматривать эти части раздельно, если конкретная сборка llama.cpp поддерживает соответствующие режимы. Подбор должен учитывать квантовку модели, размер контекста, доступную VRAM и влияние на качество ответов.

Когда асимметричный cache помогает

Асимметричный cache оправдан, когда он позволяет сохранить вычислительно тяжёлые части в быстрой памяти, уменьшить обращения к RAM или вместить нужный контекст без падения стабильности. В отдельных схемах обсуждается размещение ngram в mmap при сохранении остальных вычислительно важных частей в VRAM или RAM.

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

Когда лучше оставить базовую схему

Базовый cache лучше сохранить, если асимметрия не сокращает wallclock time, увеличивает расход памяти или вызывает скачки задержек. Дополнительная сложность оправдана только при измеримом выигрыше.

Сначала зафиксируйте стабильный запуск с понятными параметрами. После этого меняйте ctk и ctv по одному. Такой порядок упрощает откат и помогает отделить влияние cache от эффекта batch или speculative decoding.

Сравнение разных рантаймов и поведения cache на длинном контексте можно дополнить материалом о prefill, decode и warm cache: почему скорость prefill и decode зависит от выбранного рантайма.

Практический протокол настройки Qwen 3.8 на RTX 3090

Сначала зафиксировать базовую точку

Запишите следующие параметры:

  • название и квантовку GGUF;
  • версию и параметры сборки llama.cpp;
  • размер контекста и число слотов;
  • значения batch и ub;
  • режим KV-cache и параметры ctk/ctv;
  • наличие cache-prompt и speculative decoding;
  • объём занятой VRAM и RAM;
  • prefill t/s, generation t/s, время до первого токена и полное wallclock time.

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

Менять по одному фактору

ШагЧто меняетсяЧто измерять
1Базовый запускPrefill, generation, wallclock, память
2batchСкорость длинного входа и стабильность
3ubPrefill, VRAM и задержки
4cache-promptХолодный и тёплый wallclock time
5spec-draft-n-maxGeneration и полное время ответа
6spec-draft-p-minПринятие draft-токенов и стабильность
7ctk/ctvПамять, качество и время сценария
8Размер контекстаРабочую длину, VRAM и задержки

Если используется команда запуска, сохраняйте её как отдельный вариант конфигурации. Для параметров, синтаксис которых меняется между сборками, сверяйтесь с локальным выводом справки llama.cpp. Это особенно важно для экспериментальных режимов KV-cache и draft-моделей.

Критерии удачной конфигурации

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

Проверяйте несколько последовательных вызовов. Один удачный ответ не показывает, как поведёт себя сервер после заполнения контекста, серии tool calls или смены длины входного промпта.

Типичные ошибки при ускорении llama.cpp

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

Значение 131072 в n_ctx_slot описывает доступный лимит, а не гарантированную производительность. Большой KV-cache расходует память и оставляет меньше места под batch, ub и draft-контур.

Выбирайте контекст по реальным задачам. Если рабочие запросы редко превышают 32K токенов, запас памяти может принести больше пользы, чем формальный лимит 131K.

Сравнивать только отдельные показатели t/s

Высокая generation speed может компенсироваться долгим prefill. Быстрый prefill тоже не всегда сокращает полный сценарий, если модель часто вызывает инструменты или перегружает контекст новыми данными.

Минимальный набор метрик: prefill t/s, generation t/s, время до первого токена, время полного ответа и суммарный wallclock time harness-сценария.

Считать нестабильную конфигурацию оптимальной

Ошибки памяти, неожиданный offload, скачки задержек и падения llama_server требуют уменьшить нагрузку. Сначала пересмотрите размер контекста, затем batch, ub и speculative decoding.

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

Итоговая схема выбора настроек

Если главным тормозом является prefilling

Начните с batch и ub. Повышайте их до границы стабильной VRAM. Затем проверьте cache-prompt, если в запросах повторяются системные инструкции, история, описание репозитория или неизменяемые файлы.

Если главным тормозом является generation

Тестируйте speculative decoding. Подбирайте spec-draft-n-max и spec-draft-p-min вместе с доступной памятью и качеством draft-предсказаний. Смотрите на полное время ответа, а не только на количество принятых токенов или generation t/s.

Если упираемся в VRAM на длинном контексте

Сначала определите минимальную длину контекста, которая покрывает задачу. Затем пересмотрите batch, ub и speculative decoding. После этого изучите ctk/ctv и асимметричный cache. RAM и NVMe используйте как способы разместить конфигурацию, но проверяйте их влияние на wallclock time.

Для задач на RTX 3090 главный принцип остаётся практическим: длинные повторяющиеся промпты требуют сочетания высокого, но стабильного batch/ub и cache-prompt; generation может выиграть от подходящего draft-контура; дефицит VRAM сначала лечится сокращением лишнего контекста и нагрузки cache. Каждое изменение подтверждайте одинаковым harness-тестом.

Сравнить подходы к параметрам llama.cpp на другом классе GPU можно в разборе Qwen 3.6 27B на RTX 5090: как batch, KV-cache и speculative decoding меняют производительность.

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