Технологии

Почему большой контекст съедает видеопамять

Заявленная длина контекста и внезапная нехватка памяти на длинном диалоге — одна и та же величина. Формула объёма KV-кэша и таблица расхода на четыре длины контекста.

Модель класса 8B весит пять гигабайт, видеокарта — двенадцать. Запас семикратный, всё загрузилось, работает. К тридцатому сообщению диалог падает с ошибкой нехватки памяти.

Ошибка выглядит абсурдной: модель не выросла. Выросло другое — то, что новички обычно считают бесплатным.

#Короткий ответ

Между двумя величинами, которые кажутся несвязанными, — прямая зависимость. Длина контекста расходует видеопамять линейно, отдельно от весов модели, и на больших значениях этот расход превышает саму модель.

Хранилище называется KV-кэш. В нём лежат промежуточные векторы внимания для каждого уже обработанного токена — ключи и значения. Они нужны, чтобы не пересчитывать весь диалог заново на каждом новом слове.

Для модели класса 8B контекст в 32 тысячи токенов стоит около четырёх гигабайт. Для контекста в 128 тысяч — шестнадцать. Это при весах в пять.

#Как это устроено

Каждый обработанный токен оставляет след: два вектора на каждый слой модели. Отсюда формула:

KV-кэш = 2 × слои × KV-головы × размер_головы × длина_контекста × байт_на_элемент

Разберём слагаемые. Двойка — ключи и значения. Слои, KV-головы и размер головы берутся из конфигурации модели и лежат прямо в метаданных файла GGUF. Байт на элемент — два при обычном кэше в половинной точности, один при квантизации кэша в восемь бит.

Посчитаем для Llama 3.1 8B: 32 слоя, 8 KV-голов, размер головы 128.

2 × 32 × 8 × 128 × 2 байта = 131 072 байта на токен = 128 КиБ

Сто двадцать восемь килобайт на каждый токен диалога. Умножаем на длину:

Контекст KV-кэш (Llama 3.1 8B) Соотношение к весам (4,9 ГБ)
4 096 0,5 ГиБ 10%
8 192 1,0 ГиБ 20%
32 768 4,0 ГиБ 82%
131 072 16,0 ГиБ 327%

Что здесь смотреть: последнюю колонку. На коротком контексте кэш — незначительная добавка, на длинном он становится основным потребителем памяти, а на максимальном превышает модель втрое. Именно поэтому карта, спокойно державшая модель, отказывает при попытке использовать её заявленный контекст.

#Почему у разных моделей расход разный

Ключевая деталь, которую упускают: в формуле стоят KV-головы, а не головы внимания. В современных архитектурах с групповым вниманием KV-голов в четыре-восемь раз меньше, и расход соответственно ниже.

Модель Слои KV-головы На токен 32k контекста
Qwen2.5 7B 28 4 56 КиБ 1,75 ГиБ
Llama 3.1 8B 32 8 128 КиБ 4,0 ГиБ
Qwen2.5 14B 48 8 192 КиБ 6,0 ГиБ
Qwen2.5 32B 64 8 256 КиБ 8,0 ГиБ

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

#Что из этого следует на практике

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

Контекст — первый рычаг при нехватке памяти. Сократить его вдвое дешевле по качеству, чем перейти на более жёсткую квантизацию весов. Общая методика расчёта — в материале о том, сколько нужно VRAM для локальной LLM.

Квантизация кэша — самый дешёвый гигабайт. Хранение кэша в восьми битах вместо шестнадцати вдвое сокращает расход при почти незаметной разнице в качестве. Точные флаги и расчёт выигрыша — в материале о Flash Attention и квантизации KV-кэша.

Задавайте контекст явно. Значение по умолчанию в инструментах менялось между версиями и почти никогда не совпадает с тем, что вам нужно. Где именно оно задаётся в Ollama — в материале о параметрах Ollama, которые действительно влияют на результат.

#Где интуиция подводит

«Модель поддерживает 128 тысяч токенов, значит я могу их использовать». Заявленная длина — то, на что модель обучена, а не то, что влезет в вашу карту. Для класса 8B полный контекст 128k требует шестнадцати гигабайт одного только кэша. Разрыв между заявленным и практически доступным контекстом разбирает материал о реальном и заявленном контексте модели.

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

«Квантизация весов уменьшит и кэш». Не уменьшит: это независимые настройки. Модель в Q2 с контекстом 32k может занимать больше памяти, чем модель в Q4 с контекстом 8k.

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

#Частые вопросы

#Сколько памяти занимает контекст?

Считается по формуле: удвоенное произведение числа слоёв, числа KV-голов и размера головы даёт расход на один токен, дальше умножение на длину контекста. Для модели класса 8B это порядка 128 килобайт на токен, то есть гигабайт на каждые восемь тысяч токенов.

#Почему модель падает в середине диалога, а не сразу?

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

#Можно ли уменьшить расход, не сокращая контекст?

Да, квантизацией KV-кэша: восемь бит вместо шестнадцати вдвое сокращают расход. Это единственный способ, который почти не стоит качества.

#Влияет ли длина контекста на скорость?

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

#Что произойдёт, если контекст переполнится?

Зависит от инструмента: одни обрезают начало диалога и продолжают молча, другие сообщают об ошибке. Молчаливое обрезание — источник жалоб «модель забыла, о чём мы говорили в начале».

#Какую длину контекста ставить?

Ту, которая покрывает ваши реальные задачи, а не максимально возможную. Для диалога обычно достаточно 8–16 тысяч токенов. Работа с документами требует больше, и там имеет смысл считать расход заранее, а не подбирать наугад.

Хотите ИИ, который помнит вас?

Persona держит контекст между чатами и работает на вашем железе — если развернуть её у себя и подключить локальную модель.

Создать аккаунт