适用读者:要在"装不下"和"跑不满"之间做取舍、要评估量化/卸载/投机解码是否值得的人。
前置:S23-J22(KV 容量与批处理)、J15(带宽与下界)。
覆盖旧文:A-4341 §8.4–§8.6(压缩与卸载 + 推测解码 + 负载下配置选择,478 点)→ 478 点。
扩展点:E-S23-079(Q2_K 平均 2.625 bit/value,元数据占 24%)、E-S23-080(KV 量化:1152 → 612 / 324 MiB)、E-S23-081(PCIe 卸载 42.5 ms/轮 → 吞吐 ≤ 94 tok/s,爆 7 s 时限)、E-S23-082(NVLink-C2C 450 GB/s → 6.0 ms/轮)、E-S23-083(推测解码块长最优 m=4,13.34 ms/token)、E-S23-084(Little 定律n̄ = λT̄)。
上一篇:S23-J22 · 请求执行、批处理与 KV 分配
下一篇:S23-J24 · 分布式推理:布局与 PD 分离。
1. 一句话结论
"省内存"和"省时间"在三条路上是冲突的: 量化省容量、几乎不改速度;卸载省容量、按链路带宽付时间;推测解码省轮次、按接受率打折。选错方向就会像 PCIe 卸载那样——每轮 42.5 ms,直接超过 26.26 ms 的 decode 迭代。
出处:AI Infra 教材 §8.4–§8.6(
id 4341)。
量化 :容量 ↓,速度 ≈ 不变
卸载 :容量 ↓,时间 ↑(≥ 搬移量/链路带宽)
投机 :时间 ↓(按接受率),算力 ↑
2. 量化:位宽降下去,元数据占比升上来(E-S23-079)
Q2_K(GGML 分组量化):每组 256 个值
| 项 | 大小 |
|---|---|
| 2-bit 码值 | 256×2/8 = 64 B |
| scale + min 等元数据 | 20 B |
| 每组 | 84 B |
| 平均每值 | 84×8/256 = 2.625 bit |
| 元数据占比 | 约 24% |
Qwen3-235B-A22B 的 Q2_K 变体实测:
| 项 | 大小 |
|---|---|
| 量化编码 + 未量化浮点 | 64.43 GiB |
| 量化元数据 | 15.37 GiB |
| 文件头/填充 | ≈ 79.81 GiB |
UD-Q2_K_XL 变体 |
81.97 GiB |
M2 Max(96 GB 十进制):留给模型约 81.41 GiB。
79.81 GiB 文件 → 剩 1.60 GiB(够 1 条 8K:KV 1.47 GiB,余 0.13 GiB)
81.97 GiB 文件 → 超 0.56 GiB(装不下)
两文件只差 2.16 GiB,却决定能不能接一条请求
32K 上下文 → KV 要 5.88 GiB,必须加内存或换存放方式
判据:"能不能装下"是 2 GiB 级的判断题,不是"大概差不多"。 而且元数据也会随 KV 长度增长——量化不是免费的比例缩放。
3. KV 量化:只有最后一级能省(E-S23-080)
一条 8K 上下文的 BF16 KV = 1152 MiB;每 32 个 BF16 值占 64 B。
| 格式 | 每 32 值的字节 | 比例 | 8K KV |
|---|---|---|---|
| BF16 | 64 B | 1 | 1152 MiB |
| q8_0(8 bit + 2 B scale) | 34 B | 34/64 | 612 MiB |
| q4_0(4 bit + 2 B scale) | 18 B | 18/64 | 324 MiB |
q8_0 省 540 MiB;q4_0 省 828 MiB
平均每值:8.5 bit / 4.5 bit(不是 8 和 4——scale 也要摊)
判据:量化的收益要减去元数据。 位宽越低,元数据占比越高(Q2_K 已达 24%),所以"4 bit 就一定是 1/4"是错的。
4. 卸载:链路带宽直接决定可行性(E-S23-081、E-S23-082)
Qwen3-8B 一层 FFN 三个 BF16 矩阵 = 288 MiB;36 层里每 4 层卸 1 层,共 9 份 → 释放 2592 MiB。
| 预取缓冲 | 净省 | 多容纳 8K 请求 |
|---|---|---|
| 1 组(288 MiB) | 2304 MiB | 2 条 |
| 2 组(576 MiB) | 2016 MiB | 1 条 |
| 按生成完毕 1188 MiB 预留 | — | 两种都只 +1 条 |
4.1 时间账
每轮搬入 2592 MiB = 2.72 GB
PCIe Gen5 x16(64 GB/s/方向):2.72/64 = 42.5 ms/轮
对比 batch 1 一轮 decode:26.26 ms → 已经超了
吞吐上限:4 条请求 / 0.0425 s ≈ 94 tok/s
256 输出 token:255 × 42.5 ms ≈ 10.8 s > 7 s 时限
| 链路 | 每轮搬移 | 255 轮 | 可行性 |
|---|---|---|---|
| PCIe Gen5(65 GB/s) | 42.5 ms | 10.8 s | ❌ 爆 7 s |
| NVLink-C2C(GH200,450 GB/s) | 6.0 ms | 1.54 s | ✅ 藏在计算里 |
判据:卸载的可行性由"链路带宽 vs decode 迭代时间"直接决定。PCIe 上卸载大块 FFN 是负优化;C2C 上才可能被预取掩藏。
预取的约束:复制完成后计算才能读;计算不再用这组权重后缓冲才能写下一组。两组缓冲才能重叠。
5. 推测解码:接受率决定一切(E-S23-083)
5.1 正确性(不是"猜对了就算")
贪心:草稿 4 个,目标模型第 3 个不同 → 保留前 2 + 修正 1 = 3 个输出,第 4 个作废
采样:α(x) = min(1, p(x)/q(x)),拒绝后从 [p−q]₊ 归一化重采样 → 输出仍服从 p
判据:推测解码不改分布,只是用草稿网络换目标模型的轮次。
5.2 块长优化(原文练习 8-7)
a = 3/4、一轮验证 26.3 ms、草稿每 token 3.6 ms:
每轮期望输出 token 数 = 1 + a + a² + … + a^m = (1 − a^(m+1))/(1 − a)
T_m = 26.3 + 3.6m
| 块长 m | 期望输出 | T_m | ms/token |
|---|---|---|---|
| 1 | 1.75 | 29.9 ms | 17.09 |
| 2 | 2.31 | 33.5 ms | 14.49 |
| 4 | 3.05 | 40.7 ms | 13.34 ✅ |
| 8 | 3.70 | 55.1 ms | 14.89 |
按"每 4 个位置一组"执行(不足也按整组计时):m=5 需 T = 26.3+28.8 = 55.1 ms,输出 3.29 → 16.76 ms/token(更差)
实测(Qwen3-8B / DFlash,并发 1,中位数):
| 配置 | 完整耗时 |
|---|---|
| 普通 decode | 90.0 ms |
| K7(7 个草稿) | 30.6 ms |
| K15(15 个草稿) | 29.4 ms |
判据:K7 → K15 只再省 1.2 ms。块长有最优点:再长就只是多算被丢弃的 token(K15 一轮丢 14 个)。
6. 在线服务:Little 定律与准入(E-S23-084)
n̄ = λ·T̄ 系统内平均请求数 = 到达率 × 平均停留时间
例:4 req/s × 0.5 s = 2 条;停留 2 s → 8 条
准入检查:先看 KV 空间与剩余时限。
短请求:TTFT 0.196 s + 生成 6.76 s = 6.95 s,离 7 s 只剩 0.05 s
再多排队 0.1 s 就超时 → 拒绝 / 转交 / 换更快的配置
判据:排队时间也是预算的一部分。 系统内请求数由 λT̄ 决定,而不是"能装多少 KV"——两者都要满足。
6.1 16 条长请求同时到达:配置选择清单
| 判断 | 优先手段 |
|---|---|
| KV 放不下 | 分页 + 前缀共享 → 再量化 → 再换出 |
| 算力用不满 | 加 batch、投机解码(低负载时) |
| 权重装不下 | 量化 → 卸载(仅当链路够快) |
| TTFT 超标 | 分块 prefill、准入控制、PD 分离(J24) |
| 吞吐上不去 | 连续批处理 + 消除长 prefill 干扰 |
7. 可复算(实测)
$ cd /root/博客运营官/blog-v2 && python3 tools/s23_book_calc.py | tail -11
Q2_K: 64 B 码值 + 20 B 元数据 = 84 B / 256 值 → 2.625 bit/值,元数据 24%
KV q8_0: 1152 × 34/64 = 612 MiB(省 540 MiB)
KV q4_0: 1152 × 18/64 = 324 MiB(省 828 MiB)
卸载: 9×288 = 2592 MiB;净省 2304 / 2016 MiB
PCIe 64 GB/s: 2.72 GB → 42.5 ms/轮;255 轮 10.83 s(超 7 s)
C2C 450 GB/s: 2.72 GB → 6.0 ms/轮;255 轮 1.54 s
PCIe 吞吐上限: 4/0.0425 s ≈ 94 tok/s
投机 m=1: 期望输出 1.75,T 29.9 ms → 17.09 ms/token
投机 m=2: 期望输出 2.31,T 33.5 ms → 14.49 ms/token
投机 m=4: 期望输出 3.05,T 40.7 ms → 13.34 ms/token
投机 m=8: 期望输出 3.70,T 55.1 ms → 14.89 ms/token
按 4 个一组: m=5 → T 55.1 ms,输出 3.29 → 16.76 ms/token
Little: 4 req/s × 0.5 s = 2 条;× 2 s = 8 条
8. 前提与边界
| 结论 | 成立条件 | 不成立时 |
|---|---|---|
| 量化省容量 | 接受精度损失 | 质量敏感任务 → 用更高位宽 |
q4_0 = 18/64 |
每 32 值一组 | 分组更小 → 元数据占比更高 |
| 卸载可行 | 搬移时间 < decode 迭代 | PCIe 搬大块 → 严重变慢 |
| 投机加速 | 接受率够高、算力有余 | 高负载 → 争用资源,收益转负 |
n̄ = λT̄ |
稳定系统 | 突发流量 → 用排队模型 |
9. 常见误区
| 误区 | 纠正 |
|---|---|
| "2 bit 就是 1/8 大小" | Q2_K 实际 2.625 bit/值(元数据 24%) |
| "4 bit 量化就是 1/4" | q4_0 是 18/64 ≈ 28%,不是 16/64 |
| "卸载总能扩容量" | PCIe 每轮 42.5 ms,直接爆预算 |
| "草稿越长越好" | m=8 反而 14.89 ms/token;K15 一轮丢 14 个 |
| "能装 4 条就服务 4 条" | 还要看 λT̄ 与时限 |
10. 自测
- Q2_K 每组 256 值、84 B,平均多少 bit/值?元数据占多少?
- 8K 上下文 BF16 KV 1152 MiB,改 q4_0 后多少?省多少?
- 卸载 2592 MiB/轮,PCIe 64 GB/s,每轮多久?能跑满 7 s 时限吗?
a=3/4、T_m = 26.3+3.6m,块长 4 的每 token 耗时多少?
答案
84×8/256 = 2.625 bit;20/84 ≈ 24%。1152×18/64 = 324 MiB;省 828 MiB。2.72 GB/64 GB/s ≈ 42.5 ms;255 轮 ≈ 10.8 s,超 7 s,不可行。- 输出 3.05 个、耗时 40.7 ms → 13.34 ms/token。
11. 下一篇
S23-J24 · 分布式推理:布局与 PD 分离 —— 进入第 9 章:模型怎么摆、prefill 与 decode 为什么要拆开、AFD 与专家放置怎么影响 KV 分布。