引言:为什么推理是 LLM 落地的核心瓶颈
2024年至2026年间,大语言模型的能力边界不断被刷新,从百万级到千万级参数的模型层出不穷。然而,在实验室的 benchmark 数字背后,真正的挑战在于:如何让这些庞大模型在有限的硬件资源下,以可承受的成本、足够快的速度服务真实用户。训练一颗强大的大脑固然困难,但让这颗大脑持续、稳定、高效地思考,同样是一门精深的工程学问。
推理优化是一个横跨计算机体系结构、数值计算、分布式系统、编译原理等多个领域的综合性课题。本文将从 LLM 推理的独特计算特征出发,深入剖析 KV Cache 机制、推测解码(Speculative Decoding)、模型量化与压缩、PagedAttention 内存管理、连续批处理(Continuous Batching)等核心技术,并以 vLLM 和 TensorRT-LLM 为典型案例,展示如何将这些技术组合应用于生产级部署。
第一节:理解 LLM 推理的计算特征
1.1 自回归生成的本质矛盾
大语言模型的核心工作方式是自回归(Autoregressive):逐个 token 生成输出,每个 token 的生成都需要完整的前序 token 作为上下文。这一模式造成了 LLM 推理的两大独特挑战:
挑战一:内存带宽自瓶颈(Memory-Bound)。在生成阶段,模型需要将所有参数从 HBM(高带宽内存)加载到 GPU 计算单元。对于 70B 参数的 FP16 模型,单次推理需要加载 140GB 参数。以 H100 的 3.35TB/s 内存带宽计算,仅加载参数就需要约 42ms,这意味着理论上限约为 24 tokens/s。计算单元大部分时间在等待数据搬运,而非实际计算。
挑战二:序列长度动态变化。不同请求的输入输出长度差异巨大。一条简短问答可能只需 20 tokens,而一篇长文总结可能需要 4000+ tokens。传统静态批处理(Static Batching)会导致大量计算和内存浪费。
1.2 预填充与解码的分离
LLM 推理通常分为两个阶段:
预填充阶段(Prefill Phase):一次性处理全部输入 prompt,为每个 token 计算 KV 向量,存入 KV Cache。这一阶段是计算密集(Compute-Bound)的,GPU 利用率接近峰值,可并行处理整个输入序列。
解码阶段(Decode Phase):逐个生成输出 token。每次只新增一个 token 的 KV 向量到 Cache 中,并从 Cache 中读取全量 KV 向量计算注意力。这一阶段是内存带宽密集(Memory-Bound)的,传统方法每次只处理有效数据的一小部分,GPU 利用率极低,通常不到 15%。
理解这两个阶段的本质差异是掌握一切推理优化技术的基础。预填充阶段需要的是原始算力,解码阶段需要的是内存带宽和高效的 KV 缓存管理。
第二节:KV Cache 机制深度解析
2.1 KV Cache 的工作原理
在 Transformer 的注意力机制中,每个 token 都需要与所有前序 token 计算注意力分数。如果不做缓存,每次生成新 token 都需要重新计算所有历史 token 的 Key 和 Value 向量,复杂度为 O(n²)。
KV Cache 的思路十分直接:每个 Transformer 层的注意力计算完成后,将该层所有 token 的 Key 和 Value 向量保存下来。生成新 token 时,只需计算新 token 的 K、V 向量,追加到 Cache 末尾,然后使用新 token 的 Query 与全部 Cache 中的 Key 计算注意力。
数学上,第 t 步生成可表示为:
Attention(Q_t, K_{1:t}, V_{1:t}) = softmax(Q_t · K_{1:t}^T / √d) · V_{1:t}
其中 Q_t 是新 token 的 Query,K_{1:t} 和 V_{1:t} 是从 KV Cache 中读取的全部历史向量。
2.2 KV Cache 的内存占用分析
KV Cache 的内存消耗是 LLM 推理中最主要的内存开销之一。以 LLaMA-2-70B 模型为例:
单层 KV 大小 = 2(K和V)× seq_len × num_kv_heads × head_dim × dtype_size
= 2 × seq_len × 8 × 128 × 2 bytes(FP16)
= seq_len × 4096 bytes
= seq_len × 4 KB
模型总层数 = 80 层
总 KV Cache = 80 × seq_len × 4 KB = seq_len × 320 KB
对于一个 4096 token 的序列,单个请求的 KV Cache 就需要约 1.3GB 显存。在 A100 80GB 的显存中,除去模型参数本身 140GB(即使 FP16 也需要 140GB,实际需多张卡),KV Cache 成为决定最大批处理量和并发能力的关键因素。
2.3 KV Cache 的精度优化
在实践中,KV Cache 的精度可以适当降低:
FP16 → FP8:NVIDIA H100/B200 原生支持 FP8 计算,KV Cache 也可降为 FP8 存储,内存减半。研究表明,KV Cache 从 FP16 降为 FP8 对生成质量的影响可以忽略不计(困惑度差异 < 0.1%),这使得在同等硬件下可支持的序列长度翻倍。
KV Cache 量化:对于更激进的内存节省,可以对 KV Cache 进行分组量化(Group Quantization)。例如,按头维度分组,每组使用独立的 scale 和 zero-point。INT4 量化可将 KV Cache 降至原来的 1/4,但通常需要配合 GQA(Grouped Query Architecture)和 fine-grained 量化策略来保持质量。
第三节:PagedAttention —— 革命性的 KV Cache 管理
3.1 传统连续分配的痛点
在 PagedAttention 出现之前,推理引擎为每个请求预分配一块连续的 GPU 显存块来存储 KV Cache。这种方法存在严重的内存浪费:
预分配浪费:为保证长序列能容纳,系统按最大长度(如 4096 tokens)预留空间,但大多数实际请求远短于此。实测中,平均有效利用率仅 20%-40%。
内部碎片:由于不同请求的序列长度不同,预分配的固定大小块体造成大量内部碎片。
外部碎片:并发请求的动态创建和释放会在显存中留下不连续的空闲区域,进一步降低可用内存总量。
3.2 PagedAttention 的设计思想
vLLM 团队提出的 PagedAttention 借鉴了操作系统中虚拟内存和分页管理的思想,将 KV Cache 的连续分配转变为分页管理:
分页存储:将每个请求的 KV Cache 切分为固定大小的 block(通常 16 tokens 的 KV 向量),不再要求显存连续。一个请求的各个 block 通过 block table 串联,就像操作系统的页表一样。
按需分配:仅在需要时分配新 block,消除了预分配浪费。实例显示,内存利用率从传统方法的 20%-40% 提升至接近 100%。
零碎片:由于所有 block 大小相同,不存在外部碎片。任何空闲 block 都可被任何请求使用。
共享与 Copy-on-Write:在多轮对话、Beam Search 或 Parallel Sampling 场景中,多个序列可以共享前缀的 KV Cache block。当某个序列需要修改共享 block 时,执行 Copy-on-Write。这一特性在系统提示(System Prompt)共享场景中尤为重要。
3.3 PagedAttention 的实现细节
在 CUDA 层面,PagedAttention 需要自定义高效的 Attention kernel,能够从分散的 block 中随机读取 KV 向量。关键优化包括:
块表查找的合并:将 block table 常驻在 L2 Cache 中,减少 DRAM 访问。
Bank Conflict 避免:对 block 内部的数据布局进行 padding,避免 shared memory bank conflict。
与 Tensor Core 协同:利用 H100 的 Tensor Core 加速分页矩阵运算。在 A100 上,PagedAttention 实现了 24 tokens/s 的单请求解码速度,比传统方法提升 2-4 倍。
第四节:推测解码(Speculative Decoding)
4.1 核心思想:用小模型打前站
推测解码是近年来最具突破性的 LLM 推理加速技术之一。其核心思路利用了 LLM 推理的一个关键特征:简单 token 的生成比困难 token 更容易预测。
具体方法:使用一个小型但快速的自回归模型(Draft Model)作为"探路者",连续预测一批候选 token(通常 5-8 个),然后用大型目标模型(Target Model)并行验证这些候选 token。由于验证阶段可以并行处理所有候选 token,而 Draft 模型的参数远小于 Target 模型,即使需要丢弃部分错误候选,整体吞吐量仍然显著提升。
4.2 算法流程
推测解码的完整流程如下:
步骤 1:小模型推测。Draft Model(如 700M 参数)连续自回归生成 γ 个 token。这些 token 被作为候选序列。
步骤 2:大模型并行验证。Target Model(如 70B 参数)一次性并行处理整个候选序列(加上原始前缀),得到每个位置的概率分布。注意,这一步是并行执行的,而非逐 token 串行。
<步骤 3:接受/拒绝采样。对每个候选位置 i,比较 Target Model 和 Draft Model 的概率分布:
- 以概率 min(1, p_target(x_i)/p_draft(x_i)) 接受该 token
- 若被拒绝,从调整后的分布 max(0, p_target(x_i) - p_draft(x_i)) 重新采样一个 token
- 后续候选全部丢弃
步骤 4:剩余追加。如果全部 γ 个 token 都被接受,额外从 Target Model 的分布中采样下一个 token(因为 Target Model 的最后一个位置也产出了一个有效预测)。
4.3 加速效果分析
推测解码的加速倍率取决于两个因素:Draft Model 与 Target Model 的速度比、候选接受率 α。
以 700M Draft Model 搭配 70B Target Model 为例:
- Speed Ratio:小模型约为大模型速度的 11 倍(与参数量成反比)
- Acceptance Rate α:通常 0.6-0.85,取决于任务类型和小模型匹配度
- 期望接受数 E[accepted] = (1 - α^{γ+1}) / (1 - α),对 α=0.8, γ=5 约 3.66 tokens
- 净加速约 2-3 倍,Token 生成速率从 24 tokens/s 提升至 50-70 tokens/s
4.4 变体和扩展
SpecInfer(树状推测):不再使用线性链式推测,而是构建一棵推测树。多个独立的 Draft 模型并行生成不同分支,Target Model 使用 Tree Attention 并行验证整棵树,接受所有符合一致性约束的路径上的 token。理论上可进一步提升接受数。
Medusa(多头推测):在 Target Model 上附加多个轻量级的预测 Head,每个 Head 负责预测不同未来位置的 token。这些 Head 是大模型的顶层网络,不需要独立的 Draft Model,因此部署更简洁。每个 Medusa Head 额外仅需约 0.1% 参数量。
EAGLE( EagleAttention):使用 Target Model 倒数第二层的特征作为输入,训练一个轻量级的自回归模型来生成候选。由于直接利用了目标模型的内部表示,EAGLE 的接受率更高(通常 >0.85),且结构更简单。
第五节:模型量化与压缩
5.1 量化对推理的影响
模型量化是减少内存占用、提高推理吞吐量的最直接手段。从 FP16 到 INT8,模型体积减半,内存带宽需求减半;从 INT8 到 INT4,再减半。量化技术的关键在于:如何用更少的比特表达尽可能不损失精度的数值。
LLM 的权重和激活值分布具有明显特征:存在大量接近零的小值,同时少量参数/激活值是量级远大于均值的 outlier。均匀量化在处理这些 outlier 时会引入显著误差。
5.2 GPTQ:基于优化的训练后量化
GPTQ 是最经典的 LLM 训练后量化方法之一,属于二阶量化方法:
工作原理:逐层量化,使用未量化模型的 Hessian 矩阵信息指导量化过程。对于每一层权重 W,GPTQ 按列迭代处理:量化当前列后,使用未量化的其余列来补偿因量化引入的误差。
量化精度:GPTQ 支持 4-bit、3-bit 甚至 2-bit 量化。4-bit GPTQ 通常能将困惑度增加控制在 1% 以内。
推理优化:推理时,INT4 权重需要在 GEMM 计算中反量化为 FP16。为了高效利用 Tensor Core,GPTQ kernel 将反量化融合在矩阵乘法中,通过查表法(lookup table)避免分支判断。
5.3 AWQ:激活感知的权重量化
AWQ(Activation-Aware Weight Quantization)的发现是:并非所有权重同等重要。对应较大激活值的权重通道(Salient Weights)对模型输出影响更大。
AWQ 的做法是对这些重要权重通道给予更高精度(或完全不量化),对不重要的通道进行激进的 4-bit 量化。具体实现是通过搜索每个输入通道的缩放因子(per-channel scaling),在量化前对高重要性的权重行进行放大,使其在反量化后恢复原值。
AWQ 在 4-bit 量化的质量通常优于 GPTQ,且推理速度更快(不需要额外的补偿计算),已成为 vLLM、TensorRT-LLM 和 llama.cpp 默认支持的量化方案之一。
5.4 FP8 与硬件原生支持
NVIDIA H100/B200 GPU 原生支持 FP8 Tensor Core 计算。FP8 提供两种格式:E4M3(4位指数 3位尾数,精度高)和 E5M2(5位指数 2位尾数,范围大)。
混合精度推理:前向传播使用 FP8 计算 GEMM,但 Normalization 和 Attention 的 softmax 仍使用 FP16 以保证数值稳定性。
实验结果:在 H100 上运行 FP8 的 LLaMA-3-70B 推理,性能比 FP16 提升约 1.5-1.7 倍,而质量几乎无损失。这是目前性价比最高的量化部署路径之一,前提是硬件支持。
5.5 GGUF 格式与 llama.cpp 生态
llama.cpp 项目及其 GGUF 格式在开源社区中产生了深远影响。GGUF 支持从 2-bit 到 8-bit 的多种量化粒度,包括:
- Q4_K_M:4-bit 量化,中等质量级别
- Q5_K_M:5-bit 量化
- Q6_K:6-bit 量化,接近 FP16 质量
- Q8_0:8-bit 量化,无损级别
CPU-offloading 是 llama.cpp 的另一个杀手级特性:将模型的层部分或全部卸载到 CPU 内存,GPU 只处理热点层。虽然速度不如 GPU 推理,但使得在消费级硬件上运行 70B 模型成为可能。
第六节:并行策略与分布式部署
6.1 张量并行(Tensor Parallelism)
张量并行将模型的每一层按行或列切分到多个 GPU 上。以 Multi-Head Attention 为例,不同 GPU 计算不同注意力头的结果,最后通过 AllReduce 聚合。FFN 层可按列切分权重矩阵,对应通过 AllReduce 聚合输出。
优势:通信量小(每层只需要一次 AllReduce),负载均衡好。在 NVLink 拓扑(如 A100 的 600GB/s 互联)下效率极高。
劣势:每张 GPU 需要存储全部 KV Cache,对显存要求不降反增。且跨节点通信受 InfiniBand 带宽限制。
6.2 流水线并行(Pipeline Parallelism)
流水线并行将模型的不同层分配到不同 GPU。GPU 0 处理前 N 层,GPU 1 处理接下来 N 层,以此类推。不同请求在不同 stage 之间像流水线一样流动。
Micro-batching:为减少流水线气泡(bubble),将 batch 拆分为多个 micro-batch 在不同 stage 间交错执行。例如 4 级流水线中,当 stage 1 正在处理 micro-batch 3 时,stage 4 可以输出 micro-batch 0 的结果。
6.3 混合并行策略
在生产级部署中,通常会组合使用多种并行策略:
- 节点内张量并行:利用高速 NVLink 最大化单节点算力
- 跨节点流水线并行:通过 InfiniBand 连接不同节点
- 数据/序列并行:同一模型的多个副本并行处理不同请求,提升在线服务水平
以部署 Meta Llama-4-Maverick(400B MoE)为例,Meta 使用 8×H100 节点进行节点内张量并行,再通过跨节点流水线并行为每个请求提供服务。DeepSeek-V3 的 671B 参数则需要更多节点协同工作。
第七节:vLLM 架构与生产实践
7.1 vLLM 核心架构
vLLM 已成为开源 LLM 推理部署的事实标准,其核心设计围绕 PagedAttention 展开:
调度器(Scheduler):实现连续批处理(Continuous Batching / Iteration-Level Scheduling)。不再等待整个 batch 完成才添加新请求,而是在每次 decode iteration 结束后动态调整 batch 组成。首批正在生成较长输出的请求不会阻塞新到达的短请求。
KV Cache Manager:管理 GPU 和 CPU 的 block 分配。当 GPU KV Cache 不足时,将低频使用的 block swap 到 CPU 内存,需要时再 swap 回来。
Prefill-Decode Disaggregation(PD 分离):vLLM v0.6+ 支持将 Prefill 和 Decode 分配到不同的 GPU 资源池。Prefill 需要大量算力,可使用 Tensor Parallelism 加速;Decode 需要大内存带宽,适合单独部署。通过高速网络(NVLink/RoCE)传输 KV Cache 实现解耦。
7.2 TensorRT-LLM 的工业级实现
NVIDIA 的 TensorRT-LLM 提供了另一种高性能推理路径:
In-flight Batching:类似连续批处理,支持动态 batch 调整。
GEMM 与 Attention 融合:将矩阵乘法与 Attention 计算融合为单一 kernel,减少中间数据的读写开销。
Custom CUDA Kernels:针对 NVIDIA GPU 架构高度优化的 kernel 实现,包括 FlashAttention、Fused MLP(Dense + GEMM 一行完成)等。
FP8 + 量化直接路径:TensorRT-LLM 直接支持 FP8 和多种 INT 量化格式,无需额外工具链。
7.3 部署选型指南
选择 vLLM 的场景:
- 需要快速启动,支持多种模型架构(HuggingFace 格式直接加载)
- 需要灵活的功能开关(如 speculative decoding、prefix caching、prompt lookup decoding)
- 开源生态活跃,社区修复 bug 速度快
- 适合中小规模部署和研发实验
选择 TensorRT-LLM 的场景:
- 需要榨取极致的硬件性能(尤其是 NVIDIA H100/B200)
- 有专门的优化工程师团队进行模型编译和调优
- 与 Triton Inference Server 深度集成的企业级生产环境
第八节:前沿趋势与挑战
8.1 Sparse Attention 与长上下文
随着上下文窗口扩展到 100K+ tokens,标准 O(n²) Attention 的计算代价变得不可接受。Sparse Attention 只对关键位置计算全量注意力:
Mixture of Memory(MoM):在 InfiniAttn 中提出,将 KV Cache 分为局部窗口、压缩摘要和全局锚点三类,动态选择每个 Query 关注哪些 Key。
Ring Attention:将超长序列分布式切分到多个设备上,各设备通过环形通信依次将 KV 传递给下游,仅保留本地片段的 Cache。Google Gemini 1.5 的 100 万 token 上下文即采用此类技术。
8.2 分布式推断与边缘部署
拆分推断(Split Inference):将 Transformer 的浅层放在客户端设备(手机/PC),深层通过 API 在云端执行。在用户输入简单请求时(可被浅层缓存覆盖),甚至不需要访问云端。
模型卸载(Offloading):结合 CPU RAM 甚至 NVMe SSD 存储模型参数,在推理时按需加载到 GPU。GGUF + llama.cpp 已能实现这一模式,使得老旧 GPU 甚至集成显卡也能运行 13B 级别的模型。
8.3 推测解码与训练框架协同
推测解码的成功揭示了一个更广阔的方向:LLM 推理不一定必须从纯文本前缀出发。未来系统可能会结合:
- 结构化的模板预测:利用 prompt template 预知下一部分结构(如 JSON schema)
- 程序辅助推断:让 LLM 先输出代码框架,再用确定性代码填充细节
- 多模态跨域预测:用视觉特征辅助文本生成,或反之
结语
LLM 推理优化是一个快速发展的多层级技术栈。从底层的 GPU kernel 优化到中层的内存管理策略,再到顶层的分布式对齐与负载均衡,每一层都对最终性能有显著影响。
站在 2026 年的视角,我们正处在一个有趣的转折点:硬件进步让更大模型成为可能(H200、B200 的 HBM 容量达 141GB),同时优化技术让同等硬件可以服务更多请求。两者共同推动 LLM 应用的成本持续下降和体验持续提升。
对于从业者而言,理解这些优化技术的原理比单纯堆砌参数更重要。因为今天的"不可能",可能就是明天的"标配"。正如三年前的 175B 模型还需要集群部署,今天 7B 的模型已能在手机上运行——技术的本质就是将今天的极端需求,变成明天的日常体验。

发表评论 取消回复