Исправление exceeds context size в Qwen Coder 30B: llama.cpp, квантование, OOM | AiManual
AiManual Logo Ai / Manual.
16 Янв 2026 Гайд

Qwen Coder 30B вылетает с 'exceeds context size'? Разбираемся с llama.cpp и квантованием

Пошаговое решение ошибки 'exceeds context size' в Qwen Coder 30B. Настройка llama.cpp, квантование модели, увеличение контекста до 32K токенов на 32 ГБ VRAM.

Почему Qwen Coder 30B не видит дальше своего носа

Ты загружаешь Qwen Coder 30B, пытаешься скормить ему большой кусок кода — и получаешь холодное сообщение "exceeds context size". Знакомо? Эта ошибка не просто ограничение — это крик о помощи от твоего GPU. Модель хочет больше памяти, чем у неё есть. И она не виновата.

Важно: Ошибка появляется не потому что модель глупая. Проблема в том, что контекст в 32K токенов требует примерно 2-4 ГБ дополнительной VRAM только на attention-матрицы. А у тебя их и так нет.

Что происходит под капотом

Когда ты указываешь --ctx-size 32768, llama.cpp резервирует память под всю возможную последовательность. Для Qwen 30B с 32 слоями это примерно:

  • Веса модели: ~60 ГБ в FP16, ~30 ГБ в INT8
  • Кэш KV: (32768 * 32 * 2 * 8) ≈ 16 ГБ в FP16
  • Промежуточные активации: ещё 2-8 ГБ в зависимости от batch size

Итого: даже с квантованием до INT8 тебе нужно минимум 48 ГБ VRAM. А у тебя 32 ГБ. Математика против нас.

Решение: не увеличивать память, а уменьшать аппетиты

Есть два пути: оптимизировать использование памяти или уменьшить размер модели. Мы пойдём обоими одновременно.

1 Квантование: превращаем слоны в мышей

Квантование — это не просто "сжатие модели". Это перевод весов из формата с плавающей точкой (FP16, 16 бит на вес) в целочисленный (INT4, 4 бита). Разница в памяти — в 4 раза. Но есть нюанс: качество падает.

💡
Не все квантования одинаковы. Q4_K_M сохраняет больше качества чем Q4_0. Q5_K_M почти неотличим от FP16 для кодинга. Выбирай Q5_K_M если есть место, Q4_K_M если нужно максимальное сжатие.

Конвертируем оригинальную модель в GGUF:

# Клонируем llama.cpp если ещё нет
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make -j$(nproc)

# Конвертируем в GGUF Q4_K_M (рекомендуемый баланс)
python convert.py \
  --outfile qwen-coder-30b-q4_k_m.gguf \
  --outtype q4_k_m \
  ~/models/Qwen/Qwen2.5-Coder-30B-Instruct/

# Или Q5_K_M для лучшего качества
python convert.py \
  --outfile qwen-coder-30b-q5_k_m.gguf \
  --outtype q5_k_m \
  ~/models/Qwen/Qwen2.5-Coder-30B-Instruct/

Размеры после конвертации:

Формат Размер файла VRAM при загрузке Качество кодинга
FP16 (оригинал) ~60 ГБ >60 ГБ Эталонное
Q8_0 ~30 ГБ ~32 ГБ Почти идеальное
Q5_K_M ~19 ГБ ~21 ГБ Отличное
Q4_K_M ~16 ГБ ~18 ГБ Хорошее

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

2 Настройка llama.cpp: заставляем его считать по-другому

Теперь главное — правильно запустить. Вот как НЕ надо делать:

# Так сработает на 5 минут, потом OOM
./main -m qwen-coder-30b-q4_k_m.gguf \
  --ctx-size 32768 \
  --gpu-layers -1 \
  --batch-size 512 \
  --mlock

Проблема в --batch-size 512. Это слишком много для 32K контекста. И в --gpu-layers -1 — он загрузит все слои в VRAM, но оставит мало места для кэша.

Правильная команда для 32 ГБ VRAM:

./main -m qwen-coder-30b-q4_k_m.gguf \
  --ctx-size 16384 \  # Уменьшаем до реально используемого
  --gpu-layers 28 \   # Оставляем 4 слоя для CPU
  --batch-size 256 \  # Оптимально для кодинга
  --threads 8 \
  --mlock \
  --no-mmap \
  --temp 0.1 \
  --repeat-penalty 1.1

Секрет: Флаг --no-mmap отключает memory mapping. Это увеличивает время загрузки, но даёт предсказуемое использование памяти. Без него llama.cpp может резервировать память "на вырост" и вылететь при генерации.

А если нужны именно 32K токенов?

Придётся жертвовать. Вот рабочий вариант:

