如果说分布式训练回答的是“大模型如何在千卡集群上训练出来”,那么推理服务回答的就是另一个更贴近线上系统的问题:模型训练完成之后,如何在真实业务流量下稳定、快速、低成本地生成答案。

这里的“推理”需要先做一个区分。它既可以指 Inference Serving,也可以指 Reasoning Model。前者关注模型服务系统:请求如何进入模型、token 如何生成、KV Cache 如何管理、延迟和吞吐如何平衡;后者关注模型能力机制:如何通过长链思考、验证器、强化学习和 test-time compute,让模型更擅长数学、代码和复杂推理。

本文讨论的是第一种:推理服务。它不关心模型参数如何继续学习,而关心一个已经训练好的模型,如何在固定参数下被高效调用。换句话说,预训练和后训练决定模型“会什么”,分布式训练决定模型“怎么训出来”,而推理服务决定这些能力能不能以可承受的成本、稳定地交付给真实用户。

简单来说,推理服务的本质,是在模型参数固定的情况下,把自回归 token 生成过程组织成高吞吐、低延迟、低成本、可扩展的在线系统

从训练到推理

训练和推理最大的区别是:训练会更新参数,推理不会更新参数。训练阶段,模型通过前向传播计算 loss,再通过反向传播更新参数;推理阶段,模型参数已经固定,系统只是在给定 prompt 的情况下调用模型,让它生成下一个 token。如下图所示:

训练 vs 推理

从函数角度看,训练完成后的大模型可以理解为一个固定函数:

1
fθ(context) -> P(next token | context)

其中,θ 是训练好的模型参数,context 是当前上下文。模型每次读取上下文,输出下一个 token 在整个词表上的概率分布;解码策略再从这个分布中选出具体 token。一次生成过程大致如下:

自回归生成流程

因此,推理服务不是一次性生成完整答案,而是一个不断循环的过程:上下文 -> 概率分布 -> 选择 token -> 更新上下文 -> 继续生成这正是大模型推理服务的工程难点来源:每生成一个 token,都要调度一次模型前向计算;每多一个用户请求,系统就多一份上下文和缓存压力;每拉长一次上下文,首 token 延迟和显存占用都会上升。

线上推理服务通常关注以下指标:

指标 含义 影响体验
TTFT Time To First Token,首 token 延迟 用户多久能看到第一个输出
TPOT / ITL 每个输出 token 的生成间隔 流式输出是否顺滑
Latency 请求从开始到结束的总耗时 端到端体验
Throughput 单位时间生成 token 数 系统吞吐和服务成本
Concurrency 同时服务的请求数量 高峰期承载能力

这些指标之间存在天然权衡:

  • 吞吐 vs 延迟: batch 越大,GPU 利用率可能越高,但单个请求等待时间可能变长;
  • 长上下文 vs 成本: 上下文越长,能力可能越强,但 prefill 计算和 KV cache 显存都会增加;
  • 输出长度 vs 响应速度:输出越长,decode 步数越多,总耗时越高;
  • 并发能力 vs 显存占用:并发越高,每个请求的 KV cache 会叠加,占用更多显存。

所以,推理服务真正要解决的问题,不只是“模型能不能生成答案”,而是:如何在固定模型参数下,把自回归生成过程调度成一个低延迟、高吞吐、低成本的在线系统

推理成本:Prefill、Decode 与 KV Cache

理解推理服务,最关键的是先把一次请求拆开看。大模型生成答案不是一次性完成的,而是分成两个阶段:PrefillDecode。前者负责“读懂输入”,后者负责“逐字生成”。这两个阶段的计算形态完全不同,也决定了推理服务的主要成本来源。

推理服务中的 Prefill 和 Decode

Prefill 阶段:先读完上下文

Prefill 阶段负责处理用户输入的完整 prompt。由于输入 token 都是已知的,模型可以一次性并行计算它们的 attention、MLP 和 hidden states,并生成后续 Decode 阶段要复用的 KV Cache。可以把 Prefill 理解为 读题

1
prompt 越长 -> 输入 token 越多 -> prefill 计算越多 -> TTFT 越高

这就是为什么长文档问答、代码仓库分析、多轮长对话的首 token 往往更慢。模型不是“不想回答”,而是必须先把上下文完整读进去。

从计算特征看,Prefill 更接近一次大规模矩阵-矩阵乘法,GPU 并行度高,通常属于 计算密集型(Compute-Bound) 阶段。它的速度主要受 GPU 算力影响,能够比较充分地利用硬件。Prefill 的最终产出主要有两个:

  • 完整 prompt 对应的 KV Cache
  • 第一个生成 token 的概率分布。

Decode:逐 token 生成答案

