Что получилось: Qwen3 27B INT4, 144K контекста и 24 ГБ VRAM
Qwen3 27B в квантовании INT4 AutoRound запускается на одной RTX 3090 с 24 ГБ VRAM и держит контекст 147 456 токенов, это примерно 144K. KV-кэш хранится в FP8 E4M3. Связка, на которой получен результат: vLLM 0.27.1 плюс патч из репозитория Club 3090.
Замеры автора: BenchLocal 71/75 (94,7%) при reasoning_effort=low, средний prefill 871,93 tok/s, средний decode 38,39 tok/s. На промпте 90K токенов prefill держится на 743,59 tok/s, decode на 34 tok/s. Просадка на длинном промпте умеренная: около 15% по prefill и около 11% по decode.
Старт дался не автоматически: чтобы обойти OOM, автор перешёл на AOT-компиляцию вместо JIT, выставил gpu-memory-utilization=0,9475 и max-num-seqs=1. Речь идёт об опыте одного пользователя на одной машине, независимого лабораторного теста здесь нет, поэтому цифры стоит читать как ориентир.
Дальше: состав конфигурации, роль патча, расчёт памяти под 144K и места, где настройка ломается.
Железо и софт: что нужно для повторения
Набор компонентов узкий, зато чувствительный к версиям:
- GPU: RTX 3090, 24 ГБ VRAM.
- Модель: Qwen3 27B в квантовании INT4 AutoRound.
- Движок: vLLM 0.27.1.
- Патч: репозиторий Club 3090.
- Диск: 5-6 ГБ под кэш компиляции vLLM. Это дисковое место, а не VRAM.
Версию CUDA автор не называет, так что подставляйте ту, с которой собирается выбранная сборка vLLM. Патч и обвязка рассчитаны на конкретный релиз движка: на другой версии расходятся и флаги, и поведение компилятора, а значит повторить конфигурацию один в один не получится.
Почему нужен патч Club 3090
Штатный vLLM на 24 ГБ не даёт выставить такое окно и падает либо на старте, либо на этапе выделения памяти под KV-кэш. Патч из Club 3090 снимает часть ограничений и позволяет движку принять max-model-len 147 456. Решение стороннее: его ведёт сообщество, а не команда vLLM. Совместимость с будущими релизами никто не гарантирует, поэтому рабочую версию лучше зафиксировать и не обновлять вслепую.
AOT-компиляция вместо JIT: зачем и как
При обычном запуске vLLM компилирует часть ядер на ходу, в режиме JIT. Пик памяти в этот момент накладывается на уже загруженные веса и растущий KV-кэш, и на карте с 24 ГБ это заканчивается OOM ещё до первого запроса. AOT-компиляция (ahead-of-time) готовит ядра заранее, старт проходит с меньшим пиковым расходом, и модель поднимается с заданной длиной контекста.
Плата: время на подготовку и 5-6 ГБ дискового кэша компиляции. Меняете параметры или версию движка, кэш собирается заново.
Настройка vLLM: параметры, которые решают
Картину определяют четыре значения: gpu-memory-utilization=0,9475, max-num-seqs=1, max-model-len=147456 и KV-кэш FP8 E4M3. Минимальный набор в командной строке выглядит так:
vllm serve <модель> \
--gpu-memory-utilization 0.9475 \
--max-num-seqs 1 \
--max-model-len 147456 \
--kv-cache-dtype fp8
Точные имена флагов сверяйте со своей сборкой: патч и версия движка могут менять и синтаксис, и значения по умолчанию. Команду удобнее держать в скрипте запуска вместе с подготовкой AOT-кэша, тогда перезапуск после подбора параметров занимает меньше времени.
Расчёт памяти: как 144K контекста умещаются в 24 ГБ
Работают три рычага. INT4 хранит 4 бита на параметр вместо 16 у FP16, то есть веса занимают примерно вчетверо меньше места. FP8 E4M3 для KV-кэша режет память под ключи и значения примерно вдвое относительно FP16. max-num-seqs=1 оставляет один активный запрос, и весь бюджет VRAM уходит на одно длинное окно, а не распыляется между несколькими короткими.
gpu-memory-utilization=0,9475 разрешает движку занять почти всю память карты. Это значение подобрано на конкретной системе, а не выведено из формулы: на другой карте, другом драйвере или при работающем рабочем столе оно даст OOM. Начинайте ниже и поднимайте шагами по 0,01, каждый раз проверяя, что модель принимает заявленную длину контекста.
Посмотреть, как считают бюджет памяти и размещение слоёв на карте с меньшим объёмом, полезно в материале про запуск Qwen3.8-27B в true Q4_K_M на RTX 5080 с 16 ГБ: там KV-кэш и вытеснение слоёв разбираются отдельно от веса модели.
Что такое FP8 E4M3 KV-кэш и почему он важен
KV-кэш держит ключи и значения внимания для каждого обработанного токена, и его размер растёт вместе с длиной контекста. FP8 E4M3: 8 бит на элемент, из них 4 на экспоненту, 3 на мантиссу и 1 на знак. Хранение в FP16 заняло бы вдвое больше памяти, и 147 456 токенов в 24 ГБ уже не поместились бы.
Точность у FP8 ниже, чем у FP16, поэтому квантование кэша теоретически может сказаться на качестве ответов. В описанном кейсе BenchLocal дал 71/75, но это один прогон на одном наборе задач.
Бенчмарки: 71/75 в BenchLocal и скорость на 90K промпте
Итог прогона: 71/75, то есть 94,7%, при reasoning_effort=low. Четыре задания из 75 модель не прошла.
Что именно проверял BenchLocal
- tool calling: вызовы инструментов с корректными аргументами;
- следование инструкциям;
- структурированный вывод, включая JSON;
- извлечение данных из текста;
- reasoning и математика.
Категории закрывают типовые задачи локального ассистента, но проверку на ваших данных не заменяют. Ограничение важное: reasoning_effort=low. На высоком уровне рассуждений модель тратит больше токенов на «размышление», и итог может отличаться в обе стороны; данных для такой оценки в описании кейса нет.
Скорость на длинном контексте: 90K токенов
| Показатель | Среднее | Промпт 90K |
|---|---|---|
| Prefill, tok/s | 871,93 | 743,59 |
| Decode, tok/s | 38,39 | 34 |
Просадка на длинном промпте умеренная: prefill теряет около 15%, decode около 11%. 34 tok/s на генерации хватает для диалога и пошаговых агентных сценариев, но не для потоковой выдачи больших объёмов текста. Замеры сделаны автором на одном стенде, на другой машине разброс будет заметным.
vLLM или llama.cpp: что выбрать для 24 ГБ и длинного контекста
Разница в характере настройки. vLLM в этом кейсе дал 147 456 токенов и prefill в районе 700-870 tok/s, но заплатить пришлось патчем, AOT-компиляцией и подбором gpu-memory-utilization. llama.cpp в описанной конфигурации не участвовал, прямого сравнения на одном стенде нет.
Что известно про llama.cpp на 24 ГБ из других разборов: на RTX 4090 окно доводили до 194 048 токенов без MTP, а с включённым MTP скорость генерации вырастала до 65-80 токенов/с при сокращённом контексте. Другой движок, другой сценарий, другая кривая компромиссов: сравнивать цифры из разных статей бессмысленно, важнее поведение на вашей задаче.
Практическое правило простое. Нужен максимальный контекст вместе с высокой скоростью prefill, и вы готовы возиться с патчем: берите vLLM. Приоритет на быстрый запуск, меньше зависимостей и предсказуемость: смотрите в сторону llama.cpp, но сначала убедитесь, что нужная длина окна реально поднимается. Отдельно стоит понимать, как в vLLM проверяют распределение модели, память, квантование, prefill и generation, чтобы отличать воспроизводимый бенчмарк от красивого заявления.
Подводные камни и ограничения конфигурации
- max-num-seqs=1 означает один запрос за раз. Для личного использования нормально, для сервера на несколько клиентов не подходит: пропускная способность при батчинге низкая.
- gpu-memory-utilization=0,9475 подобрано под конкретный стенд. Сменился драйвер, добавился браузер с аппаратным ускорением, и старт упирается в OOM.
- Кэш компиляции занимает 5-6 ГБ на диске, плюс время на его сборку. После смены настроек или версии движка он пересобирается.
- Патч Club 3090 сторонний: обновление vLLM может его сломать, поддержку никто не обещает.
- INT4 снижает точность весов относительно FP16. Результат 71/75 получен при reasoning_effort=low и на другие режимы автоматически не переносится.
- Длинный контекст не бесплатен по времени: обработка промпта на 90K токенов занимает секунды, и в интерактивных сценариях это чувствуется.
Настройка требует времени на первый запуск, терпения к подбору параметров и готовности держать под неё отдельный запуск.
Кому стоит повторять этот сетап
Два условия: 24 ГБ VRAM и реальная потребность в длинном окне. Подойдёт, если вы гоняете RAG по большой документации, разбираете длинные файлы, ведёте агентные цепочки с длинной историей или делаете локальный ассистент для одного пользователя.
Не подойдёт как сервер с параллельными запросами: max-num-seqs=1 закрывает этот сценарий. Тем, кто не хочет возиться с патчами, стоит сначала посмотреть на более простые пути: кейс с Qwen 3 и контекстом 200K+ на 16 ГБ VRAM показывает, что длинное окно достижимо и без патчей vLLM, хотя компромиссы по квантованию и скорости там другие.
Если повторяете: возьмите vLLM 0.27.1, патч Club 3090, INT4 AutoRound, выставьте max-num-seqs=1 и max-model-len 147456, включите AOT-компиляцию, а gpu-memory-utilization подбирайте от меньшего значения вверх. Цифры на вашем железе будут отличаться от приведённых, и это нормально.