丹尼拉(Dayfing)
返回文章列表
4,541 字18 分钟

2026 年本地运行 LLM 的硬件:显存、内存带宽与量化

要在本地运行开放权重的语言模型,执行计算的设备需要有足够的高速内存来容纳三样东西:量化后的权重、与上下文长度和并发请求数相匹配的 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 通道、内存和存储。
  • 先做基准测试,缩小与上限的差距,再考虑增加硬件。

更多文章