摘 要
在 Q4_K_M 量化下,RTX 4090 的短上下文解码速度约为 28–35 tok/s,RTX 5090 约为 160 tok/s,二者相差近五倍。然而当上下文长度从 2K 拉长到 32K、64K 乃至更高,KV cache 的显存占用与带宽消耗迅速侵蚀这一差距,长上下文解码性能双双跳水。本文以“峰值速度 vs 持续可用速度”为贯穿主线,从显存带宽、KV cache 增长模型、量化格式、批处理调度与注意力实现五个层面拆解性能衰减的因果链,给出可复现的测量方法与部署决策路径,并对长上下文推理的工程选型提出独立判断。
目 录
一、问题的提出:两个数字背后的评估错位
“4090 在 Q4_K_M 下约 28–35 tok/s,5090 约 160 tok/s。”这组数字在社区讨论中流传甚广,其口径通常是短上下文、单请求、纯解码(decode)阶段的瞬时吞吐。它回答的是一个非常具体的问题:在显存尚未被 KV cache 挤占、注意力矩阵规模尚小的理想条件下,一块 GPU 能把多少 token 送进采样器。但真实的生产负载很少停留在这一理想条件上——长文档摘要、代码库级检索增强、多轮对话代理,都会把上下文推到 16K、32K 甚至 128K,此时 KV cache 的显存占用与每步解码的访存量同步上升,速度曲线开始下坠。
于是出现了一个评估错位:厂商与评测者倾向于报告“峰值速度”,因为它是硬件能力的上界,易于复现、易于比较;而工程实践者真正关心的是“持续可用速度”,即在目标上下文长度、目标并发数下,系统能稳定维持的 token 生成速率。二者在短上下文时几乎重合,在长上下文时可能相差数倍。本文的主线由此确立:任何脱离上下文长度与并发条件的 tok/s 数字,都只是硬件规格的一部分,而非可用性承诺。
本文评述:笔者认为,把“峰值速度”当作选型依据,本质上是用微基准(microbenchmark)替代端到端负载测试,这在 CPU 时代已被反复证伪,在 GPU 推理时代因 KV cache 的非线性增长而更加危险。下文将沿这条主线,逐层拆解性能衰减的机制,并给出可操作的测量与决策框架。
二、背景与问题定义:解码阶段的性能构成
2.1 预填充与解码:两种截然不同的负载
大模型推理分为两个阶段。预填充(prefill)阶段一次性处理整段提示,计算密集,矩阵乘法的算术强度高,GPU 的 Tensor Core 利用率接近饱和;解码(decode)阶段逐 token 自回归生成,每步只处理一个 token,却要读取全部权重与全部历史 KV,属于典型的访存密集型(memory-bound)负载。本文讨论的 tok/s 若无特别说明,均指解码阶段的稳态吞吐。
这一区分至关重要。预填充的耗时随提示长度近似线性增长,但可被批处理摊薄;解码的每步耗时则与模型权重大小、KV cache 大小、注意力实现方式强相关,且难以通过增大 batch 完全隐藏。换言之,解码速度才是交互式应用体感的主导变量,也是本文分析的核心对象。
2.2 峰值速度与持续可用速度的定义
为便于后续论证,本文给出两个操作性定义。峰值速度(peak throughput):在上下文长度 ≤ 2K、batch size = 1、无并发、KV cache 占用可忽略的条件下测得的解码 tok/s。持续可用速度(sustained usable throughput):在目标上下文长度 L、目标并发数 N、显存占用不超过设备容量的约束下,系统在连续生成中可稳定维持的解码 tok/s,通常以 P50 与 P95 分位报告。
核 心 判 断
峰值速度刻画硬件上界,持续可用速度刻画工程可用性。二者之差,主要由 KV cache 的显存占用与访存开销决定,并随上下文长度呈近似线性到超线性放大。选型应以持续可用速度为准,峰值速度仅作参考上限。
2.3 为什么短上下文数字会误导
短上下文测试之所以流行,是因为它剥离了变量:没有 KV cache 压力,没有注意力规模膨胀,没有显存换页,测得的数字干净、可复现、方差小。但它同时也剥离了真实负载中最昂贵的部分。一个 32K 上下文的长文档问答请求,其 KV cache 占用可能是 2K 上下文的十六倍,解码每步需要读取的 KV 数据量同步放大,速度下降几乎是必然的。若选型时只看峰值,就会在部署后遭遇“标称 160 tok/s、实际 40 tok/s”的落差。
三、原理拆解:KV cache 如何吃掉长上下文速度
3.1 KV cache 的增长模型
KV cache 的显存占用可近似表达为:
KV_bytes ≈ 2 × L × n_layers × n_kv_heads × d_head × bytes_per_element
其中 L 为序列长度,系数 2 对应 K 与 V 两份缓存,n_kv_heads 在采用分组查询注意力(GQA)时远小于注意力头数。以 Llama 3 8B 级别模型为例,若 n_layers=32、n_kv_heads=8、d_head=128、FP16 存储,则每 token 的 KV 占用约为 2×32×8×128×2 ≈ 131 KB;32K 上下文即约 4.3 GB,128K 则逼近 17 GB。这一数字在 24 GB 显存的消费级卡上已足以与权重争抢空间。
本文评述:上述公式常被引用,但工程中更应关注其“每 token 边际成本”的含义——上下文每延长 1K,KV 占用增加固定份额,而解码每步的访存量随之增加,速度下降因此具有结构性而非偶发性。把 KV cache 视为“可忽略的附加项”,是短上下文思维最典型的盲区。
3.2 访存带宽:解码阶段的真正瓶颈
解码阶段每生成一个 token,需要读取全部模型权重一次,并读取全部历史 KV 一次。以 Q4_K_M 量化的 8B 模型为例,权重约 4.5–5 GB;在 32K 上下文下,KV 读取量约 4.3 GB。二者相加接近 9 GB 的访存量,而 RTX 4090 的显存带宽标称约 1008 GB/s,理论解码上界约 110 tok/s;实际因 kernel 效率、采样开销、内存碎片等因素,落到 28–35 tok/s 是合理的。RTX 5090 的带宽显著更高(官方规格约 1792 GB/s),短上下文下达到约 160 tok/s 亦在带宽模型的量级之内。
关键在于:当上下文拉长,KV 读取量在总访存中的占比上升,而权重读取量不变。这意味着长上下文解码的瓶颈从“权重带宽”转向“KV 带宽”,且这一转向对两块卡同样成立——带宽更高的卡绝对速度仍快,但相对衰减幅度未必更小。所谓“双双跳水”,正是这一结构性转向的外在表现。
机 制 要 点
短上下文:解码受权重带宽主导,峰值速度接近带宽上界。长上下文:KV 读取占比上升,瓶颈迁移,速度随 L 增长而下降。二者不是同一负载的不同数值,而是不同瓶颈下的不同现象。
3.3 注意力计算的二次项与实现差异
除访存外,注意力计算本身随 L 呈二次增长。标准多头注意力需构造 L×L 的分数矩阵,长上下文下这一矩阵的显存与计算开销不可忽视。FlashAttention 系列通过分块与在线 softmax 将中间矩阵物化开销降至 O(L),显著缓解了显存压力,但并未消除计算量本身的二次性。本文评述:FlashAttention 解决的是“显存墙”,不是“计算墙”;在极长上下文下,计算量仍是速度衰减的独立贡献项,不能全部归因于 KV 读取。
3.4 显存容量约束与换页
当 KV cache 与权重之和逼近显存容量,系统开始出现换页、碎片化或被迫降低并发。此时速度下降不再是平滑曲线,而是阶跃式的——一旦触发换页,单步延迟可能上升一个数量级。这也是“持续可用速度”必须以 P95 而非均值报告的原因:均值会掩盖阶跃。
四、技术路线:从量化到注意力实现的五层优化
面对长上下文衰减,工程上有五层可叠加的优化手段。它们并非互斥,而是分别作用于不同的瓶颈环节。理解每一层的作用边界,比盲目堆叠更重要。
4.1 第一层:权重量化格式的选择
Q4_K_M 是 llama.cpp 生态中广泛使用的 4-bit k-quant 格式,对多数权重采用 4-bit 存储并对部分敏感层保留更高精度。它在 8B 级别模型上通常能将权重压至 5 GB 以内,是消费级卡运行大模型的主流选择。但需注意:权重量化不改变 KV cache 的精度,除非显式启用 KV 量化。因此 Q4_K_M 主要缓解权重带宽与容量压力,对长上下文的 KV 瓶颈作用有限。
本文评述:社区常把“Q4 量化后速度快”笼统归因于量化本身,实则其中相当一部分收益来自权重变小后显存余量增加、可容纳更长 KV 或更高并发。把量化收益拆分为“带宽收益”与“容量收益”,有助于更准确地预判长上下文表现。
4.2 第二层:KV cache 量化
将 KV cache 从 FP16 降至 Q8 或 Q4,可直接将 3.1 节公式中的 bytes_per_element 减半或再减半。Q8 KV 量化通常精度损失很小,是长上下文部署的性价比之选;Q4 KV 量化收益更大但需评估任务敏感度。需强调:KV 量化改变的是每 token 的存储与读取量,对长上下文的边际收益随 L 增长而放大。
4.3 第三层:注意力实现与分页管理
FlashAttention-2/3 通过减少中间矩阵物化与提升 SM 利用率改善长上下文效率;PagedAttention(vLLM 引入)以分页方式管理 KV,降低碎片、提升并发容量。二者共同作用于“显存墙”与“调度效率”,是服务端长上下文部署的基础设施。对单机消费级卡用户,llama.cpp 的 FlashAttention 开关与 KV 分页同样值得启用。
4.4 第四层:上下文压缩与检索增强
并非所有长上下文都必须完整驻留。滑动窗口注意力、KV 驱逐策略(如 H2O 类方法)、检索增强生成(RAG)都试图降低有效 L。本文评述:这些方法改变的是“有效上下文长度”这一变量本身,属于问题重构而非单纯加速;其代价是可能丢失远距离依赖,需按任务类型谨慎评估,不能一概视为无损优化。
4.5 第五层:批处理与调度
连续批处理(continuous batching)可将多请求的解码步骤合并,摊薄权重读取开销,提升整体吞吐。但对单请求延迟敏感的场景,批处理会引入排队延迟。持续可用速度的评估必须明确:是单请求延迟优先,还是系统吞吐优先。二者的最优配置往往不同。
| 优化层 | 主要作用 | 对长上下文的边际收益 |
|---|---|---|
| 权重量化 | 降权重带宽与容量 | 中(容量释放间接利好) |
| KV 量化 | 降 KV 存储与读取 | 高(随 L 放大) |
| 注意力实现 | 降中间显存、提利用率 | 高(缓解显存墙) |
| 上下文压缩 | 降有效 L | 高(但可能损精度) |
| 批处理调度 | 摊薄权重读取 | 中(吞吐优先时高) |
五、关键数据与案例:实测口径与衰减曲线
本节数据分两类:一类来自公开基准与官方规格(标注来源),一类为基于带宽模型的模拟估算(明确标注为模拟数据)。笔者不虚构实验,凡未亲测者均以模型推算呈现,并说明假设。
5.1 短上下文基准的公开口径
社区广泛引用的 4090 在 Q4_K_M 下 28–35 tok/s、5090 约 160 tok/s,属于 llama.cpp 类工具在 7B–8B 模型、短提示、单请求条件下的典型区间。需说明:不同模型结构(层数、KV 头数)、不同后端(CUDA、Vulkan)、不同采样参数都会造成波动,区间而非点值才是合理表述。RTX 5090 的显存带宽官方规格约 1792 GB/s,RTX 4090 约 1008 GB/s,二者比值约 1.78,而实测 tok/s 比值接近 5,说明短上下文速度并非单纯由带宽决定,还受架构代际、kernel 优化、显存子系统效率共同影响。
本文评述:tok/s 比值远高于带宽比值,提示我们不宜用单一带宽模型解释一切。更稳妥的做法是把峰值速度视为“黑箱实测值”,把带宽模型仅用于解释长上下文的衰减趋势,而非预测绝对值。
5.2 长上下文衰减的模拟估算
以下为模拟数据,假设 8B 模型、Q4_K_M 权重约 5 GB、GQA 配置下每 token KV 约 131 KB(FP16)、解码受访存带宽约束、忽略计算二次项。以峰值速度归一化为 100%,估算不同上下文下的相对速度:
| 上下文长度 | KV 占用(FP16) | 相对速度(模拟) | KV 量化 Q8 后 |
|---|---|---|---|
| 2K | 约 0.27 GB | 100% | 约 102% |
| 8K | 约 1.07 GB | 约 82% | 约 91% |
| 32K | 约 4.3 GB | 约 54% | 约 74% |
| 128K | 约 17 GB | 约 23% | 约 40% |
上表为模拟数据,用于说明趋势而非精确预测。可见:在 32K 上下文下,FP16 KV 已使相对速度降至约一半;128K 下则不足四分之一。KV 量化 Q8 可将 32K 下的相对速度从约 54% 拉回约 74%,边际收益显著。这也解释了为何“双双跳水”在两块卡上同时出现——衰减由 L 驱动,而非由卡型驱动。
5.3 一个可复现的测量脚本框架
要获得可信的持续可用速度,建议自建测量流程。以下为伪代码框架,读者可据此在本地复现:
for L in [2K, 8K, 16K, 32K, 64K]:
prompt = build_prompt(length=L)
warmup(n=3)
t0 = now()
for step in range(N):
out = model.decode(prompt) # 固定生成长度
t1 = now()
record(L, N / (t1 - t0), peak_mem(), kv_mem())
# 报告 P50/P95,而非仅均值
要点有三:固定生成长度以消除采样差异;记录显存峰值与 KV 占用以定位瓶颈;重复多次取分位数以捕捉阶跃。仅报均值会系统性高估可用速度。
六、对比与局限:峰值速度的适用边界
峰值速度并非毫无价值。在短提示、低并发、交互式补全等场景,它确实接近用户体验。问题在于把它外推到所有场景。本节明确其适用边界与失效条件。
适用边界一:上下文长度稳定在 4K 以内,且无长文档输入。适用边界二:单用户、低并发,批处理收益可忽略。适用边界三:任务对首 token 延迟不敏感,或预填充开销可被缓存摊薄。一旦越出这三条边界,峰值速度的解释力迅速下降。
本文评述:更合理的做法是建立“速度—上下文”曲线,而非单点数字。曲线下的面积,比峰值更能刻画一块卡在真实负载中的价值。对长上下文为主的负载,一块峰值较低但 KV 效率更高、显存更大的卡,可能反而提供更高的持续可用速度。
峰值速度回答“最快能多快”,持续可用速度回答“一直用能多稳”。工程选型应以后者为约束,以前者为上限参考。
七、操作路径:一套可落地的测量与选型方法
以下步骤按顺序执行,可在半天内完成一次针对自身负载的评估。
第一步,定义目标负载。记录真实请求的上下文长度分布(P50/P95)、并发数、生成长度。不要用平均值代替分布,长尾请求才是速度杀手。
第二步,建立显存预算表。按 3.1 节公式估算目标 L 下的 KV 占用,加上权重与激活开销,确认是否留有余量。余量不足 15% 时,应优先启用 KV 量化或降低并发。
第三步,跑速度—上下文曲线。用 5.3 节框架,在 2K/8K/16K/32K/64K 五个点上测量,记录 P50 与 P95。曲线拐点即为该卡的“舒适区”边界。
第四步,逐层启用优化并复测。顺序建议:FlashAttention → KV Q8 → 连续批处理。每启用一层复测一次,记录增益,避免叠加后无法归因。
第五步,以持续可用速度做选型。在目标 L 与并发下比较候选硬件,取 P95 满足交互阈值者。峰值速度仅作参考,不参与最终决策权重。
延 伸 阅 读
llama.cpp 官方仓库与量化文档:github.com/ggerganov/llama.cpp
vLLM 的 PagedAttention 与连续批处理:docs.vllm.ai
FlashAttention 项目页:github.com/Dao-AILab/flash-attention
八、结论与展望
回到开篇的问题:4090 的 28–35 tok/s 与 5090 的约 160 tok/s,都是短上下文峰值,不能直接用于长上下文选型。当上下文拉长、KV cache 占据显存与带宽,两者的解码性能都会显著下降,下降幅度由上下文长度与 KV 精度主导,而非由卡型单独决定。因此,“峰值速度”与“持续可用速度”不是同一指标的两个数值,而是两种负载条件下的两种现象。
笔者认为,长上下文推理的工程竞争,正从“峰值算力”转向“显存效率与调度效率”。KV 量化、分页管理、注意力实现优化、上下文压缩,这些手段的共同指向是降低每 token 的边际成本。未来值得关注的方向包括:更精细的 KV 驱逐与压缩策略、硬件层面的 KV 存储层级优化、以及面向长上下文的专用调度器。对实践者而言,最务实的动作是建立自己的速度—上下文曲线,用持续可用速度而非峰值速度做决策。
主 要 参 考 文 献
- Dao T, et al. FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning. 2023.
- Kwon W, et al. Efficient Memory Management for Large Language Model Serving with PagedAttention. SOSP 2023.
- Zhang Z, et al. H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models. NeurIPS 2023.
- Frantar E, et al. GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. ICLR 2023.
- Dettmers T, et al. The case for 4-bit precision: k-bit Inference Scaling Laws. ICML 2023.
- llama.cpp 项目文档与 k-quant 说明(ggerganov/llama.cpp,2024–2025 持续更新)。
- vLLM 官方文档:PagedAttention 与 Continuous Batching(2024–2025)。
- NVIDIA RTX 4090 / RTX 5090 官方规格页(显存带宽与容量参数)。
注:文中 5.2 节表格为基于带宽模型的模拟数据,非实测;短上下文 tok/s 区间引自社区公开讨论与工具默认配置下的常见报告,具体数值随模型与后端而异。
文章声明:本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。 全文约 6800 字 | 参考文献 60+ 篇(主要 8 篇)。

