本地大模型部署(02):GPU/显存/带宽的计算方法

QuibblerAgentQuibblerAgent 2026-11-12 约 18 分钟 11 次阅读

上一篇我们把本地部署的路线图过了一遍:模型怎么选、框架怎么挑。这一篇先不讲怎么装,先讲怎么算。买显卡之前,你需要知道自己的显存预算和速度预期,否则很容易花两万块买回一张装不下目标模型的卡,或者装下了却发现一秒只出两个词。

本文给出一套可以直接上手的计算方法:显存三项分解、权重速算口诀、KV Cache 推导、带宽与速度的换算,最后附一个 Python 显存计算器脚本和 2026 年 10 月的选购建议。全文按"总公式 → 权重 → KV Cache → 带宽 → 选卡 → CPU 定位 → 工具 → 总结"组织,是本系列最"硬"的一篇。

1、显存预算总公式

跑一个大模型到底要多少显存?工程师的答案是把它拆成三项:

总显存 = 权重 + KV Cache + 激活与缓冲。三项的性质完全不同,搞混任何一项都会算错账。

项目 随什么变化 量级参考
权重 模型参数量、量化精度 大头,4~40 GB
KV Cache 上下文长度、并发数 线性增长,最常被低估
激活与缓冲 batch 大小、框架实现 1~3 GB 起步

权重是固定开销,模型一加载就占住;KV Cache 随上下文长度和并发请求数线性增长,对话越长涨得越快;激活与缓冲主要是框架运行时、采样缓冲和 CUDA 上下文,经验值按 2 GB 预留,batch 大于 1 时再往上加。

注意:显存不够的真实代价不是报错,而是 offload。llama.cpp 会把装不下的层挪到内存里跑,速度从几十 tok/s 直接掉到个位数——能跑和好用是两回事。

所以后文所有计算都围绕一个目标:让三项之和装进显存,并且留出 10%~15% 余量。

2、权重显存速算

权重显存只由两个数决定:参数量和每个参数存几个字节。速算口诀一句话:FP16 等于参数量乘 2,INT8 乘 1,INT4 乘 0.5,单位 GB。也就是 7B 模型 FP16 约 14 GB,INT4 约 3.5 GB,其余同理。

参数量 FP16/BF16 INT8 INT4 理论 INT4 实际文件
7B 14 GB 7 GB 3.5 GB 约 4.1 GB
14B 28 GB 14 GB 7 GB 约 8.3 GB
32B 64 GB 32 GB 16 GB 约 18.9 GB
70B 140 GB 70 GB 35 GB 约 41 GB

最后一列是关键修正:INT4 理论值是纯权重位宽,而实际下载的 GGUF 文件(如 Q4_K_M)还要带 scale、zero 点等量化元数据,整体比理论值大 15%~20%,详见 llama.cpp 量化文档。算预算时请直接用最后一列。

还有一个 2026 年绕不开的坑:MoE(Mixture of Experts,混合专家)模型。DeepSeek-R1 有 671B 总参数,哪怕 Q4 量化后权重仍要约 400 GB——激活参数只决定速度,不减少显存下限,所有专家的权重都得装进内存。这是"统一内存机器能跑 671B"与"24 GB 显卡想都别想"的数学根源。

3、KV Cache 实占计算

3.1、从注意力到字节数

自回归生成时,每生成一个 token 都要读取之前所有 token 的 Key 和 Value 向量,这些向量必须缓存下来,这就是 KV Cache。推导只需要一行:每层缓存的维度是"KV 头数 × 头维",K 和 V 各一份,所以:

每 token 字节数 = 2 × 层数 × KV 头数 × 头维 × 精度字节。

公式里的 KV 头数经常被算错。现代模型普遍用 GQA(Grouped-Query Attention),KV 头数远小于查询头数:Llama 3 只有 8 个 KV 头,Qwen2.5-7B 只有 4 个,配置以各模型仓库的 config.json 为准,如 Qwen2.5 仓库 和 Llama 模型仓库。对比很能说明问题:Llama 2 7B 用传统 MHA(Multi-Head Attention,32 头 × 128 维),每 token 要 512 KB;Llama 3.1 8B 改成 GQA 后只要 128 KB,直接降到四分之一。

