Перейти к содержимому
АРЕНДА GPU / ПОЧАСОВАЯ ОПЛАТА / USD

Сколько VRAM нужно LLM: расчёт весов и KV-кэша на примере Qwen 7B

Опубликовано:

Одна и та же LLM может требовать разный объём VRAM: кроме весов, GPU хранит контекст каждого активного диалога и рабочие данные движка. Для Qwen2.5-7B-Instruct в BF16 полезные данные KV-кэша занимают около 0,44 GiB при одном диалоге на 8192 токена и 7 GiB при четырёх диалогах на 32 768 токенов. Разница в 16 раз, хотя модель не менялась.

Посчитаем веса и кэш по файлам модели. Затем посмотрим, сколько памяти остаётся движку и с каким бюджетом идти в каталог GPU.

Сколько памяти занимают веса, а сколько — контекст

Удобно разделить бюджет на три части:

  • Веса: параметры модели после загрузки на GPU.
  • KV-кэш: сохранённые ключи и значения attention для обрабатываемых последовательностей. Он позволяет использовать уже рассчитанное состояние при генерации следующих токенов.
  • Рабочая память: временные тензоры, буферы операций и другие выделения среды исполнения.

Размер скачанного файла помогает оценить первую часть, но не весь бюджет. У неквантованных тензоров одного типа размер весов равен числу параметров, умноженному на байты на параметр: два для BF16/FP16, четыре для FP32. При смешанных типах группы тензоров считают отдельно.

Надпись «4-bit» также не означает, что весь расход памяти уменьшился в четыре раза относительно BF16. У квантованных весов есть служебные данные, часть тензоров может остаться в более высокой точности. Тип KV-кэша задаётся отдельно. Например, документация bitsandbytes разделяет квантование весов и тип вычислений.

Ещё одна частая путаница — RAM сервера и VRAM видеокарты. Большой объём системной RAM помогает загрузке и подготовке данных. Чтобы перенести туда часть весов или кэша во время работы, нужен поддерживаемый режим offload; скорость и схема исполнения при этом меняются.

Расчёт для Qwen2.5-7B-Instruct

Зафиксируем ревизию a306ca65c69cb09b9ce8ae8396fd529d509d872e. В конфигурации указаны 28 слоёв, 28 query-голов, четыре головы ключей/значений и hidden size 3584. Размерность головы: 3584 / 28 = 128. Sliding window выключен.

В расчёте веса и KV-кэш имеют тип BF16. Все данные размещаются на одной GPU, без квантования, offload, лучевого поиска и переиспользования общих префиксов. Для трактовки растущего кэша используем DynamicCache из Transformers 4.57.1.

Для такой архитектуры полезные данные KV-кэша считаются по формуле:

KV = 2 × число слоёв × число KV-голов × размер головы
     × байтов на элемент × сумма хранимых длин последовательностей

Двойка учитывает отдельно ключи и значения. Используем именно четыре KV-головы: подстановка 28 query-голов завысила бы результат в семь раз.

На один токен одной последовательности:
2 × 28 × 4 × 128 × 2 = 57 344 байта = 56 KiB
Расчётный KV-кэш Qwen2.5-7B-Instruct в BF16
Вход + лимит ответа Активных последовательностей Полезные данные KV-кэша
6144 + 2048 = 8192 токена 1 0,4375 GiB
6144 + 2048 = 8192 токена 4 1,75 GiB
30 720 + 2048 = 32 768 токенов 1 1,75 GiB
30 720 + 2048 = 32 768 токенов 4 7 GiB

← Прокрутите таблицу →

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

В индексе весов поле metadata.total_size равно 15 231 233 024 байтам, или примерно 14,19 GiB. Это полезный объём сохранённых тензоров. При размещении этих BF16-весов на GPU известная расчётная часть для четырёх длинных диалогов составляет:

Веса + полезные данные KV-кэша ≈ 14,19 + 7 = 21,19 GiB

21,19 GiB — ещё не полный рабочий пик. К этой части добавляются рабочие выделения движка. Для карты на 24 GB нужно ещё проверить, сколько места займут эти буферы.

Как использовать расчёт при выборе GPU

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

С более вместительной картой вопрос другой: сколько осталось для выполнения операций? Для одного короткого диалога известная часть нашего примера около 14,63 GiB; для четырёх длинных — 21,19 GiB. Поэтому разумный размер карты зависит от того, какой из этих режимов вы действительно будете обслуживать.

Сверяйте единицы: 1 GB = 10⁹ байт, 1 GiB = 2³⁰ байт. В каталоге сохраняйте обозначение производителя, а при проверке смотрите фактически доступный объём устройства. Две GPU по 24 GB тоже не дают приложению одну прозрачную область на 48 GB: для распределения весов и вычислений требуется поддержка программой.

Почему замер может отличаться

На длинном входе движок сначала выполняет prefill, затем генерирует ответ по токенам. В этих фазах разные временные выделения. Пик может возникнуть не в тот момент, когда вы смотрите обычный короткий ответ.

Кроме того, движки управляют памятью по-разному. StaticCache резервирует заданную ёмкость заранее; DynamicCache растёт. vLLM может заранее выделить пул под кэш, поэтому занятая память после старта не равна полезным данным текущего диалога. Эти различия описаны в руководстве vLLM по расходу памяти.

Формула выше относится к выбранной архитектуре с полным attention. Модели со скользящим окном, гибридными слоями или другим устройством состояния требуют своего расчёта. Универсальная таблица «7B = столько-то GB» скрывает эти различия.

Короткая проверка перед рабочей нагрузкой

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

В PyTorch полезно наблюдать max_memory_allocated() и max_memory_reserved(), а память всего устройства — отдельно. Первый счётчик показывает пик памяти тензоров, второй — пик аллокатора PyTorch; их нельзя складывать. Для других движков используйте их средства наблюдения. Пояснение счётчиков PyTorch.

При OOM сначала уменьшите параллелизм или максимальную длину, если задача это допускает. Затем рассмотрите квантование, поддерживаемый offload или карту с большей VRAM. После изменения режима повторите проверку качества и задержки: экономия памяти сама по себе не делает результат приемлемым.

В каталог XGPU стоит идти с конкретной записью: модель, точность, контекст и параллелизм. Она намного полезнее одного размера «7B»: помогает выбрать подходящий объём памяти и не оплачивать запас, который вашей задаче не нужен.

Расчёт по файлам модели и документации, проверенным 2 ноября 2026 года.