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

Вы указали для локального Qwen окно 128K, но запуск падает примерно на 72K, резко замедляется или выдаёт ответ, не учитывая условия из начала prompt. Обычно дело не в одном параметре: реальный предел складывается из квантизации весов, формата KV-кэша, реализации бэкенда и того, как нагрузка разложена по GPU.
Ниже — порядок проверки, который можно повторить на своей машине. Сначала вы отделите нехватку памяти от проблем скорости и качества дальнего контекста, а затем по одному сравните KV-кэш, бэкенд, квантизацию модели и распределение между видеокартами.
Прямой ответ: заданное окно — это верхняя граница, а не гарантия
Параметр 128K лишь просит бэкенд подготовиться к входу такого размера. Конфигурация работает только пока сходится баланс памяти:
веса модели + KV-кэш + рабочая память рантайма + запас ≤ память, которой реально может пользоваться бэкенд
Веса занимают большую, почти постоянную часть памяти после загрузки. KV-кэш растёт вместе с числом сохранённых token, а временные буферы зависят от бэкенда, batch-настроек и используемых ядер. Даже если всё поместилось, скорость или способность модели достать факт из начала текста могут стать неприемлемыми раньше физического лимита.
Поэтому нужно ответить на три разных вопроса: помещается ли запрос, выполняется ли он достаточно быстро и использует ли модель весь переданный контекст. Число 128K в интерфейсе само по себе этого не показывает.
Сначала определите тип сбоя
Фраза «не доходит до 128K» может описывать совершенно разные ситуации. Отнесите свой случай к одной из них, иначе легко начать оптимизировать не тот слой.
| Симптом | Куда смотреть в первую очередь | Первая проверка |
|---|---|---|
| При загрузке или создании длинного контекста сразу возникает OOM | Веса и KV-кэш конкурируют за память; одна карта не может выделить свою часть | Запишите пик и свободную память отдельно на каждой GPU |
| Ошибка возникает почти на одном и том же числе token | Формат KV-кэша, реализация бэкенда или граница выделения памяти | Зафиксируйте модель и железо, меняйте только кэш или бэкенд |
| Вход принимается, но обработка prompt или генерация становятся слишком медленными | Пропускная способность памяти, обмен между GPU, ядра или чрезмерная длина | Измеряйте prefill и генерацию отдельно |
| Ответ генерируется, но ранние условия забываются | Качество эффективного контекста, а не только объём памяти | Разместите контрольные факты по всей длине входа |
| Один и тот же тест то проходит, то падает | Слишком маленький запас, параллельная нагрузка или нестабильный рантайм | Уберите другие процессы и повторите запуск три раза |
Если всё помещается, но работает слишком медленно, более компактный KV-кэш не обязательно решит задачу. Если память есть, но модель не помнит начало, дополнительная VRAM сама по себе тоже не гарантирует улучшения.
Что показывает пример перехода с 72K на 128K
В публикации от 23 сентября 2026 года Nigel Hungerford-Symes описал запуск Qwen3.8-27B (Unsloth UD-Q5_K_M) на RTX 5060 Ti 16GB и RTX 3070 8GB. Для варианта 128K он указал beellama.cpp + kvarn5 KV + MTP n=2, около 36 tok/s на коротком контексте и 18 tok/s при 126K. Ранее связка mainline llama.cpp и q8_0 KV, по его словам, упиралась примерно в 72K.
Этот пример полезен тем, что на одной конкретной машине предел изменился вместе со стеком инференса. Но одновременно поменялись бэкенд, схема KV-кэша и другие настройки. Поэтому из него нельзя сделать вывод, что один только kvarn5 добавил 56K контекста, а приведённые скорости будут такими же на другой системе.
Используйте публикацию как подсказку для диагностики: если предел стабильно повторяется на одной длине, проверяйте не только файл модели, но и KV-кэш с бэкендом.
Зафиксируйте базовую конфигурацию до любых изменений
Сохраните воспроизводимую базу, прежде чем переделывать стек. Иначе после удачного запуска вы всё равно не поймёте, какая именно замена помогла.
| Область | Что записать |
|---|---|
| Модель | Полное имя, точный файл, квантизация весов, размер файла |
| Бэкенд | Название, версия или commit, способ запуска |
| Контекст | Запрошенное окно, фактический вход в token, резерв на выход |
| KV-кэш | Тип или схема, размещение в GPU либо RAM, параметры сжатия |
| Железо | Модель и VRAM каждой GPU, объём RAM, топология PCIe |
| Размещение | Разделение по GPU, offload, переходы между устройствами |
| Рантайм | Batch, параллельность, sampling, максимальный выход |
| Результат | Успех или ошибка, полный текст ошибки, пик VRAM/RAM, скорость prefill и генерации |
Не считайте 16GB и 8GB двумя половинами единого пула на 24GB. Бэкенд решает, где лежат веса, KV-кэш и рабочие буферы. Одна карта может заполниться раньше другой, а обмен между устройствами — съесть выигрыш от длинного окна.
Меняйте четыре переменные по одной
1. Квантизация весов меняет постоянный объём
Квантизация модели в первую очередь определяет, сколько памяти занимают веса. Более компактный файл может освободить место для KV-кэша, но сам по себе не обещает более длинный рабочий контекст и способен изменить качество или скорость.
Чтобы проверить, вытесняют ли веса кэш, оставьте прежними бэкенд, формат KV-кэша и тестовый prompt. Поменяйте только квантизацию весов, затем сравните освобождённую память и длину, на которой возникает сбой.
2. Формат KV-кэша меняет расход на каждый сохранённый token
KV-кэш хранит состояния, которые модель повторно использует при следующих шагах. Для фиксированной модели и одного представления его объём обычно растёт примерно вместе с числом сохранённых token. Поэтому это самый прямой рычаг для длинного контекста.
При сравнении двух схем смотрите сразу на три результата: пик памяти, максимальную стабильную длину и точность дальнего извлечения. Победа «128K поместились» мало что значит, если модель стала хуже вспоминать ранние факты или бэкенд работает нестабильно.
3. Бэкенд определяет, как кэш и распределение работают на практике
Бэкенды различаются компоновкой кэша, выделением памяти, распределением по GPU и ядрами. Одинаковый размер окна и тот же файл модели не обязаны давать одинаковую кривую памяти или скорость.
Если новый бэкенд требует другой KV-кэш, формулируйте результат честно: «эта связка прошла тест». Не приписывайте весь выигрыш одному формату. Для отделения влияния бэкенда проведите ещё один A/B на общих для обоих вариантах настройках, если это возможно.
4. Размещение на железе определяет, какой ресурс закончится первым
Главная ошибка в multi-GPU — смотреть только на сумму VRAM. Запуск может падать из-за нехватки памяти на одной карте, концентрации KV-кэша на одном устройстве, отсутствия запаса под рабочий буфер или слишком дорогого обмена по PCIe.
Снимайте показатели по каждой GPU отдельно. Если одна почти заполнена, а на другой остаётся заметный запас, сначала исправьте split или placement и только потом жертвуйте качеством модели.
Проведите ступенчатый тест длинного контекста
Не переходите от короткого prompt сразу к 128K. Фиксированная лестница длин покажет, возникает ли резкая граница или система постепенно теряет практичность.
Подходящий стартовый набор: 8K → 32K → 64K → 72K → 96K → 126K. Точка 126K близка к 128K и оставляет явный бюджет для ответа. Если вам нужен длинный вывод, увеличьте этот резерв и уменьшите вход.
Подготовьте один контролируемый набор входов
- Считайте token тем tokenizer, который действительно использует модель; не оценивайте их по символам или размеру файла.
- На отметках примерно 10%, 20% и далее до 90% разместите разные контрольные факты, например
ORBIT-17 = copper. - В начале, середине и конце добавьте по одному условию кода, а в финале попросите перечислить условия и сделать небольшую правку.
- На всех длинах сохраняйте порядок материала, sampling и бюджет ответа.
- Уберите фоновую нагрузку и повторите каждую ключевую длину три раза.
Контрольные факты измеряют извлечение, но не заменяют проверку реальной coding-задачи. В окончательный прогон добавьте код, логи или документацию репозитория, похожие на вашу обычную работу.
Для каждого запуска собирайте одинаковые показатели
| Показатель | Что он показывает |
|---|---|
| Фактический размер входа в token | Принял ли бэкенд целевую длину |
| Результат выделения и точная ошибка | Где ломается объём или совместимость |
| Пик памяти каждой GPU и RAM | Какое устройство стало узким местом |
| Время или скорость обработки prompt | Приемлем ли длинный prefill |
| Скорость генерации | Можно ли пользоваться системой после длинного входа |
| Число найденных контрольных фактов | Использует ли модель дальнюю информацию |
| Выполнение условий кода | Помогает ли окно реальной задаче |
Запишите критерий прохождения до теста. Например: три успешных запуска подряд на целевой длине, ни одной ошибки памяти или бэкенда, не менее 9 правильных контрольных фактов из 10 и время в пределах вашего рабочего лимита. 9/10 — только пример; важнее выбрать порог заранее, а не снижать его после красивого запуска на 128K.
Выберите действие по результату
Система стабильно получает OOM на одной длине
Сначала найдите устройство, которое заполняется первым. Если запас съедает растущий KV-кэш, сравните более компактную схему. Если после загрузки весов места почти не остаётся, проверьте меньшую квантизацию модели. В каждом прогоне меняйте один пункт и смотрите, сдвинулся ли предел ожидаемым образом.
Новый бэкенд доходит до 128K, старый останавливается на 72K
Считайте новый стек кандидатом, но воспроизведите результат три раза и проверьте дальнее извлечение. Пока вместе изменились бэкенд и кэш, доказан только успех всей связки, а не одна корневая причина.
128K завершаются, но слишком медленно
Это эксплуатационная граница, а не нехватка объёма. Оставьте меньшее окно по умолчанию и включайте сверхдлинный контекст только для редких задач, либо сравните меньшую модель, другой бэкенд и иное размещение. «Может запуститься» и «удобно использовать каждый день» — разные решения.
128K работают, но модель теряет начало
Рассматривайте это как проблему эффективного контекста. Запустите тот же prompt на 64K, 72K и 96K и постройте кривую recall. Если короткие варианты заметно надёжнее, установите production-предел там, где проходит качество, а не там, где срабатывает allocation. Для огромных репозиториев также полезны поиск, разбиение и предварительное сокращение нерелевантных материалов.
Оптимизируйте проверенное рабочее окно, а не максимальное число в меню
Если 72K уже покрывают ваши обычные репозитории и логи, не меняйте одновременно квантизацию весов, KV-кэш, бэкенд и GPU split ради надписи 128K. Сохраните стабильную базу и требуйте от каждого изменения измеримого выигрыша в объёме, скорости или recall.
Если вам действительно нужен вход больше 100K, сначала задайте лестницу длин и критерии приёмки, а затем сравнивайте связки KV-кэша и бэкенда. Полезный итог звучит конкретно: «эта модель, бэкенд, кэш и железо три раза прошли 126K с нужной скоростью и точностью», а не просто «конфигурация поддерживает 128K».