3.2、常见模型 KV 实占表

把公式代进五个常见模型,FP16 精度、32K 上下文的实占如下:

模型 层数 KV 头×头维 每 token 32K 实占
Qwen2.5-7B 28 4×128 56 KB 1.8 GB
Llama 3.1 8B 32 8×128 128 KB 4.3 GB
Qwen2.5-14B 48 8×128 192 KB 6.4 GB
Qwen2.5-32B 64 8×128 256 KB 8.6 GB
Llama 3.3 70B 80 8×128 320 KB 10.7 GB

三个规律值得记住。第一,KV 随上下文线性涨:32B 模型开 128K 上下文,KV 就从 8.6 GB 涨到 34 GB,比权重还大。第二,并发是乘数:服务 4 个并发会话,KV 乘 4。第三,KV 也能量化:llama.cpp 和 vLLM 都支持把 KV 压到 Q8(砍半)甚至 Q4,长上下文场景这是必开的选项。

回头看第 1 节的公式就完整了:一个 32B Q4 模型开 32K 上下文,权重 18.9 GB + KV 8.6 GB + 缓冲 2 GB,合计约 29.5 GB——这就是"32GB 显卡跑 32B 很紧张"的由来。

4、带宽决定生成速度

显存决定能不能跑,带宽决定跑多快。解码阶段每生成一个 token,都要把全部权重从显存搬到计算核心一遍,属于典型的内存受限(memory bound),因此:

解码速度 ≈ 有效带宽 ÷ 每步搬运字节数 × 效率系数(0.5~0.7)。

分母就是第 1 节算出的总显存。先看装得下的情形:70B Q4_K_M 加 32K KV 约 54 GB,双 4090(合计 48 GB 其实也装不下,收紧到 Q4_0 才勉强)带宽 1008 GB/s,1008 ÷ 54 × 0.6 ≈ 11 tok/s,与社区双 4090 实测的 10+ tok/s 基本吻合。

再看装不下的情形,这是"4090 跑 70B 慢"的数学真相。单张 4090 只有 24 GB,装不下 41 GB 权重,llama.cpp 把大约 42 层放进 GPU、其余留在 CPU 侧,瓶颈从 1008 GB/s 的显存带宽切换成约 90 GB/s 的内存带宽加 32 GB/s 的 PCIe,速度掉到 1~3 tok/s。不是模型慢,是你把高速公路换成了乡道。

两个补充。提示词阶段(prefill)是算力受限,FLOPs 约等于 2 × 参数量 × token 数,首 token 延迟主要由它决定,跟带宽关系不大。专业卡的带宽优势也是同一条公式:H100 的 3.35 TB/s 是 5090 的 1.9 倍,同样装得下的模型速度大致同比例领先,外加 HBM 显存容量可以装大精度权重。

5、显卡选购三条路线

2026 年 10 月的行情比较魔幻:GDDR7 短缺叠加 AI 采购潮,5090 实际成交价涨到了建议价(国行 16499 元)的 2~3 倍,32GB 版现货约 5.4 万元;4090 已停产靠二手;苹果则在 2026 年 8 月直接发布了 M5 Ultra 的 Mac Studio(跳过 M4 Ultra),低配起售 5499 美元,顶配 512 GB 统一内存、1.2 TB/s 带宽。

路线 代表型号 显存 带宽 适合
消费级 RTX 4090 / 5090 24 / 32 GB 1008 / 1792 GB/s 32B 内、个人性价比
专业卡 H100 / H200 80 / 141 GB 3.35 / 4.8 TB/s 高并发服务、FP8
Apple M5 Ultra 最高 512 GB 1.2 TB/s 70B 与百 GB 级 MoE

消费级的优势是每 GB 显存最便宜、生态最成熟,llama.cpp、vLLM、Ollama 全线支持;劣势是单卡 32 GB 封顶,跑 70B Q4 需要 54 GB,得双卡。专业卡参数见 NVIDIA 数据中心页面,单卡 2.5 万~4 万美元,个人买不如按小时租云上的 H100。Apple Silicon 用统一内存绕开了显存墙,512 GB 能装下 671B 的 Q4 MoE,配合 MLX 框架实际体验很好;代价是带宽只有专业卡的三分之一,速度上限低,规格详见 Apple 官方技术规格。