Decode 阶段负责真正生成回答。它是自回归的:第 t+1 个 token 必须等第 t 个 token 生成之后才能继续。

1
token_1 -> token_2 -> token_3 -> ... -> token_n

这带来一个天然限制:输出越长,decode step 越多,总耗时越高。即使每一步都很快,长答案也必须一步一步生成。可以把 Decode 理解为 写答案:Prefill 决定用户多久看到第一个 token,Decode 决定后续流式输出是否顺滑。

指标 主要受什么影响
TTFT Prefill 成本、排队时间、prompt 长度
TPOT / ITL Decode 速度、batch 调度、KV Cache 访问效率

从计算特征看,Decode 每一步只处理最新生成的一个 token,并读取所有历史上下文的 KV Cache。这更接近矩阵-向量计算,batch 较小时并行度不高。因此,Decode 通常是 内存带宽密集型(Memory-Bandwidth Bound) 阶段。它的瓶颈往往不是 GPU 算力不够,而是需要不断从 HBM(High Bandwidth Memory,高带宽显存)读取模型权重和不断增长的 KV Cache,再送入片上 SRAM(Static Random Access Memory,静态随机存取存储器)参与计算。

这也是为什么 Decode 阶段经常出现一种现象:GPU 计算单元并没有完全吃满,但生成速度仍然上不去。瓶颈不在“算得慢”,而在“数据搬得慢”。

KV Cache:用显存换计算

Transformer 在生成新 token 时,需要关注前面所有历史 token。如果每一步都重新计算历史上下文的 Key 和 Value,计算成本会非常高。因此,推理系统会引入 KV Cache:把历史 token 在各层 attention 中的 Key / Value 缓存下来,后续 Decode 时直接复用。

KV Cache 作用

KV Cache 的核心价值是:用显存换计算

1
2
没有 KV Cache:每一步都重新计算历史上下文的 K/V
有 KV Cache:只计算新 token 的 K/V,并复用历史 K/V

这样可以避免大量重复计算,让 Decode 阶段从“反复处理整个历史上下文”,变成“处理新 token + 读取历史缓存”。但 KV Cache 也带来了新的瓶颈:显存占用。它的大小可以粗略估算为(实际单卡显存还会受 Tensor Parallel、Pipeline Parallel、GQA/MQA、beam search、多采样等因素影响):

1
KV Cache ≈ 2 × layers × tokens × kv_heads × head_dim × bytes × batch_size

其中:

  • 2 表示 Key 和 Value;
  • layers 是模型层数;
  • tokens 是上下文长度,包括 prompt 和已生成 token;
  • kv_heads 是 KV head 数量;
  • head_dim 是每个 head 的维度;
  • bytes 是每个数值占用的字节数;
  • batch_size 表示并发 batch 中的请求规模。

这个公式说明:上下文越长、输出越长、并发越高,KV Cache 越大。对于长上下文任务,KV Cache 的显存占用甚至可能接近或超过模型权重本身。

场景 为什么 KV Cache 压力大
长 prompt Prefill 后初始 KV Cache 就很长
长输出 每生成一个 token,都要追加新的 K/V
高并发 每个请求都要维护自己的 KV Cache
多轮对话 历史消息越长,缓存越大
多采样 / beam search 多条候选路径会增加缓存管理压力

所以,KV Cache 既是优化,也是新的瓶颈。它解决了重复计算问题,却把压力转移到了显存容量、显存带宽和缓存调度上。现代推理优化,很大一部分都围绕 KV Cache 展开:

  1. PagedAttention: 像操作系统分页一样管理 KV Cache,减少显存碎片;
  2. KV Cache 量化:用 INT8 / INT4 等低精度存储 K/V,降低显存占用;
  3. KV Cache 压缩:通过低秩、稀疏化或聚合方法减少缓存规模;
  4. 选择性保留:只保留更重要的历史 token 或注意力信息;
  5. Prefix Cache:复用相同系统提示词、长文档前缀或多轮对话前缀;
  6. Chunked Prefill:把长 prompt 分块处理,降低首 token 阻塞和调度压力。

因此,推理服务的关键问题不是“模型能不能跑起来”,而是:如何在长上下文、高并发、长输出的情况下,高效管理 KV Cache,并把 Prefill 和 Decode 调度好

服务系统:如何把 GPU 用满?

前面讲的是单个请求的成本结构:Prefill 负责读上下文,Decode 负责逐 token 生成,KV Cache 决定长上下文和高并发的显存压力。但线上推理服务真正难的是:请求不是一个一个安静排队来的,而是同时到达、长度不同、输出不同、优先级不同。系统既要让单个用户感觉快,又要让整体 GPU 利用率足够高。推理服务要解决的核心矛盾是:

  • 单个请求希望低延迟;
  • 整体系统希望高吞吐;
  • GPU 希望持续满载;
  • 显存希望尽量不碎片化。

