要在本地运行开放权重的语言模型,执行计算的设备需要有足够的高速内存来容纳三样东西:量化后的权重、与上下文长度和并发请求数相匹配的 KV 缓存,以及运行时余量。容量决定哪些模型装得下,内存带宽决定生成文本的速度,算力决定读取长提示词的速度。粗略来说,16 GB 显卡能流畅运行 8B 级模型,24 到 32 GB 可以覆盖 4 bit 量化的 32B 级模型,而 70B 级模型大约需要 48 GB 或更多,也就是一张工作站显卡、两张 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
一个 706 亿参数的模型,在 16 bit 下仅权重就需要约 141 GB,在每个权重 4.8 bit 时约需 42 GB。
KV 缓存保存模型当前跟踪的每个 token 的注意力键和值,因此会随着提示词和输出的每个 token 增长。系数 2 对应键和值,其余各项来自模型的 config.json:num_hidden_layers、num_key_value_heads 和 head_dim。目前大多数模型采用 grouped-query attention,KV 头的数量远少于查询头。
运行时开销包括 CUDA、ROCm 或 Metal 上下文以及计算缓冲区。使用 llama.cpp 时,每个设备预留 1 到 2 GiB;它的自动适配功能默认会为每个设备保留 1024 MiB 余量。对于为大批量预先分配内存的推理服务器,则要预留更多。在统一内存机器上,还要给操作系统留出空间。
KV 缓存随上下文和并发增长
每个 token 的开销可以直接从配置文件算出:
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 个 token 时,16 bit 缓存分别为 4、8 和 10 GiB。到 131,072 个 token 时,70B 模型的缓存本身就达到 40 GiB,与它的 4 bit 权重一样大。
并发会成倍放大缓存:四个用户各自进行 16K token 的对话,占用的缓存与一个 64K 对话相同。vLLM 用加载权重后剩余的内存建立 KV 池,llama-server 则在各个槽位(--parallel)之间共享同一个上下文预算(-c)。本地 LLM 推理服务器指南介绍了各个服务器如何分配和调度这个池。
有两种办法可以缩小缓存。使用 8 bit 缓存,也就是 llama.cpp 中的 -ctk q8_0 -ctv q8_0 或 vLLM 中的 --kv-cache-dtype fp8,大约能减半;把上下文限制在应用实际需要的长度则没有任何代价。滑动窗口层、混合注意力和 multi-head latent attention 每个 token 存储的数据更少,因此请以 llama.cpp 加载模型时打印的 KV 缓冲区大小为准。
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。更大的模型数值略低:Qwen3-32B 和 Llama 3.3 70B 公开发布的 Q4_K_M 文件折合约 4.8。下面的脚本按 32K 上下文和 1.5 GiB 开销套用公式:
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 GB 显卡,用 Q8_0 可以装进 16 GB 显卡,所以在 16 GB 显卡上没有容量上的理由低于 Q6_K。32B 模型用 Q4_K_M 并保留完整 32K 缓存时需要 32 GB 显卡;在 24 GB 显卡上,配合 16K 上下文和 8 bit 缓存也能装下,占用约 22 GiB。70B 模型用 Q4_K_M 需要约 51 GiB:两张 32 GB GPU、一张 72 或 96 GB 的工作站显卡,或 64 GB 以上的统一内存。48 GB 显卡可以在约 8K 上下文下运行它,而 Q8_0 需要 96 GB 显卡或 128 GB 统一内存。
量化格式及其代价
量化用更少的比特存储权重,并为每个块附加缩放系数。它节省内存、加快生成,但会引入误差。
GGUF 的 K-quants 与 I-quants
GGUF 是 llama.cpp 的文件格式,Ollama 和 LM Studio 也使用它。Q4_K_M、Q6_K 等 K-quants 按块量化权重,并把敏感张量保留为更高精度的类型。IQ4_XS 等 I-quants 压缩得更激进。两者都能从基于校准文本计算的重要性矩阵(imatrix)中获益,llama.cpp 文档用困惑度和 KL 散度来衡量它们的损失。GGUF 可以在 CUDA、ROCm、Vulkan、Metal 和 CPU 上运行,是可移植性最好的选择。
8 bit 与 FP8
Q8_0 是 GGUF 的 8 bit 类型。在 GPU 服务器上,常用的 8 bit 格式是 FP8。根据 vLLM 的 FP8 文档,FP8 计算需要计算能力 8.9 及以上的 NVIDIA GPU(Ada Lovelace、Hopper、Blackwell),更老的 GPU 会退回到仅量化权重的 W8A16 内核;FP8 能把模型内存减半,吞吐最多提升 1.6 倍,对精度的影响极小。
AWQ、GPTQ 与 4 bit 浮点
AWQ 和 GPTQ 是面向 vLLM、SGLang 等 GPU 服务器的 4 bit 仅权重量化方法。它们为权重分组校准缩放系数,激活保持 16 bit,许多模型发布方会直接提供这类版本,例如 Qwen/Qwen3-32B-AWQ。Blackwell GPU 增加了原生 FP4 计算,OpenAI 的 gpt-oss 模型则以 MXFP4 格式存储专家权重。
质量会损失多少
8 bit 格式通常很难与 BF16 区分。Q6_K 和 Q5_K_M 会带来小幅但可测的困惑度上升,在内存允许时是稳妥的默认选择。4 bit 是常见的折中:损失可以测出来,而且最容易在对小错误敏感的场景中显现,比如代码、数学以及从长上下文中精确找回信息。低于 4 bit 后误差迅速增大,小模型受到的影响比大模型更明显。在相同内存下,4 bit 的大模型往往胜过 8 bit 的小模型,但请用你自己的任务验证,方法见 AI 代理评估指南。
带宽决定生成速度,算力决定提示词处理速度
稠密模型每生成一个 token,都要把所有权重读取一遍,再加上当前上下文的 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 GB,因此在 1792 GB/s 下上限约为每秒 42 个 token,在 614 GB/s 下约为 14 个,在 256 GB/s 下约为 6 个。8B 的 Q4_K_M 文件(4.9 GB)在 448 GB/s 下约为每秒 91 个 token。实际运行时会低于这些上限,并随上下文增长而变慢:在 32K 时,70B 模型的缓存每个 token 还要多读约 10.7 GB。
llama.cpp 的量化表格在同一台机器上用 Llama 3.1 8B 展示了这一规律:生成速度从 F16 的每秒约 29 个 token 提高到 Q8_0 的 51 个和 Q4_K_M 的 72 个,而提示词处理速度在所有类型下都保持在每秒约 700 到 920 个 token 之间。
提示词处理以数百个 token 为一批进行,每次读取权重都能服务大量 token,瓶颈于是转移到矩阵运算吞吐。计算量约为 2 × parameters × prompt tokens 次运算,对 32B 模型处理 8000 个 token 的提示词来说约为 5 × 10^14 次。这决定了检索增强生成的首 token 延迟,因为提示词里带着检索到的段落,就像 pgvector 混合检索设计中那样;对需要发送大文件的编程代理也是如此。两项规格都要看:NVIDIA DGX Spark 在 273 GB/s 下的生成上限并不高,但 NVIDIA 给出的 GB10 芯片稀疏 FP4 算力最高可达 1 PFLOP。
批处理让一次权重读取服务多个序列,因此服务器的总吞吐会持续上升,直到算力或缓存耗尽。代理循环则更在意单个请求的延迟,因为每一步都要等待上一次调用,生产环境 AI 代理架构指南对此有详细讨论。
混合专家(MoE)模型把这两个约束分开:内存取决于总参数量,生成速度取决于激活参数量。gpt-oss-120b 共有 1170 亿参数,其中 51 亿为激活参数,其模型卡说明它可以装进单张 80 GB GPU;它的 MXFP4 GGUF 文件为 63.4 GB。gpt-oss-20b 可以在 16 GB 内运行。这正是大容量、中等带宽的机器仍然有价值的原因。
按能力划分的硬件选项
按显存档位划分的 NVIDIA GPU
NVIDIA GPU 的运行时支持最广,因为 vLLM、SGLang、TensorRT-LLM 和 llama.cpp 都把 CUDA 作为参考平台。先比较容量,再比较同一档位内的带宽:16 GB 的 GeForce 显卡能运行的模型相同,但 RTX 5080 的带宽是 RTX 5060 Ti 的两倍多。RTX PRO 6000 Blackwell 单卡即可容纳 8 bit 的 70B 模型。GeForce RTX 50 系列不支持 NVLink,因此多 GPU 之间的通信走 PCIe。
统一内存:Apple Silicon、Ryzen AI Max 与 DGX Spark
统一内存系统让 CPU 和 GPU 共用一个 LPDDR 内存池:可用于模型的内存远多于消费级 GPU,但带宽低于高速 GDDR7 显卡,Apple 最高端的芯片除外。在 Mac Studio 上,Apple 提供起步 96 GB 的 M5 Ultra,并表示 512 GB 配置将于 10 月底上市,还支持通过 Thunderbolt 5 和 RDMA 组建集群;可用的运行时包括基于 Metal 的 llama.cpp 和 MLX。AMD 的 Ryzen AI Max+ 395 采用 256 位 LPDDR5x-8000 接口,折合 256 GB/s;Ryzen AI Max+ PRO 495 升级到 LPDDR5x-8533,OEM 整机计划于 2026 年第三季度上市;llama.cpp 可以通过 ROCm 或 Vulkan 在两者上运行。NVIDIA DGX Spark 运行 CUDA 软件栈,并配有 200 Gbps 的 ConnectX-7 端口用于连接多台设备。
按上限公式计算,这些机器运行 70B 稠密模型的速度在每秒几个到几十个 token 之间,运行 MoE 模型则快得多。它们的 GPU 功耗预算远低于 575 W 的独立显卡,因此请用真实的提示词测量首 token 延迟。
| 平台 | 可用于模型的内存 | 带宽 | 功耗 | 32K 上下文下可运行的稠密模型 |
|---|---|---|---|---|
| GeForce RTX 5060 Ti 16 GB | 16 GB GDDR7 | 448 GB/s | 180 W | Q8_0 的 8B |
| GeForce RTX 5070 Ti / 5080 | 16 GB GDDR7 | 896 / 960 GB/s | 300 / 360 W | Q8_0 的 8B |
| GeForce RTX 5090 | 32 GB GDDR7 | 1792 GB/s | 575 W | Q4_K_M 的 32B |
| RTX PRO 4000 / 4500 Blackwell | 24 / 32 GB GDDR7 ECC | 672 / 896 GB/s | 145 / 200 W | 4 bit 的 32B |
| RTX PRO 5000 Blackwell | 48 或 72 GB GDDR7 ECC | 1344 GB/s | 300 W | Q8_0 的 32B,72 GB 版可运行 Q4_K_M 的 70B |
| RTX PRO 6000 Blackwell | 96 GB GDDR7 ECC | 1792 GB/s | 600 W 或 300 W(Max-Q) | Q8_0 的 70B |
| DGX Spark | 128 GB LPDDR5x | 273 GB/s | 240 W 电源 | Q8_0 的 70B |
| Ryzen AI Max+ 395 | 128 GB,最多 96 GB 分配给显卡 | 256 GB/s | 45 至 120 W | Q6_K 的 70B |
| Ryzen AI Max+ PRO 495 | 192 GB,最多 160 GB 分配给显卡 | 约 273 GB/s | 45 至 120 W | Q8_0 的 70B |
| Mac Studio, M5 Max | 最高 128 GB | 最高 614 GB/s | 整机最大 480 W | Q8_0 的 70B |
| Mac Studio, M5 Ultra | 最高 512 GB | 1.2 TB/s | 整机最大 480 W | BF16 的 70B |
最后一列来自上文针对单个用户的计算示例。这张表描述的是能力,而不是性价比。
多 GPU 与 CPU 卸载
两张 GPU 能让容量翻倍,但速度取决于切分方式。按层切分是 llama.cpp 的默认方式,每张 GPU 保存一段连续的层及其 KV 缓存,批大小为 1 时各 GPU 轮流工作:容量增加,生成速度不变。每个 token 只有少量激活数据经过 PCIe,所以 x8 甚至 x4 链路都够用。采用张量并行(vLLM 中的 --tensor-parallel-size 2)时,两张 GPU 同时读取每一层中各自的部分,从而提高上限,但每一层都要通过 PCIe 同步。vLLM 的张量并行是为相同型号的 GPU 设计的,GPU 数量必须能整除模型的注意力头数。
CPU 卸载会把部分层留在系统内存中,由 CPU 执行。每个 token 的耗时变成两部分之和:GPU 上的字节数除以显存带宽,加上 CPU 上的字节数除以内存带宽。双通道 DDR5-6000 的理论带宽为 96 GB/s(2 个通道 × 8 字节 × 6000 MT/s),DDR5 内存指南介绍了通道和频率如何共同决定带宽。一个 70B 的 Q4_K_M 模型如果 24 GB 放在 GPU、18.5 GB 放在内存中,速度会低于每秒 5 个 token。卸载解决的是容量问题,而不是速度问题。
MoE 模型的卸载效果要好得多。--cpu-moe 和 --n-cpu-moe N 把专家权重留在内存中,注意力和 KV 缓存则保留在 GPU 上,每个 token 只读取被激活的专家。新版 llama.cpp 在未设置 -ngl 时会自动适配层数(--fit 默认开启);需要可复现的结果时,请显式指定。下面的命令分别展示了部分卸载的稠密模型、专家放在内存中的 MoE 模型,以及偏向较大 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 W,所需系统功率为 1000 W。RTX PRO 6000 的 300 W Max-Q 版本与 600 W 版本内存相同,这在一个机箱里安装多张显卡时很重要。由于生成阶段在等待内存,可以用 nvidia-smi -pl 测试更低的功耗上限,保留生成速度几乎不变的那个设置。
推理是持续负载,相邻插槽里的两张开放式散热显卡会互相吹热风。请在 30 分钟的持续运行中检查频率、温度和功耗。
GeForce RTX 50 和 RTX PRO Blackwell 显卡使用 PCIe 5.0 x16。消费级台式平台通常只提供一条 x16 显卡链路,部分主板可以拆成 x8/x8,而芯片组插槽往往只以 x4 运行。按层切分可以接受这种情况;张量并行和模型加载则最好有 x8 或更宽的链路,工作站平台能够提供。GPU 空闲时显示的链路代数可能会降低,因此请在负载下检查。
系统内存至少要与你加载的最大模型文件一样大,再加上操作系统所需的空间;如果要卸载层,则要多得多。模型文件从约 5 GB 到远超 100 GB 不等,因此高速硬盘能缩短加载时间,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 设置生成的 token 数,-d 把 KV 缓存预先填充到指定深度,可以看出对话变长时速度如何下降。第二条命令对比 16 bit 和 8 bit 缓存:
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 的端点,报告首 token 延迟、每个输出 token 的耗时、token 间延迟和总吞吐:
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 链路是否降宽、是否出现温度或功耗降频,以及后端是否过慢。
配置检查清单
- 从
config.json记下参数量、层数、KV 头数和头维度。 - 选择量化:装得下就用 8 bit,其次是 Q6_K 或 Q5_K_M,然后是 4 bit,更低的档位只在测试后使用。
- 确定上下文长度和并发数,计算 KV 缓存,并决定能否接受 8 bit 缓存。
- 每个设备加 1 到 2 GiB,统一内存机器还要给操作系统留余量。
- 排除生成上限低于所需速度的平台。
- 对于 RAG 或编程代理的长提示词,要同时考虑算力,并测量首 token 延迟。
- 对于 MoE 模型,按总参数量估算内存,按激活参数量估算速度。
- 购买第二张 GPU 之前,检查电源、散热、PCIe 通道、内存和存储。
- 先做基准测试,缩小与上限的差距,再考虑增加硬件。