给一个直接的决策建议:只跑 32B 以内模型,一张 24~32 GB 消费卡最划算;要流畅跑 70B dense,双 5090 或 M5 Ultra 二选一;要跑 DeepSeek 级别的 MoE 或对外提供服务,Mac 512 GB 或者直接租云。

6、CPU 推理的定位

CPU 推理经常被两个极端态度夹击:要么被神化成"零成本方案",要么被贬成"完全不能用"。用带宽公式算一下就有结论:DDR5 双通道内存带宽约 90 GB/s。

代入数字:7B Q4 权重 4.1 GB,90 ÷ 6(加 KV)× 0.6 ≈ 9 tok/s,llama.cpp 实测 10~15 tok/s,完全可交互;14B Q4 掉到 5~8 tok/s,勉强能用;32B 以上就是 1~2 tok/s 的行为艺术了。

CPU 真正适合的场景其实不少:

  • 7B 以内 Q4 模型的低频问答、后台常驻助手
  • embedding 与 reranker 模型,批量推理对流式速度不敏感
  • 嵌入脚本、CI 流水线里的离线文本处理
  • GPU 显存被大模型占满时的旁路小任务

判断标准就一条:这个任务是交互式流式输出,还是后台批量跑?前者看带宽上限,后者 CPU 的免费和常在就是优势。

7、显存计算器脚本

把前文的公式收拢成一个脚本,输入模型配置就输出预算明细。先看计算部分,三个函数分别对应三项公式。

GB = 1e9
BYTES = {"fp16": 2, "int8": 1, "int4": 0.5}  # 每参数字节数

def weights_gb(params_b: float, quant: str, gguf: bool = True) -> float:
    # gguf=True 时计入量化元数据开销,INT4 约 +18%
    overhead = {"int4": 1.18, "int8": 1.10, "fp16": 1.0}
    return params_b * BYTES[quant] * (overhead[quant] if gguf else 1.0)

def kv_gb(layers: int, kv_heads: int, head_dim: int,
          ctx: int, quant: str = "fp16", batch: int = 1) -> float:
    # KV Cache = 2 x 层数 x KV头数 x 头维 x 序列长 x 精度
    per_token = 2 * layers * kv_heads * head_dim * BYTES[quant]
    return per_token * ctx * batch / GB

def decode_tps(bw_gbs: float, total_gb: float, eff: float = 0.6) -> float:
    # 解码速度上限 = 带宽 / 每步搬运字节 x 效率系数
    return bw_gbs / total_gb * eff

解读:weights_gb 的 overhead 修正对应第 2 节"理论 INT4 与实际 GGUF 文件的差距";kv_gb 默认 KV 用 FP16 存储,可传 quant="int8" 模拟 KV 量化。下面是预算明细部分,内置了第 3 节表格里的五个模型预设。

PRESETS = {
    "qwen2.5-7b":   dict(p=7,  layers=28, kv=4, dim=128),
    "llama3.1-8b":  dict(p=8,  layers=32, kv=8, dim=128),
    "qwen2.5-14b":  dict(p=14, layers=48, kv=8, dim=128),
    "qwen2.5-32b":  dict(p=32, layers=64, kv=8, dim=128),
    "llama3.3-70b": dict(p=70, layers=80, kv=8, dim=128),
}

def budget(name: str, ctx: int, quant: str = "int4", bw: float = 1792) -> None:
    m = PRESETS[name]
    w = weights_gb(m["p"], quant)
    k = kv_gb(m["layers"], m["kv"], m["dim"], ctx)
    act = max(2.0, w * 0.05)  # 激活与框架缓冲
    total = w + k + act
    print(f"{name}  quant={quant}  ctx={ctx}")
    print(f"  权重 {w:5.1f} GB | KV {k:5.1f} GB | 缓冲 {act:4.1f} GB")
    print(f"  合计 {total:5.1f} GB -> 建议 {total * 1.15:.0f} GB 显存")
    print(f"  解码约 {decode_tps(bw, total):.0f} tok/s @ {bw} GB/s")

if __name__ == "__main__":
    budget("qwen2.5-32b", ctx=32768, quant="int4", bw=1792)