所以,推理服务系统的关键能力,不只是“跑模型”,而是 batching、调度、缓存管理和解码优化

在线推理系统优化方向

Batching:把请求合起来算

GPU 擅长大规模并行计算。如果一个请求一个请求跑,矩阵规模小,GPU 利用率会很低。Batching 的核心思想是:把多个请求合并成一个 batch,一起送进模型计算。

方式 核心思路 适用性
静态 batching 等一批请求凑齐后一起计算 离线任务更适合,在线延迟较差
动态 batching 在短时间窗口内合并请求 在线服务常用,需要调度策略
Continuous batching Decode 过程中持续加入新请求 适合 LLM 流式生成
In-flight batching 正在生成的 batch 中动态增删请求 更适合高并发在线推理

静态 batching 和早期动态 batching 最大的问题是:batch 一旦形成,内部请求长度不一致就会造成浪费。短请求先结束,但长请求还在生成,GPU slot 不能被及时复用。Continuous batching 这里的思想是:

1
2
请求结束 -> 释放 slot
新请求到来 -> 立即补进 batch

这样可以让 Decode 阶段的 batch 始终保持较高利用率,显著提升吞吐。

在很多语境下,Continuous Batching 和 In-flight Batching 都是在描述“生成过程中动态加入/移除请求”的迭代级调度思想,不同框架叫法和实现细节略有差异。

PagedAttention:管理 KV Cache 的碎片

Batching 提高了 GPU 计算利用率,但也放大了 KV Cache 的管理问题。不同请求的 prompt 长度、输出长度都不一样,KV Cache 会在生成过程中动态增长;有的请求已经结束并释放缓存,有的请求还在继续生成。如果要求 KV Cache 在显存中连续存放,就很容易产生碎片:表面上还有剩余显存,但找不到足够大的连续空间容纳新请求。

PagedAttention 的思路来自操作系统的虚拟内存管理:不再把每个请求的 KV Cache 当作一整段连续显存,而是切分成许多固定大小的 block。逻辑上,一个序列的 KV Cache 仍然是连续的;物理上,这些 block 可以分散存放在 GPU 显存的不同位置,并通过 block table 完成逻辑块到物理块的映射。这样做的价值很直接:

  • 减少 KV Cache 显存碎片;
  • 支持不同长度请求混合调度;
  • 方便请求结束后回收 block;
  • 支持更大的 batch 和更高并发;
  • 在 beam search / parallel sampling 中更容易共享前缀缓存。

vLLM 的核心贡献就在这里:通过 PagedAttention,把 KV Cache 管理从“连续显存分配”变成“分页式块管理”。在论文实验中,这种方式显著降低了显存浪费,并带来了数倍级吞吐提升。

PagedAttention

Speculative Decoding:减少大模型解码步数

Decode 慢的根本原因是自回归串行生成:大模型每一步通常只确认一个 token。Speculative Decoding,也叫投机解码,试图减少大模型的串行 decode 轮次。它的基本流程是:

  1. 用一个较小的 Draft Model 先快速生成多个候选 token;
  2. 用目标大模型 Target Model 一次性并行验证这些 token;
  3. 被接受的 token 直接输出;
  4. 如果某个 token 被拒绝,就从该位置回退并重新采样。

Speculative Decoding

它的优势是:如果 Draft Model 质量足够好,目标模型一次可以接受多个 token,生成速度会明显提升。但它也有代价:

  • Draft Model 质量:质量越好,接受率越高;
  • Draft Model 成本:草稿模型本身也要消耗算力;
  • 验证实现:需要额外调度和并行验证逻辑;
  • 任务类型:创造性强或分布不稳定的任务接受率可能下降。

所以,投机解码不是“免费加速”,而是用一个便宜模型和更复杂的系统,换取目标大模型更少的 decode 轮次。

量化与低精度推理:降低单位 token 成本

量化的目标很直接:用更低的数值精度存储或计算模型权重、激活和 KV Cache,从而降低显存占用、提升吞吐、降低成本。

方案 特点
FP16 / BF16 常见推理精度,稳定性好
FP8 显存和吞吐更优,对硬件、校准和算子支持要求更高
INT8 常见部署量化方案,质量损失通常可控
INT4 / GPTQ / AWQ 显存节省明显,适合成本敏感场景,但质量风险更高
KV Cache INT8 / INT4 直接降低长上下文和高并发的缓存压力

