LLM 推理流水线完整解析:Prefill-Decode 双阶段模型¶
📊 Level ⭐⭐⭐⭐ | 12.9KB
-> 原文存档
LLM 推理流水线完整解析¶
一句话¶
系统讲解 LLM 推理的完整流水线——从 tokenization 到流式输出,核心框架是 prefill(计算受限)vs decode(内存受限)双阶段模型,所有推理优化都针对其中一个阶段。
核心框架:Prefill vs Decode¶
LLM 的 generate() 调用在同一块 GPU 上经历两个截然不同的计算阶段:
| 阶段 | 工作方式 | 瓶颈 | 关键指标 |
|---|---|---|---|
| Prefill | 所有输入 token 并行处理,矩阵乘矩阵 | GPU 算术吞吐(compute-bound) | TTFT(Time to First Token) |
| Decode | 逐个 token 生成,query 向量 × 缓存矩阵 | 内存带宽(memory-bound) | ITL(Inter-Token Latency) |
诊断原则:当有人说模型慢,先判断是启动慢(prefill-bound → 优化 TTFT)还是流式输出慢(decode-bound → 优化 ITL)。二者消耗不同的硬件资源。
完整推理路径¶
1. Tokenization & Embedding¶
BPE tokenizer 将文本转为词表整数 ID(词表规模约 50K),映射到 [vocab_size, hidden_dim] embedding 矩阵。位置编码使用 RoPE(Rotary Position Embeddings)——通过旋转向量而非额外位置向量来编码位置。
2. Transformer 层¶
每层依次执行: - Self-attention:为每个 token 计算 Q/K/V 投影,query 与所有 key 打分 → softmax → 加权混合 value - FFN:两层 MLP 独立处理每个 token 向量(attention 跨位置传递信息,FFN 变换位置表示)
3. Prefill 阶段¶
所有输入 token 并行经过每一层,attention 以大型矩阵乘矩阵运行,GPU 利用率高。此阶段同时填充 KV cache(每层的 K/V 张量存入 GPU 内存供 decode 复用)。输出第一个 token。
4. Decode 阶段¶
每步只为新 token 计算 Q,与缓存中的 K/V 做 attention。算术量小但需从内存加载全部权重 + 完整 KV 缓存,瓶颈切换为内存带宽。
KV Cache:推理的核心约束¶
无缓存时生成 1K token 回答需每步重算完整 attention(平方级复杂度)。KV cache 将 K/V 存一次、增量追加,提速约 5 倍以上。
代价: - 13B 模型:每个 token 约消耗 1 MB KV cache - 4K 上下文:仅 KV cache 占 4 GB 显存 - 直接与 batch size 争夺 GPU 内存 → 并发能力下降
四种缓解方法:
| 方法 | 原理 |
|---|---|
| KV cache 量化(INT8/INT4) | 降低缓存精度 |
| Sliding window attention | 丢弃固定窗口外的 token |
| GQA(Grouped-Query Attention) | 多个 head 共享 K/V,减少缓存张量 |
| PagedAttention(vLLM) | 像 OS 虚拟内存一样分页管理缓存,消除碎片 |
DeepSeek V4:从结构上压缩 KV Cache¶
DeepSeek V4 Preview(2026-04-24)没有把 KV cache 当固定成本管理,而是重新设计 attention 让缓存结构性更小:
- CSA(Compressed Sparse Attention):softmax-gated pooling 压缩 KV 4 倍 → sparse attention
- HCA(Heavily Compressed Attention):128 个 token 的 KV 合并为 1 个压缩条目 → dense attention
效果(1M-token 上下文 vs V3.2): - 单 token 推理 FLOPs:27% - KV cache:10%(bf16 下 9.62 GiB vs 83.9 GiB) - 叠加 fp4/fp8 量化可再缩小 2 倍
→ 相关实体:DeepSeek V4 本地推理
量化:收益最高的优化手段¶
内存节省与 bit width 线性相关:
| 精度 | 7B 模型显存 |
|---|---|
| FP32 | 28 GB |
| FP16/BF16 | 14 GB |
| INT8 | 7 GB |
| INT4 | 3.5 GB |
- INT4 是 7B 模型在笔记本 GPU(4-6 GB)上运行的关键
- GPTQ / AWQ 使用 per-channel scaling 降低质量损失
- INT4 通常只比全精度低 1-2 个百分点
- FP16→INT8 推理延迟通常减半,质量损失可忽略
推理服务基础设施¶
现代推理服务器的三种核心优化:
| 技术 | 作用 |
|---|---|
| Continuous batching | 同一 GPU step 交错处理多请求的 token,decode 阶段也能保持高利用率 |
| Speculative decoding | 小 draft model 先提多个 token → 大模型一次 forward pass 验证,串行→并行 |
| PagedAttention(vLLM) | 固定大小 block 管理 KV cache,消除碎片,提升并发 |
框架组合:vLLM、TensorRT-LLM、TGI。一块 GPU 可服务几十并发用户——decode 阶段大量闲置算力被 continuous batching 填满。
实践结论¶
- 长 prompt 成本在 TTFT(prefill),长输出成本在 ITL(decode)——消耗不同硬件资源
- 上下文长度不免费——膨胀 KV cache,直接降低 batch capacity
- decode 阶段 GPU 利用率可能仅 30%——瓶颈在内存带宽不在算术计算
- 解决方向:更快的内存 + 更小的缓存 + 更好的 batching,而非更多算力
深度分析¶
TTFT 与 ITL:两条斜率不同的曲线¶
Prefill 随 prompt 线性增长、可完全并行;decode 单步恒定、必须串行。混在一张卡上,长 prompt 抬高全批 TTFT,为压 ITL 收紧 batch 又浪费 prefill 算力,两者资源配比还不兼得(FLOPS vs 带宽)。PD 分离的价值是让两类负载按各自瓶颈独立扩缩,代价是 KV 跨节点搬运——只有迁移成本低于调度损耗时才划算,KV 更小的架构因此让 PD 更便宜。
KV Cache 才是真正的容量约束¶
decode 每步搬全部权重加整条 KV,算术强度极低,token/s ≈ 每步字节 ÷ 带宽——加算力无用。字节里权重恒定、KV 随上下文线性涨,延迟与容量在长上下文下合成一个问题:装得下多少序列就有多少并发。分页治碎片(浪费从"预留到最大长度"降为尾块残余),前缀复用治计算侧(公共前缀 KV 从私有开销变成共享资产,故缓存须先分层再路由)。
量化收益为何非线性¶
位宽与显存线性,延迟不是。权重降位宽直接减少搬运字节,带宽受限的 decode 近等比例受益;权重一旦能留在片上或改由低精度张量核心执行,收益即被别的瓶颈吃掉。激活的离群通道让 per-tensor scale 失效、误差沿层累积,最先伤工具调用与复杂推理。KV 量化只压随序列增长的那项,收益随上下文放大。故"INT8 延迟减半"只在权重量化 + 带宽受限 + 长 decode 时成立。
投机解码的接受率经济学¶
收益 ≈ 期望接受数 ÷(草稿成本 + 验证成本)。草稿越强,接受率 α 越高但单步越贵,最优推测长度在两条曲线交点而非越大越好。难点是分布匹配:草稿偏移让 α 在代码、结构化输出、罕见语言上骤降;验证仍要为目标模型预留整批显存——省时间不省显存,KV 紧张时先撞容量墙。
公平性代价与 kLLM 数字的边界¶
continuous batching 把延迟问题变成排队问题:长 prefill 阻塞同批 ITL,只能靠调度显式纠正(chunk 切分、短请求优先、让出补偿防饿死),收益因此是分布性的——均值改善常伴随尾部恶化。kLLM 的 7.3× KV 容量、-25% TTFT、启动 10min→10s 同样绑定在 MLA cKV 跨 head 共享、8 卡节点、稀疏+压缩注意力与快手自身流量形状上;换 MHA 小模型或短对话流量多半不成立,可迁移的只是方法论。
实践启示¶
- 先分诊再优化。 启动慢查 prefill(prompt 长度、前缀命中、chunk 策略),流式慢查 decode(带宽、KV 读放大、batch 效率);混看平均延迟必然误判。
- 先算容量上限再谈吞吐。 用"每 token KV 字节 × 上下文 × 并发"估显存墙;容量不足时 KV 量化、GQA/MLA、前缀复用优先级高于加卡。
- 把前缀命中率当一级 SLO。 命中一档即省一次 prefill;再配 cache-aware 路由送到已持有该前缀的实例。
- 量化分部件决策。 权重先量化(收益稳定),激活谨慎(离群值 + 累积误差),KV 长上下文优先;用真实长尾流量验收而非只看 benchmark。
- 投机解码只在"接受率高 + 显存有余"时上。 先在自己流量上实测 α,偏低时草稿成本吃掉全部收益。
- 用 P99 与 SLO 达成率验收。 chunk prefill、公平调度、PD 分离都是均值与尾部的交换,收益须放回自己的流量分布重算。
延伸:分级 KV Cache、PD 分离、投机解码。
与现有知识的关联¶
- → DeepSeek V4 本地推理:V4 的 CSA/HCA 架构创新(本文第 6 节)与 antirez 的 ds4.c 本地推理引擎互补
- → GLM-5 Scaling Pain:高并发推理下的竞态 Bug,是本文第 8 节"推理服务基础设施"的反面案例
- → vLLM:PagedAttention 的具体实现
工业实践:快手 kLLM 全栈优化(2026-07)¶
快手系统软件团队围绕 GLM-5.2(DSA/MLA)与 DeepSeek-V4 构建自研推理引擎 kLLM,将本文上述概念落地为可量化的生产优化,原则是不以模型能力损失为代价做优化。
| 本文概念 | kLLM 工业实践 | 量化收益 |
|---|---|---|
| PagedAttention / KV cache | 分级 KV Cache(L1 GPU HBM / L2 CPU DRAM / L3 SSD+分布式)+ Cache-Aware 路由 | 命中率 +20pp、SLO 下吞吐 +30%、总命中率 ~87.6%;前缀树增量匹配使 GPU Bubble 400ms→30ms、Prefill +40% |
| Prefill vs Decode(TTFT vs ITL) | PD 分离 + SLO Load 驱动弹性:以相对 TTFT/TPOT SLO 的背离度统一度量 P/D 压力,取预测/真实值上界 | 容量生效速度 10min→10s(约 60×),OpenRouter Uptime 99%+ |
| Speculative decoding | DSpark 半自回归投机解码(并行 logits + 轻量序列模块 Bias 修正) | DeepSeek V4 Flash 线上 TPOT -15% |
| 长上下文 / KV 膨胀 | MLA 下 Attention Request DP + MoE EP 混合并行(cKV 跨 Head 共享无法 TP 切分 → 按请求维分) | 8 卡 KV 容量 2.9M→21.2M Tokens(7.3×)、TTFT -25% |
| Continuous batching 边界 | Chunk Prefill 公平调度 + Decode KV 高水位保护(短请求优先、长请求 Chunk 边界让出) | 平均 TTFT -17.8%、P50 -26.0%、P95 -12.1%(P99 +2.7%) |
核心洞见:①模型侧降本 ≠ 系统侧同比提效——新一代模型(稀疏激活/稀疏注意力/百万上下文)把瓶颈从单一算力问题转化为计算/通信/显存/调度耦合的系统问题;②并行边界应按状态分布方式重构(MLA cKV 沿 Request DP、MoE 沿专家 EP、Dense FFN 按需 TP),而非单一并行策略覆盖全模型。
Agent 场景延伸:kLLM 规划 Program-Aware 全生命周期调度——调度单元从"单请求"提升为一次 agent 会话/工作流,做暂停/恢复调度 + 工具调用空窗资源回收,指向推理系统向 agent 工作负载演进。