Чтобы запустить open-weight языковую модель локально, устройству, которое выполняет вычисления, нужно достаточно быстрой памяти для трех вещей: квантизованных весов, KV-кэша под вашу длину контекста и число одновременных запросов, а также запаса для среды выполнения. Объем памяти определяет, какие модели поместятся, пропускная способность памяти определяет скорость генерации текста, а вычислительная мощность определяет скорость чтения длинных промптов. Упрощенно: GPU на 16 ГБ хорошо справляется с моделями класса 8B, 24–32 ГБ хватает для моделей класса 32B в 4-битной квантизации, а моделям класса 70B нужно примерно 48 ГБ и больше, то есть рабочая станционная карта, два GPU или машина с единой памятью.
Формула памяти
Любой расчет начинается с одной суммы:
memory ≈ weights + KV cache + runtime overhead
weights = parameters × bits per weight / 8
KV cache = 2 × layers × kv_heads × head_dim × bytes per element × tokens in flight
Модели с 70,6 млрд параметров нужно около 141 ГБ под веса при 16 битах и около 42 ГБ при 4,8 бита на вес.
KV-кэш хранит ключи и значения внимания для каждого токена, который модель держит в контексте, поэтому он растет с каждым токеном промпта и ответа. Множитель 2 учитывает ключи и значения, а остальные величины берутся из config.json модели: num_hidden_layers, num_key_value_heads и head_dim. Большинство современных моделей используют grouped-query attention, где KV-голов намного меньше, чем голов запросов.
Накладные расходы среды выполнения включают контекст CUDA, ROCm или Metal и вычислительные буферы. Закладывайте 1–2 ГиБ на устройство для llama.cpp, чье автоматическое размещение по умолчанию оставляет запас 1024 МиБ на устройство, и больше для серверов, которые заранее резервируют память под большие батчи. На машинах с единой памятью оставьте место и для операционной системы.
KV-кэш растет с контекстом и параллельностью
Стоимость одного токена напрямую следует из конфигурации:
Llama 3.1 8B: 2 × 32 layers × 8 kv_heads × 128 head_dim × 2 bytes = 128 KiB per token
Qwen3-32B: 2 × 64 layers × 8 kv_heads × 128 head_dim × 2 bytes = 256 KiB per token
Llama 3.3 70B: 2 × 80 layers × 8 kv_heads × 128 head_dim × 2 bytes = 320 KiB per token
При 32 768 токенах это 4, 8 и 10 ГиБ для 16-битного кэша. При 131 072 токенах кэш модели 70B достигает 40 ГиБ, то есть столько же, сколько ее 4-битные веса.
Параллельные запросы умножают кэш: четырем пользователям с диалогами по 16K токенов нужно столько же, сколько одному диалогу на 64K. vLLM формирует пул KV из памяти, оставшейся после загрузки весов, а llama-server делит один бюджет контекста (-c) между слотами (--parallel). В руководстве по серверам локального инференса LLM разобрано, как каждый сервер распределяет этот пул.
Уменьшить кэш можно двумя способами. 8-битный кэш, -ctk q8_0 -ctv q8_0 в llama.cpp или --kv-cache-dtype fp8 в vLLM, сокращает его примерно вдвое, а ограничение контекста реально используемой длиной ничего не стоит. Sliding-window, гибридное внимание и multi-head latent attention хранят меньше данных на токен, поэтому сверяйтесь с размером KV-буфера, который llama.cpp выводит при загрузке модели.
Расчет для моделей 8B, 32B и 70B
Документация llama.cpp по квантизации приводит число бит на вес, измеренное на Llama 3.1 8B: Q8_0 — 8,50, Q6_K — 6,56, Q5_K_M — 5,70, Q4_K_M — 4,89, IQ4_XS — 4,46 и Q3_K_M — 4,00. У больших моделей значения немного ниже: опубликованные файлы Q4_K_M для Qwen3-32B и Llama 3.3 70B дают около 4,8. Этот скрипт применяет формулу для контекста 32K и накладных расходов 1,5 ГиБ:
GiB = 2**30
def weights_gib(params, bits_per_weight):
return params * bits_per_weight / 8 / GiB
def kv_gib(layers, kv_heads, head_dim, tokens, bytes_per_elem=2):
return 2 * layers * kv_heads * head_dim * bytes_per_elem * tokens / GiB
models = {
"Llama 3.1 8B": (8.03e9, 32),
"Qwen3-32B": (32.76e9, 64),
"Llama 3.3 70B": (70.55e9, 80),
}
for name, (params, layers) in models.items():
kv = kv_gib(layers, 8, 128, 32768)
for quant, bpw in (("BF16", 16.0), ("Q8_0", 8.5), ("Q4_K_M", 4.85)):
w = weights_gib(params, bpw)
print(f"{name:14} {quant:7} weights {w:6.1f} GiB KV@32K {kv:5.1f} GiB total {w + kv + 1.5:6.1f} GiB")
Llama 3.1 8B BF16 weights 15.0 GiB KV@32K 4.0 GiB total 20.5 GiB
Llama 3.1 8B Q8_0 weights 7.9 GiB KV@32K 4.0 GiB total 13.4 GiB
Llama 3.1 8B Q4_K_M weights 4.5 GiB KV@32K 4.0 GiB total 10.0 GiB
Qwen3-32B BF16 weights 61.0 GiB KV@32K 8.0 GiB total 70.5 GiB
Qwen3-32B Q8_0 weights 32.4 GiB KV@32K 8.0 GiB total 41.9 GiB
Qwen3-32B Q4_K_M weights 18.5 GiB KV@32K 8.0 GiB total 28.0 GiB
Llama 3.3 70B BF16 weights 131.4 GiB KV@32K 10.0 GiB total 142.9 GiB
Llama 3.3 70B Q8_0 weights 69.8 GiB KV@32K 10.0 GiB total 81.3 GiB
Llama 3.3 70B Q4_K_M weights 39.8 GiB KV@32K 10.0 GiB total 51.3 GiB
Модель 8B в Q4_K_M помещается на карту 12 ГБ, а в Q8_0 — на карту 16 ГБ, так что на 16 ГБ нет причин по объему опускаться ниже Q6_K. Модели 32B в Q4_K_M с полным кэшем на 32K нужна карта 32 ГБ; на 24 ГБ она помещается с контекстом 16K и 8-битным кэшем, занимая около 22 ГиБ. Модели 70B в Q4_K_M нужно около 51 ГиБ: два GPU по 32 ГБ, рабочая станционная карта на 72 или 96 ГБ либо 64 ГБ единой памяти и больше. Карта на 48 ГБ запускает ее с контекстом около 8K, а для Q8_0 нужна карта на 96 ГБ или 128 ГБ единой памяти.
Форматы квантизации и их цена
Квантизация хранит веса меньшим числом бит плюс масштабы для каждого блока. Она экономит память и ускоряет генерацию, но добавляет ошибку.
K-quants и I-quants в GGUF
GGUF — формат файлов llama.cpp, его же используют Ollama и LM Studio. K-quants, например Q4_K_M и Q6_K, квантизуют веса блоками и оставляют чувствительные тензоры в более точном типе. I-quants, например IQ4_XS, упаковывают веса плотнее. Оба семейства выигрывают от матрицы важности (imatrix), рассчитанной на калибровочном тексте, а документация llama.cpp измеряет их потери через perplexity и дивергенцию Кульбака — Лейблера. GGUF работает на CUDA, ROCm, Vulkan, Metal и CPU, поэтому это самый переносимый вариант.
8 бит и FP8
Q8_0 — 8-битный тип GGUF. На GPU-серверах стандартный 8-битный формат — FP8. Согласно документации vLLM по FP8, вычисления FP8 требуют NVIDIA compute capability 8.9 или выше (Ada Lovelace, Hopper, Blackwell), старые GPU переходят на weight-only ядра W8A16, а FP8 вдвое сокращает память модели при росте пропускной способности до 1,6 раза и минимальном влиянии на точность.
AWQ, GPTQ и 4-битная плавающая точка
AWQ и GPTQ — 4-битные weight-only методы для GPU-серверов, таких как vLLM и SGLang. Они калибруют масштабы для групп весов, оставляют активации в 16 битах, и многие авторы моделей публикуют такие версии сами, например Qwen/Qwen3-32B-AWQ. GPU Blackwell добавляют аппаратную математику FP4, а модели gpt-oss от OpenAI хранят веса экспертов в MXFP4.
Сколько качества вы теряете
8-битные форматы обычно трудно отличить от BF16. Q6_K и Q5_K_M дают небольшой, но измеримый рост perplexity и остаются безопасным выбором, если позволяет память. 4 бита — привычный компромисс: потери измеримы, и заметнее всего они там, где важны мелкие ошибки: в коде, математике и точном извлечении фактов из длинного контекста. Ниже 4 бит ошибка быстро растет, причем маленькие модели страдают сильнее больших. Более крупная модель в 4 битах часто обходит меньшую в 8 битах при том же объеме памяти, но проверяйте это на своих задачах, как описано в руководстве по оценке AI-агентов.
Пропускная способность задает скорость генерации, вычисления — скорость промпта
Генерация одного токена плотной моделью читает каждый вес один раз, плюс KV-кэш текущего контекста. При размере батча 1 перемещение данных доминирует, поэтому потолок считается просто:
decode tokens/s ≤ memory bandwidth / bytes read per token
bytes read per token ≈ weight bytes (dense) or active-expert bytes (MoE) + KV cache bytes at current depth
Файл Llama 3.3 70B Q4_K_M занимает 42,5 ГБ, поэтому потолок составляет около 42 токенов в секунду при 1792 ГБ/с, 14 при 614 ГБ/с и 6 при 256 ГБ/с. Файл 8B Q4_K_M (4,9 ГБ) получает около 91 токена в секунду при 448 ГБ/с. Реальные среды выполнения работают ниже этих потолков и замедляются с ростом контекста: на 32K кэш модели 70B добавляет около 10,7 ГБ чтения на каждый токен.
Таблица квантизации llama.cpp показывает эту закономерность на одной машине с Llama 3.1 8B: генерация растет примерно с 29 токенов в секунду в F16 до 51 в Q8_0 и 72 в Q4_K_M, а обработка промпта для всех типов остается в диапазоне примерно от 700 до 920 токенов в секунду.
Обработка промпта идет батчами по сотням токенов, поэтому каждое чтение веса обслуживает много токенов, и ограничением становится матричная производительность. Объем работы — примерно 2 × parameters × prompt tokens операций, то есть около 5 × 10^14 для промпта на 8000 токенов у модели 32B. От этого зависит время до первого токена в retrieval-augmented generation, где промпт несет найденные фрагменты, как в схеме гибридного поиска на pgvector, и у агентов для кода, которые отправляют большие файлы. Смотрите на обе характеристики: у NVIDIA DGX Spark скромный потолок генерации при 273 ГБ/с, но NVIDIA оценивает ее чип GB10 до 1 PFLOP разреженных вычислений FP4.
Батчинг обслуживает много последовательностей за одно чтение весов, поэтому пропускная способность сервера растет, пока не закончатся вычисления или кэш. Циклам агентов, наоборот, важна задержка одного запроса, потому что каждый шаг ждет предыдущий вызов, как описано в руководстве по архитектуре production AI-агента.
Модели mixture-of-experts (MoE) разделяют эти ограничения: память определяется общим числом параметров, а скорость генерации — числом активных. У gpt-oss-120b 117 млрд параметров, из них 5,1 млрд активных, и в ее карточке модели сказано, что она помещается на один GPU с 80 ГБ; ее файл MXFP4 GGUF занимает 63,4 ГБ. gpt-oss-20b работает в пределах 16 ГБ. Поэтому машины с большим объемом и умеренной пропускной способностью остаются полезными.
Варианты оборудования по возможностям
GPU NVIDIA по классам VRAM
У GPU NVIDIA самая широкая поддержка со стороны сред выполнения, потому что vLLM, SGLang, TensorRT-LLM и llama.cpp считают CUDA эталонной платформой. Сначала сравнивайте объем, затем пропускную способность внутри класса: карты GeForce на 16 ГБ запускают одни и те же модели, но у RTX 5080 пропускная способность более чем вдвое выше, чем у RTX 5060 Ti. RTX PRO 6000 Blackwell вмещает модель 70B в 8 битах на одной карте. Карты GeForce RTX 50 не поддерживают NVLink, поэтому обмен между несколькими GPU идет через PCIe.
Единая память: Apple Silicon, Ryzen AI Max, DGX Spark
Системы с единой памятью дают CPU и GPU общий пул LPDDR: намного больше памяти под модель, чем у потребительских GPU, но с меньшей пропускной способностью, чем у быстрой карты GDDR7, за исключением старшего чипа Apple. Для Mac Studio Apple предлагает M5 Ultra от 96 ГБ, сообщает, что конфигурация на 512 ГБ появится в конце октября, и поддерживает кластеризацию через Thunderbolt 5 с RDMA; среди сред выполнения — llama.cpp на Metal и MLX. Ryzen AI Max+ 395 от AMD использует 256-битный интерфейс LPDDR5x-8000, что дает 256 ГБ/с, а Ryzen AI Max+ PRO 495 переходит на LPDDR5x-8533, и системы OEM заявлены на третий квартал 2026 года; llama.cpp работает на обоих через ROCm или Vulkan. NVIDIA DGX Spark использует стек CUDA и имеет порт ConnectX-7 на 200 Гбит/с для объединения устройств.
По формуле потолка такие машины запускают плотные модели 70B со скоростью от единиц до пары десятков токенов в секунду, а модели MoE — намного быстрее. Их GPU работают в гораздо меньшем бюджете мощности, чем карта на 575 Вт, поэтому измеряйте время до первого токена на реальных промптах.
| Платформа | Память для модели | Пропускная способность | Мощность | Плотная модель при контексте 32K |
|---|---|---|---|---|
| GeForce RTX 5060 Ti 16 GB | 16 ГБ GDDR7 | 448 ГБ/с | 180 Вт | 8B в Q8_0 |
| GeForce RTX 5070 Ti / 5080 | 16 ГБ GDDR7 | 896 / 960 ГБ/с | 300 / 360 Вт | 8B в Q8_0 |
| GeForce RTX 5090 | 32 ГБ GDDR7 | 1792 ГБ/с | 575 Вт | 32B в Q4_K_M |
| RTX PRO 4000 / 4500 Blackwell | 24 / 32 ГБ GDDR7 ECC | 672 / 896 ГБ/с | 145 / 200 Вт | 32B в 4 битах |
| RTX PRO 5000 Blackwell | 48 или 72 ГБ GDDR7 ECC | 1344 ГБ/с | 300 Вт | 32B в Q8_0, 70B в Q4_K_M на 72 ГБ |
| RTX PRO 6000 Blackwell | 96 ГБ GDDR7 ECC | 1792 ГБ/с | 600 Вт или 300 Вт (Max-Q) | 70B в Q8_0 |
| DGX Spark | 128 ГБ LPDDR5x | 273 ГБ/с | блок питания 240 Вт | 70B в Q8_0 |
| Ryzen AI Max+ 395 | 128 ГБ, до 96 ГБ для графики | 256 ГБ/с | 45–120 Вт | 70B в Q6_K |
| Ryzen AI Max+ PRO 495 | 192 ГБ, до 160 ГБ для графики | около 273 ГБ/с | 45–120 Вт | 70B в Q8_0 |
| Mac Studio, M5 Max | до 128 ГБ | до 614 ГБ/с | максимум системы 480 Вт | 70B в Q8_0 |
| Mac Studio, M5 Ultra | до 512 ГБ | 1,2 ТБ/с | максимум системы 480 Вт | 70B в BF16 |
Последняя колонка следует из расчетов выше для одного пользователя. Таблица описывает возможности, а не соотношение цены и качества.
Несколько GPU и выгрузка на CPU
Два GPU удваивают объем, но скорость зависит от способа разделения. При разделении по слоям, режиме llama.cpp по умолчанию, каждый GPU хранит диапазон слоев и их KV-кэш, а при батче 1 GPU работают по очереди: объем больше, скорость генерации та же. На каждый токен через PCIe проходят только небольшие активации, поэтому линков x8 или x4 достаточно. При тензорном параллелизме (--tensor-parallel-size 2 в vLLM) оба GPU одновременно читают свою долю каждого слоя, что поднимает потолок, но каждый слой синхронизируется через PCIe. Тензорный параллелизм vLLM рассчитан на одинаковые GPU, а число GPU должно делить число голов внимания модели.
Выгрузка на CPU оставляет часть слоев в системной памяти, и их выполняет процессор. Время на токен становится суммой: байты на GPU, деленные на пропускную способность VRAM, плюс байты на CPU, деленные на пропускную способность RAM. Двухканальная DDR5-6000 теоретически дает 96 ГБ/с (2 канала × 8 байт × 6000 MT/s), а в руководстве по памяти DDR5 разобрано, как сочетаются каналы и частоты. Модель 70B Q4_K_M, у которой 24 ГБ на GPU и 18,5 ГБ в RAM, не превысит 5 токенов в секунду. Выгрузка решает проблему объема, а не скорости.
Модели MoE выгружаются гораздо лучше. --cpu-moe и --n-cpu-moe N держат веса экспертов в RAM, а внимание и KV-кэш остаются на GPU, и на каждый токен читаются только активные эксперты. Свежие сборки llama.cpp сами подбирают число слоев, если -ngl не задан (--fit включен по умолчанию); задавайте его явно, когда нужны воспроизводимые результаты. Команды ниже показывают частично выгруженную плотную модель, модель MoE с экспертами в RAM и разделение по слоям с перевесом в сторону большего GPU:
llama-server -m Llama-3.3-70B-Instruct-Q4_K_M.gguf -c 16384 -ngl 48 -fa on
llama-server -hf ggml-org/gpt-oss-120b-GGUF -c 32768 -ngl all --n-cpu-moe 24 -fa on
llama-server -m Qwen_Qwen3-32B-Q8_0.gguf -c 32768 -ngl all --split-mode layer --tensor-split 3,2
Питание, охлаждение, линии PCIe и системная память
Для GeForce RTX 5090 NVIDIA указывает 575 Вт графической мощности и 1000 Вт требуемой мощности системы. Версия RTX PRO 6000 Max-Q на 300 Вт сохраняет тот же объем памяти, что и модель на 600 Вт, и это важно, если в одном корпусе будет несколько карт. Поскольку генерация ждет память, проверьте пониженный лимит через nvidia-smi -pl и оставьте значение, при котором скорость генерации почти не меняется.
Инференс — длительная нагрузка, а две карты с открытым охлаждением в соседних слотах гоняют друг другу горячий воздух. Проверяйте частоты, температуру и мощность во время 30-минутного прогона.
Карты GeForce RTX 50 и RTX PRO Blackwell используют PCIe 5.0 x16. Потребительские настольные платформы обычно дают один графический линк x16, который некоторые платы делят на x8/x8, а слот от чипсета часто работает в режиме x4. Разделение по слоям это переносит; тензорному параллелизму и загрузке моделей лучше x8 и шире, что дают платформы рабочих станций. Отображаемое поколение линка может снижаться, пока GPU простаивает, поэтому проверяйте его под нагрузкой.
Системной памяти должно быть не меньше, чем самый большой загружаемый файл модели, плюс место для ОС, и намного больше, если вы выгружаете слои. Файлы моделей занимают от 5 ГБ до более чем 100 ГБ, поэтому быстрый накопитель сокращает время загрузки; об этом сценарии рассказывает руководство по выбору NVMe SSD.
nvidia-smi --query-gpu=name,pcie.link.gen.current,pcie.link.width.current,power.draw,memory.used --format=csv -l 1
nvidia-smi dmon -s pucvmt -d 1
sudo nvidia-smi -pl 450
Измерьте собственную скорость
Опубликованные цифры редко совпадают с вашим файлом модели, контекстом, драйвером и версией среды выполнения, поэтому измеряйте сами и сравнивайте с формулой потолка. В llama-bench параметр -p задает длину промпта, -n — число генерируемых токенов, а -d заранее заполняет KV-кэш до заданной глубины и показывает, как падает скорость по мере роста диалога. Вторая команда сравнивает 16-битный и 8-битный кэш:
llama-bench -m Qwen_Qwen3-32B-Q4_K_M.gguf -p 512,4096 -n 128 -d 0,16384 -fa on -r 3 -o md
llama-bench -m Qwen_Qwen3-32B-Q4_K_M.gguf -p 4096 -n 128 -d 16384 -ctk f16,q8_0 -ctv f16,q8_0 -fa on
Затем проверьте параллельную нагрузку. vllm bench serve работает с OpenAI-совместимыми endpoint и показывает время до первого токена, время на выходной токен, задержку между токенами и общую пропускную способность:
vllm serve Qwen/Qwen3-32B-AWQ --max-model-len 32768
vllm bench serve --backend openai --base-url http://127.0.0.1:8000 --model Qwen/Qwen3-32B-AWQ --dataset-name random --random-input-len 4096 --random-output-len 256 --num-prompts 200 --max-concurrency 8
Разделите измеренную скорость одного потока на потолок. Если отношение необычно низкое, ищите слои, незаметно выгруженные на CPU, линк PCIe с урезанной шириной, троттлинг или медленный backend.
Чеклист подбора
- Выпишите из
config.jsonчисло параметров, слоев, KV-голов и размерность головы. - Выберите квантизацию: 8 бит, если помещается, затем Q6_K или Q5_K_M, затем 4 бита, а ниже только после проверки.
- Задайте контекст и число параллельных запросов, посчитайте KV-кэш и решите, допустим ли 8-битный кэш.
- Добавьте 1–2 ГиБ на устройство и запас для ОС на единой памяти.
- Отбросьте платформы, у которых потолок генерации ниже нужной вам скорости.
- Для длинных промптов из RAG или агентов для кода учитывайте вычисления и измеряйте время до первого токена.
- Для MoE считайте память по общему числу параметров, а скорость по активным.
- Проверьте питание, охлаждение, линии PCIe, RAM и накопитель до покупки второго GPU.
- Проведите замеры и сократите разрыв с потолком, прежде чем добавлять оборудование.