量化的本质是权衡:更低显存 + 更高吞吐 + 更低成本 VS 校准复杂度 + 数值误差 + 可能的质量损失。对推理服务来说,量化不仅是“模型变小”,更重要的是降低单位 token 成本。尤其在长上下文和高并发场景下,KV Cache 量化往往和权重量化一样关键。

小结

这一节的核心可以压缩成一句话:Batching 解决 GPU 利用率,PagedAttention 解决 KV Cache 管理,Speculative Decoding 解决 Decode 串行瓶颈,量化解决单位 token 成本。

主流推理框架

一个成熟的推理系统,本质上是在做四件事:

  1. 让 GPU 尽量满:通过 batching、调度和并行执行提高硬件利用率;
  2. 让 KV Cache 尽量省:通过分页管理、压缩、量化和复用降低显存压力;
  3. 让请求调度尽量稳:在不同长度、不同优先级、不同 SLA 的请求之间做资源分配;
  4. 让单位 token 成本尽量低:通过量化、低精度、多机并行和模型路由降低服务成本。

因此,推理框架不是简单的 HTTP server,而是把模型执行、KV Cache 管理、batch 调度、解码策略、量化、多卡并行和资源隔离组织成一个在线系统。不同框架的设计哲学不同,适合的场景也不同。

框架 核心取向 关键技术 优势 适合场景
vLLM 用高效 KV Cache 管理换高吞吐 PagedAttention、Continuous Batching 吞吐高,社区活跃,易用性好,支持 NVIDIA / AMD 等多种硬件 高并发、吞吐敏感的在线服务
TensorRT-LLM 榨干 NVIDIA GPU 性能 TensorRT 编译、kernel fusion、FP8 / INT4、in-flight batching NVIDIA 硬件上性能极强,和 Triton / CUDA 生态结合紧密 NVIDIA 技术栈下的极致性能部署
Hugging Face TGI Hugging Face 生态早期重要 serving 框架 Continuous Batching、Tensor Parallel、Rust 服务核心 和 HF Hub / Transformers 生态集成好,但当前已进入维护模式 快速上线、标准模型服务、HF 生态用户
SGLang 面向复杂生成工作流的 runtime RadixAttention、结构化生成、并发调度 适合多轮、多分支、工具调用和复杂 prompt workflow Agent、结构化输出、复杂 serving workflow
llama.cpp 本地/边缘/低成本推理 GGUF、CPU/GPU 混合、INT4/INT8 量化 轻量、可本地运行,硬件门槛低 本地部署、边缘设备、个人推理服务

这些框架体现的是工程里的典型权衡:性能(Performance)、生产力(Productivity)和可移植性(Portability) 很难同时拉满。更准确地说,推理框架没有绝对最优,只有场景最优:如果目标是高并发在线吞吐,优先看 vLLM;如果目标是在 NVIDIA GPU 上追求极致性能,TensorRT-LLM 更合适;如果模型和部署链路都在 Hugging Face 生态里,TGI 上手最快;如果要做复杂 Agent runtime 或结构化生成,SGLang 更有优势;如果是本地、边缘或低成本部署,llama.cpp 是最轻量的选择。

行业演进:推理服务往哪里走?

推理服务正在从“把模型跑起来”,走向“把每个 token 的成本、延迟和稳定性做到极致”。早期部署一个模型,重点是能不能加载权重、能不能返回结果。现在的推理服务要面对更复杂的场景:长上下文、多轮对话、多工具调用、多模态输入、Agent 任务流,以及不断增长的并发和成本压力。

推理服务演进

趋势 核心变化
KV Cache 成为一等公民 长上下文和高并发让缓存管理成为系统核心
Prefill / Decode 分离 两个阶段资源特征不同,可能采用不同调度和硬件策略
投机解码常态化 用 draft model 或 draft head 换更低 decode 延迟
低精度深入部署 FP8、INT8、INT4、KV 量化会按场景分层使用
Agent Runtime 融合 模型不只生成文本,还要调用工具、维护状态、执行任务

未来推理服务比拼的,不再是单个模型“能不能跑起来”或“单次生成有多快”,而是整体系统效率:

  1. 同样 GPU,谁能服务更多 token;
  2. 同样延迟,谁能支持更长上下文;
  3. 同样成本,谁能提供更稳定的体验;
  4. 同样模型,谁能把调度、缓存和解码优化得更好。

所以,推理服务的本质不是部署一个模型 API,而是把模型权重、KV Cache、batch 调度、解码策略、量化、多机并行和线上 SLA 组织成一个稳定、可扩展、可控成本的在线系统。

放回整个 LLM 训练与服务链路中看:预训练和后训练决定模型能力,分布式训练决定模型如何被训练出来,而推理服务决定这些能力能否以可承受的成本、稳定地交付给真实用户