Skip to content
懒人吧
Go back

反常识:为什么有些 7B 模型比 9B 模型更吃显存?(全面分析)

编辑页面

反常识:为什么有些 7B 模型比 9B 模型更吃显存?(全面分析)

引言

“模型越大越吃显存”——这听起来像常识,但在实际部署中,我们确实遇到了反直觉的情况:一个 7B 模型在同等量化下,占用的显存比另一个 9B 模型还多。

单纯说”量化差异”太片面了,影响模型显存占用的因素远比想象中复杂。

早在本文之前,我们已经写过一篇从量化角度分析的文章。但收到反馈:同量化下,7B 为什么比 9B 大?纯文本和视觉模型的区别?维度的影响?今天这篇全面分析会覆盖所有变量。

一、模型显存占用的完整公式

首先,一个模型推理时的显存占用不是只有”参数量 × 量化字节”这么简单。完整公式如下:

总显存 = 参数内存 + KV 缓存 + 激活内存 + 中间缓冲区

其中参数内存KV 缓存是两个大头,而它们又受多个架构参数影响。

二、同量化下,7B 比 9B 大的原因

原因 1:词表大小差异(最容易被忽略的因素)

词表大小(vocab_size) 决定了两个关键层的参数量:

embedding 层参数 = vocab_size × hidden_dim
lm_head 层参数   = vocab_size × hidden_dim(很多模型是 tied)
模型词表大小embedding 层占参数量
Qwen2.5 系列151K~0.6B
Llama 3 系列128K~0.5B
DeepSeek-V2102K~0.4B
Qwen3.6-35B-A3B152K~0.6B
某些多语言模型200K~256K~1.0B+

实战案例:

假设两个模型 hidden_dim 相同(4096):

模型参数量词表大小embedding 层大小
7B 模型 A7B200K200K × 4096 = 0.82B
9B 模型 B9B32K32K × 4096 = 0.13B

仅 embedding 层,7B 模型就比 9B 多了 0.7B 参数。

这 0.7B 虽然算在”总参数量”里,但会让人忽略一个事实:去除 embedding 层后,7B 的”实际 Transformer 核心参数”可能更少。 但显存占用上,这 0.7B 是实实在在加载进来的。

在同量化(比如 Q4)下:

原因 2:隐藏层维度与层数的不同组合

总参数量相同≠同一种架构。看一个核心公式:

Transformer 核心参数 ≈ layers × (hidden_dim² × 12 + 其他小项)

两个模型一深一宽:

模型总参层数(layers)隐藏维(hidden_dim)特点
模型 A7B56 层3584深而窄
模型 B9B28 层5120浅而宽

虽然模型 A 总参数少,但层数多意味着:

KV 缓存大小 ∝ 层数 × 隐藏维 × 量化字节 × 2 × 上下文长度

模型 A(7B)的 KV 缓存每层更小(3584 vs 5120),但层数翻倍(56 vs 28):

KV 缓存对比(同上下文同量化):
模型 A(7B): 56 × 3584 × X = 200704 × X
模型 B(9B): 28 × 5120 × X = 143360 × X

模型 A 的 KV 缓存比 B 大 40%!

参数量少的模型,KV 缓存反而可能更大。

原因 3:注意力头的配置差异(GQA / MQA)

现代模型广泛使用 GQA(Grouped Query Attention)MQA(Multi-Query Attention),这直接影响 KV 缓存的大小。

配置说明KV 缓存大小
MHA(标准)query_heads = kv_heads基准 1.0×
GQA-8每 8 个 query 头共享 1 个 KV 头0.125×
GQA-4每 4 个 query 头共享 1 个 KV 头0.25×
MQA所有 query 共享 1 个 KV 头1/query_heads

实例对比:

模型参数量Q 头数KV 头数KV 缓存相对大小
7B 模型 A7B3232 (MHA)1.0×
9B 模型 B9B324 (GQA-8)0.125×

9B 的 KV 缓存只有 7B 的 1/8。 显存占用一下子就反超了。

三、纯文本模型 vs 视觉模型(多模态)的区别

视觉模型多出来的组件

一个多模态视觉模型在纯文本模型的基础上,额外包含

多模态模型 = 文本基座 + 视觉编码器 + 视觉投影层
                                 ↑           ↑
                             额外参数     额外参数

视觉编码器(Vision Encoder)

常见的视觉编码器及其参数量:

视觉编码器参数量模型举例
CLIP ViT-L~0.3BLLaVA 1.5
CLIP ViT-H~0.6BLLaVA-NeXT
SigLIP ViT-SO~0.4BQwen-VL
InternViT-6B~6BInternVL2

关键问题:模型的”7B”通常只指文本部分的参数量!

看一个实际案例:

Qwen3.6-35B-A3B 的"35B"是文本部分
    
    但实际上还包含:
    - mmproj 投影层:~900MB(Qwen 的 mmproj-model-f16.gguf)
    - 视觉编码器:如果分离部署,额外显存

视觉投影层(mmproj)

mmproj 的逻辑是:

视觉编码器的输出 → mmproj 投影层 → 映射到文本嵌入空间

纯文本 vs 视觉模型显存对比

对比项纯文本 7B多模态 7B差异
文本参数量7B7B(不包含视觉部分)相同
视觉编码器-0.3~6B✅ 额外
mmproj 投影-~0.9GB✅ 额外
运行形态单模型文本 + 视觉流水线更复杂

所以一个标称”7B”的多模态模型,实际显存占用可能相当于 8~13B 的纯文本模型。

部署时的差异