# Для контекста 32768 на 32 ГБ VRAM
./main -m qwen-coder-30b-q4_k_m.gguf \
  --ctx-size 32768 \
  --gpu-layers 24 \    # Ещё меньше слоёв на GPU
  --batch-size 128 \   # Маленький batch
  --flash-attn \       # Если собрано с поддержкой
  --no-kv-offload \    # Не выгружаем кэш (быстрее)
  --parallel 1 \
  --mlock

Или используем --ngl 20 вместо --gpu-layers 24 — это синонимы, но в разных версиях llama.cpp.

Тонкая настройка: что ещё можно выжать

Оптимизация через слои

Qwen Coder 30B имеет 32 слоя. Каждый слой на GPU — это ~300 МБ VRAM в Q4_K_M. Посчитаем:

  • 20 слоёв на GPU: 20 * 300 МБ = 6 ГБ
  • Кэш KV для 32K: ~8 ГБ
  • Остальное: ~2 ГБ
  • Итого: 16 ГБ — влезает!

Но 12 слоёв на CPU будут тормозить. Решение: найти баланс. Начни с 24 слоёв на GPU, уменьшай если вылетает.

Batch size — не то, что кажется

Большой batch size ускоряет обработку промпта, но съедает память квадратично. Формула простая:

# Память для attention ~ batch_size * ctx_size * layers
# При batch=512 и ctx=32768: 512 * 32768 * 32 = 537M элементов
# В FP16: 537M * 2 байта = 1 ГБ только на одну матрицу!

Поэтому batch=256 — разумный компромисс.

Если ничего не помогает

Бывает. Тогда идём на крайние меры:

1. Используем vLLM вместо llama.cpp

vLLM эффективнее управляет памятью благодаря PagedAttention. Но сложнее в настройке.

2. Берем меньшую модель

Qwen Coder 14B в Q4_K_M занимает ~8 ГБ. Контекст 32K — легко. Качество? На 20% хуже для сложного кода, но для большинства задач достаточно. Сравнивал в статье про Qwen3 на 12 ГБ VRAM.

3. Разбиваем контекст

Если нужно проанализировать 100К строк кода — не грузи всё сразу. Разбей на чанки по 8К, обработай отдельно, потом сведи результаты. Есть техники в гайде по долгой памяти.

💡
Проверь сборку llama.cpp. Если собирал год назад — пересобери. За последние 6 месяцев оптимизировали память на 30%. Используй make clean && make -j$(nproc) LLAMA_CUDA=1 с последней версией из git.

Частые ошибки и как их избежать

Ошибка Причина Решение
"CUDA out of memory" после 10 токенов Кэш KV растёт по мере генерации Уменьши --ctx-size или используй --kv-offload
Модель загружается, но не отвечает Слишком много слоёв на CPU, deadlock Увеличь --gpu-layers или используй --no-mmap
Скорость 0.5 токен/сек Большинство слоёв на CPU Попробуй Q3_K_M чтобы больше слоёв влезло в VRAM
"Model size exceeds context size" при конвертации Старая версия convert.py Обнови llama.cpp и переконвертируй

Проверка: работает ли теперь?

Запусти тест:

# Генерируем длинный промпт для проверки
cat > test_prompt.txt << EOF
Analyze this Python code and suggest improvements:

def process_data(data):
    result = []
    for item in data:
        if item['type'] == 'A':
            processed = item['value'] * 2
        elif item['type'] == 'B':
            processed = item['value'] / 2
        else:
            processed = item['value']
        result.append(processed)
    return result

# [добавь ещё 5000 строк кода для теста контекста]
EOF

# Запускаем с замером памяти
./main -m qwen-coder-30b-q4_k_m.gguf \
  --ctx-size 16384 \
  --gpu-layers 28 \
  --batch-size 256 \
  --file test_prompt.txt \
  --n-predict 512 \
  --verbose 2>&1 | grep -E "(total VRAM|ctx size|layers)"

Если видишь "total VRAM used: 28.4G" и модель отвечает — победа.

Что в итоге

Проблема "exceeds context size" в Qwen Coder 30B решается комбинацией:

  1. Квантование до Q4_K_M или Q5_K_M — уменьшаем модель в 3-4 раза
  2. Настройка --gpu-layers — оставляем часть слоёв на CPU
  3. Реалистичный --ctx-size — не 32768, а 16384 (всё равно редко используешь больше)
  4. Оптимизация --batch-size — 256 вместо 512

Самое главное: не пытайся запихнуть невпихуемое. 32K контекст на 30B модели с 32 ГБ VRAM — это на грани. Иногда лучше взять Qwen Coder 14B с 32K контекстом, чем 30B с 8K.

И последний совет: следи за обновлениями llama.cpp. Каждый месяц появляются новые оптимизации памяти. То что не работало вчера — заработает завтра. Как минимум, пересобирай раз в месяц.