一个 7B 模型,q4 权重只要 4.6 GB, 但 8192 上下文的 KV 缓存又要 4.3 GB——合计 8.9 GB。买卡时只按权重挑,差的就是这一档。 671B 要 435 GB:能下载,永远装不下。
第一章把原理和成本都算完了。 从这一节开始动手——但第一步不是下载,是算清楚自己这台机器到底能装哪个档。
一、本地部署要准备的三样东西
硬件:显存(或内存)、磁盘、内存带宽。这三项决定「装得下吗」和「跑得动吗」。 软件:Python 环境、Ollama 本体、一个前端界面。装软件是确定的,装错了能重装; 硬件是确定不了的,装错了只能换机器。 网络:模型体积动辄几个 GB,网速决定你要等多久。 这一项最容易被忽略,但它只影响等待时间,不影响能不能用。 三样里只有硬件会真正卡死人,因为它的失败方式不是「装不上」, 是「装上了,然后慢到没法用」——这种失败最难被发现。
二、显存要算两笔,不是一笔
第一笔是权重:参数量 × 每参数占几位 ÷ 8。q4_K_M 大约每参数 4.8 位,7B 算出来是 4.6 GB。 第二笔是KV 缓存:模型在读上下文时,要把每个 token 的中间状态存下来,免得每次重算。 这笔开销随上下文长度线性增长。 公式是 2 × 层数 × 头数 × 每头维度 × 上下文长度 × 每数字节数。 7B(32 层、32 头、每头 128 维)在 8192 上下文下,算出来是 4.3 GB——和权重差不多大。 所以 7B 的真实占用是 8.9 GB,不是 4.6 GB。 把上下文调到 32768,KV 变成 17.2 GB,比权重还大。 这一条解释了一个常见困惑:明明权重只有 4.6 GB,8 GB 的卡为什么还是会爆? 因为还有 KV 和计算中间结果。
三、跑得快不快,看带宽不看核数
解码阶段每生成一个字,都要把全部权重从内存搬一遍——因为每个权重都要参与一次乘法, 而它不在缓存里。 所以速度有个很硬的上限:内存带宽 ÷ 权重体积。双通道 DDR4 实测约 25 GB/s, 25 ÷ 4.6 ≈ 5.5 tok/s。 这个算式能解释几乎所有现象。显卡快,不是因为算得快,是因为显存带宽高出一个数量级; 模型大一半就慢一半,因为要搬的字节多了一半;量化能提速,因为搬的东西变少了。 反过来,它也能解释为什么「加 CPU 核数」没用:瓶颈在总线,不在计算单元。 解码是访存密集型任务,不是计算密集型。
四、按机器选档,别按喜好选档
16 GB 内存、没独显:1.5B 舒服,7B 勉强(5 tok/s 上下)。 8 GB 显存:7B q4 刚好装下,但上下文别开太大,KV 会顶爆。 24 GB 显存:14B q4 舒服,32B 吃力(权重 19.5 GB 加 KV 就超了)。 48 GB 以上显存:70B 才能谈。 顺序一定是先量机器,再挑模型。 反过来做的结果,往往是下了 40 GB 的模型,跑起来一个字两秒,最后删掉重下。
五、动手 Demo:7B 的 q4 权重 4.6 GB,加 8192 上下文的 KV 变成 8.9 GB
按真实的模型配置算两笔账:权重(参数量乘每参数字节)和 KV 缓存(层数、头数、维度、上下文长度)。 先看 7B 在三档量化下的占用,再扫七个档位、用内存带宽反推每个档能跑多快。
bits = {u'fp16': 16.0, u'q8': 8.5, u'q4_K_M': 4.8, u'q2_K': 2.6}
ctx = 8192
w = 7.6e9 * bits[u'q4_K_M'] / 8 / 1e9 # 权重
kv = 2 * 32 * 32 * 128 * ctx * 2 / 1e9 # 2×层×头×维度×长×字节
print(w, kv, w + kv)
# 出字速度的上限:内存带宽 ÷ 权重体积
tps = 25.0 / w
实跑输出:
--------------------------------------------------------------------
部署前的准备:先算显存,再决定装哪个档
--------------------------------------------------------------------
先看一个 7B 模型在三档量化下的实际占用(上下文 8192):
量化 权重 KV 缓存 合计 每参数
----------------------------------------------
fp16 15.2 GB 4.3 GB 19.5 GB 16.0 bit
q8 8.1 GB 4.3 GB 12.4 GB 8.5 bit
q4_K_M 4.6 GB 4.3 GB 8.9 GB 4.8 bit
同一张表里有两笔钱:**权重是死的,KV 缓存是随上下文长出来的。**
8192 上下文的 KV 就有 4.3 GB,把它算漏了,买卡时一定差一档。
再扫全档:每个档位在 q4_K_M 下要多少显存、按内存带宽能跑多快。
档位 权重 KV(8k) 合计 CPU 出字(tok/s)
-------------------------------------------------------
1.5B 0.9 GB 0.7 GB 1.6 GB 27.8
7B/8B 4.6 GB 4.3 GB 8.9 GB 5.5
14B 8.9 GB 8.1 GB 16.9 GB 2.8
32B 19.5 GB 10.7 GB 30.2 GB 1.3
70B 42.4 GB 21.5 GB 63.8 GB 0.6
671B 402.6 GB 32.7 GB 435.3 GB 0.1
最后那一列是**用内存带宽除出来的上限**:每出一个字,全部权重都要从内存过一遍,
所以 25 GB/s ÷ 4.6 GB ≈ 5.5 tok/s。真实值只会更低,不会更高。
671B 那一行的 KV 是按常规多头算的,DeepSeek 自己用 MLA 把它压小了;
这里保留它是为了看另一件事:**权重占绝对多数,KV 只是零头。**
结论只有两句:
能装下 看「合计」这一列,比你的显存小就装得下
跑得快 看权重体积——它决定每个字要搬多少数据过总线
**参数越多,装不下和跑不动是同时发生的两件事**,不是先后关系。
第一张表:fp16 权重 15.2 GB、q8 是 8.1 GB、q4 是 4.6 GB。 但 KV 那一列三行全是 4.3 GB,一动不动——它只跟上下文长度和模型结构有关,跟量化无关。 合计那一列才是买卡要看的数:q4 也要 8.9 GB。 按 7B 只占 4.6 GB 去挑 8 GB 的卡,装下去就会在长上下文时崩。 第二张表扫了七个档。 看最后两列的关系:权重每翻一倍,出字速度就掉一半。1.5B 能到 27.8 tok/s, 70B 只剩 0.6——比人打字还慢,已经不是「慢」是「不能用」。 最后那一列是用 25 GB/s 除出来的上限,不是实测值。 真实速度还要再打折(系统占用、批处理、框架开销),但用它来判断「这个档要不要试」足够了。 671B 那一行的 KV 是按常规多头算的,DeepSeek 自己用 MLA 压缩过,实际小得多。 这里保留这一行是为了看另一件事:权重 402.6 GB 占绝对多数,KV 只是零头。模型大到这个量级, 讨论上下文已经没意义了。
30 秒实验
- 把 ctx 从 8192 改成 32768,看 KV 从 4.3 GB 变成 17.2 GB。 再算一遍合计——这时候权重只占三分之一,KV 才是大头。
- 把量化从 q4 换成 q8,权重从 4.6 涨到 8.1、出字速度从 5.5 掉到 3.1。 精度和速度的交换比,就摆在这两列里。
- 把内存带宽从 25 改成 50(DDR5),出字速度正好翻倍。 再想想:如果换成显存 500 GB/s,速度会到多少?现实里为什么到不了这个数?
常见误区
- 「显存够放权重就行」。还要放 KV 缓存,以及计算时的中间张量。 7B 在 8192 上下文下的真实占用接近权重的两倍。
- 「CPU 核多就跑得快」。解码是访存密集型任务,瓶颈在内存带宽,加核数几乎没帮助。 加带宽才有用。
- 「参数量除以 2 就是显存占用」。那是 fp16 的一半,只算了权重,没算 KV,也没算量化带来的元数据。
自测三问(点开对答案)
1. 7B 的 q4 权重只有 4.6 GB,为什么实际要按 8.9 GB 准备? —— 因为还有 KV 缓存。8192 上下文下 7B 的 KV 是 4.3 GB,几乎和权重一样大。 kv = 2 × 层 × 头 × 每头维度 × 上下文 × 字节数。 2. 为什么显卡跑大模型比 CPU 快这么多? —— 主要不是算力,是显存带宽。解码每出一个字都要把全部权重过一遍,所以速度 ≈ 带宽 ÷ 权重体积。 显存带宽比双通道 DDR 高一个数量级以上。 3. 64 GB 内存的机器能跑 671B 吗? —— 不能。q4 下权重就要 402.6 GB。 就算用 mmap 把权重放在磁盘上硬跑,每个字都要从磁盘读几百 GB,速度会掉到分钟级, 没有使用价值。机器算清楚了,下一步是把软件环境备好。下一节先写一个自检脚本,把「这台机器现在有什么」量出来。
- ☐ (本节完,下一节 2.1.2 安装Python依赖项)