我们实际部署 35B A3B 时:

# 纯文本推理(不含 mmproj)
--model 35B.gguf  → 参数显存 ~15.3GB(Q3_K)

# 多模态推理(含 mmproj)
--model 35B.gguf \
--mmproj mmproj.gguf  → 参数显存 ~15.3GB + ~0.9GB = ~16.2GB

同样的 35B,带视觉和不带视觉,显存可以差近 1GB。

四、几个典型实战案例

案例 1:大词表模型 vs 小词表模型

场景:在某次实际使用中,我们对比两个模型

对比项7B 多语言模型9B 英文模型
词表大小200K32K
层数4032
隐藏维40964096
量化Q4_K(同量化)Q4_K(同量化)
参数显存(参数×0.5)3.5GB4.5GB
实际加载后~8.5GB~7.2GB

为什么 7B 实际占用反而多 1.3GB?

分析:

  1. 大词表 200K:embedding 层 = 200K × 4096 × 0.5 字节 = 0.41GB
  2. 小词表 32K:embedding 层 = 32K × 4096 × 0.5 字节 = 0.07GB
  3. 差 0.34GB ✅
  4. 该 7B 模型层数多(40 vs 32)+ 注意力头配置差异导致 KV 缓存更大

仅词表差异一项就贡献了约 0.34GB 的差距。

案例 2:纯文本与视觉模型

对比项纯文本 7B多模态 7B
标称参数量7B7B(仅文本部分)
视觉编码器CLIP ViT-L(~0.3B)
投影层~0.1B
Q4 量化下加载~3.5GB + KV 缓存3.5GB + 0.2GB + KV 缓存
同量化同上下文~4.5GB~5.5GB(多 1GB)

案例 3:KV 头配置差异

模型参数量层数Q头KV头KV 配置KV 缓存大小(32K·Q4)
7B-A7B323232(MHA)无优化~1.2GB
9B-B9B28324(GQA-8)高效~0.15GB
7B-C7B563232(MHA)深层~2.1GB

9B 反而比两个 7B 的 KV 缓存都小。

五、影响显存占用的完整因素清单

由模型架构决定(不可改)

因素影响权重
总参数量参数内存🥇
词表大小 (vocab_size)参数内存(embedding + lm_head)🥇
隐藏维度 (hidden_dim)参数内存 + KV 缓存🥇
层数 (layers)参数内存 + KV 缓存🥇
KV 头数 (kv_heads)KV 缓存(直接影响巨大)🥇
中间维度 (intermediate_size)参数内存(FFN 层)🥈
是否多模态(视觉编码器 + mmproj)参数内存额外增加🥈
是否 MoE(专家数)所有专家参数都加载🥈

由部署配置决定(可改)

因素影响权重
量化等级参数显存(成倍变化)🥇
上下文长度 (ctx-size)KV 缓存🥇
批处理大小 (batch size)激活内存🥈
—n-gpu-layers部分 CPU 推理🥈

六、如何准确预估一个模型的显存

步骤 1:查模型架构参数

从模型的 config.json 中读取:

{
  "vocab_size": 152064,        // ← 词表大小
  "hidden_size": 4096,         // ← 隐藏维度
  "num_hidden_layers": 40,     // ← 层数
  "num_attention_heads": 32,   // ← Q 头数
  "num_key_value_heads": 8,    // ← KV 头数 ← 关键!
  "intermediate_size": 14336,  // ← FFN 中间维度
  "vision_config": {...}       // ← 有的话说明是多模态
}

步骤 2:估算参数内存

参数内存 ≈ 总参数量 × 量化字节

总参数量 ≈ (vocab_size + vocab_size) × hidden_dim     ← embedding + lm_head
         + layers × (hidden_dim² × 12 + ...)           ← Transformer 层
         + vision_encoder_params (如果有)               ← 视觉编码器
         + mmproj_params (如果有)                        ← 投影层

步骤 3:估算 KV 缓存

KV 缓存 = 2(K和V)× kv_heads × hidden_dim_per_head × layers × ctx_size × 量化字节

其中 hidden_dim_per_head = hidden_dim / num_attention_heads

步骤 4:汇总

总显存 ≈ 参数内存 + KV 缓存 + 1~2GB(激活和其他开销)

七、总结

“7B 比 9B 显存大”从来不是什么灵异事件,而是多个架构参数共同作用的结果。

原因说明影响程度
词表大小不同大词表的 embedding 层可达 1B+ 参数⭐⭐⭐
层数与维度不同层数多→KV 缓存大,参数量少不一定省显存⭐⭐⭐
KV 头配置差异GQA/MQA 可让 KV 缓存缩小数倍到数十倍⭐⭐⭐⭐
视觉 vs 纯文本视觉编码器 + mmproj 额外增加 0.5~6GB⭐⭐⭐⭐
注意力配置MHA vs GQA vs MQA 差异巨大⭐⭐⭐⭐

选模型不能只看”7B”或”9B”的数字,要看的完整清单:

□ 总参数量是多少?
□ 词表大小有多大?
□ 层数和隐藏维度是多少?
□ KV 头数:MHA 还是 GQA 还是 MQA?
□ 是否多模态?带视觉编码器吗?
□ 量化等级是多少?
□ 上下文长度设多少?

只有把这些全部对齐,“7B 比 9B 显存大”的疑问才能得到准确答案。


编辑页面
Share this post on:

Previous Post
MTP(多 Token 预测):大模型推理加速的“透视眼”
Next Post
小模型原地打转:模型为什么会陷入反复循环以及如何解决