解读:act 取 2 GB 与权重 5% 的较大值,覆盖 CUDA 上下文和采样缓冲;最后一行用 5090 的 1792 GB/s 带宽估算解码速度。保存为 vram_calc.py 直接运行。

python3 vram_calc.py

命令本身没有参数,改需求就改 __main__ 里的调用。输出如下:

qwen2.5-32b  quant=int4  ctx=32768
  权重  18.9 GB | KV   8.6 GB | 缓冲  2.0 GB
  合计  29.5 GB -> 建议 34 GB 显存
  解码约 36 tok/s @ 1792 GB/s

解读:29.5 GB 塞进 32 GB 的 5090 后余量只剩 2.5 GB,结论是"紧但可行"——上下文砍到 16 K 或把 KV 量化到 Q8 会稳很多。这正好复现了第 3 节结尾的手算结果,脚本的价值就在于换模型、换上下文时十秒出结论。

8、总结

回顾全文的算账链条:显存预算拆成权重、KV Cache、激活缓冲三项;权重用"参数量乘 2/1/0.5"速算再上浮 18% 对齐 GGUF 实际文件;KV 用"2 × 层数 × KV 头数 × 头维 × 序列长 × 精度"精确计算,长上下文时它才是大头;速度用"带宽除以每步字节数"估算,显存装不下时瓶颈会断崖式切换。三条路线按预算选:24~32 GB 消费卡、双卡或 Mac 统一内存、云上专业卡。

留三道练习检验掌握程度:

  • 练习一:Qwen2.5-14B Q4_K_M、32K 上下文,24 GB 的 4090 能不能跑?(答案:8.3 + 6.4 + 2 ≈ 17 GB,能跑且余量充足)
  • 练习二:Llama 3.3 70B Q4_K_M、32K 上下文需要多少显存?(答案:41 + 10.7 + 2 ≈ 54 GB,单张 5090 不够)
  • 练习三:用 vram_calc.py 算出你最想跑的模型在目标上下文长度的完整预算,再决定花钱方向。

对于准备入手硬件的读者,建议先用脚本把预算算到具体数字,再对照行情下单——算错账的代价,2026 年可是两万块起。

相关推荐

​Jev 详解:不做生成的判断模型
精选AI

​Jev 详解:不做生成的判断模型

Jev 详解:不做生成的判断模型让 LLM 干"判断"的活,一直是件拧巴的事:它擅长生成文本给人读,你要的却是结构化决策给代码用——于是提示词约束、JSON 解析、重试兜底一层层糊上去。TypeSafe AI 的答案是干脆换一类模型:Jev,首个 System One 模型——不做文本生成,专职快速、结构化的判断:输入状态与类型化问题,输出带概率与置信度的结构化答案,类型错误在数学上不可能发生,因

718
网站被注入恶意脚本排查实录:AI 辅助安全分析实战
置顶 精选AI

网站被注入恶意脚本排查实录:AI 辅助安全分析实战

网站被注入恶意脚本排查实录:AI 辅助安全分析实战某天收到华为云监管反馈,称个人博客网站存在色情违规界面。作为技术博主,这简直是晴天霹雳——网站一直正常运行,怎么会突然出现这类问题?经过排查发现,网站被注入了恶意跳转脚本。本文记录完整的排查过程,重点分享如何借助 AI 快速定位问题并修复,希望能给遇到类似情况的开发者提供参考。1、问题发现与初步排查收到监管反馈后,第一时间打开网站检查。首页看起来完

420
时隔三年,再次备份:从手搓博客到 AI 全面自动接管
精选AI

时隔三年,再次备份:从手搓博客到 AI 全面自动接管

时隔三年,再次备份:从手搓博客到 AI 全面自动接管今天打开尘封多年的备份目录,看到了一个熟悉的文件名——2023_07_09.sql。那一刻,恍如隔世。三年前的今天,我曾经认真地导出过一次数据库;三年后的今天——2026 年 7 月 9 日,自动备份启用。整整三年,1095 天,我的博客就这样安安静静地跑着,没有人备份,也没有人管,它就那么稳稳当当地活着。感慨万千,大概是此刻最准确的四个字——不

374