01 模型推理基础
学习目标:讲清楚一次 LLM 请求从 prompt 到输出 token 的完整过程,理解 MoE 模型"总参数大、激活参数小"的含义,建立 Prefill/Decode 资源需求相反的核心认知。 重点度:必会(10 分) 前置要求:Linux、Docker、基本 Python
概述#
在谈 vLLM、SGLang、推理网关之前,先要理解最根本的问题:一次 LLM 请求到底是怎么产生输出的?
不理解 prompt、token、prefill、decode、context length,就无法理解后面的 TTFT、TPOT、KV Cache、Continuous Batching。这一章是整个路线的基石,也是面试里"原理追问型"题目的高频考点。
2026 年还有一个不得不提的背景:前六大模型全是 MoE 架构,DeepSeek 系列带火的 MLA(Multi-head Latent Attention)让 KV Cache 压缩成为长上下文推理的标配。这意味着"模型推理基础"不再是"token + prefill + decode"三件套,还要把 MoE 的"总参数 vs 激活参数"、MLA 的"KV 压缩"纳入认知。
模型权重与推理的本质#
一个 LLM(大语言模型)本质上是一个巨大的神经网络。以 Qwen2.5-72B 为例,它有 720 亿个参数,每个参数在 FP16 精度下占 2 字节,总权重约 144 GB。这些参数存储在 checkpoint 文件(通常是 .safetensors 格式)中,构成了模型的"知识"。
推理(Inference)的本质:给定一段输入文本,模型通过一次前向传播(forward pass)计算出下一个最可能出现的 token,然后把这个 token 追加到输入中,重复这个过程直到输出结束。
输入 → [模型前向传播 → 输出1个token → 追加到输入] → 循环 → 输出完整回复权重精度与显存占用#
同一个模型可以用不同精度加载,显存占用差异巨大:
| 精度 | 每参数字节 | 72B 权重大小 | 适用硬件 |
|---|---|---|---|
| FP32 | 4 | 288 GB | 训练(推理基本不用) |
| FP16/BF16 | 2 | 144 GB | 通用(A100/H100) |
| FP8 | 1 | 72 GB | H100/H200 原生 |
| INT4 (AWQ/GPTQ) | 0.5 | 36 GB | Ampere+,单卡跑 70B |
BF16 vs FP16:BF16 牺牲精度(7 位尾数)换范围(8 位指数),训练稳定性更好,现代模型默认 BF16。推理场景 FP16 和 BF16 性能基本一致。
Prompt、Token 与 Tokenizer#
Prompt(提示词)#
Prompt 是用户送给模型的输入文本。可以是简单的一句话,也可以是多轮对话的完整历史。Chat 场景中,prompt 会被组织成结构化的 messages 格式:
system: 你是一个代码审查助手
user: 请帮我review这段Python代码
assistant: (模型将生成的回复)System Prompt 在生产中通常固定(定义角色、规则、工具),是 Prefix Cache 和 RadixAttention 命中的关键——system prompt 一变,整个 KV Cache 失效。
Token(词元)#
模型不直接理解文本字符,而是将文本分解为更小的单元——token。一个 token 可能是一个完整的词、一个子词、甚至一个单独的字符。中英文的 token 效率差异很大:
| 语言 | 示例 | token 数 | token/汉字比例 |
|---|---|---|---|
| 英文 | "Hello world" | 2 | — |
| 中文 | "你好世界" | 4 | ~2 token/字 |
| 代码 | def add(a, b): | 7 | — |
粗略估计:英文约 4 字符 = 1 token,中文约 1.5-2 字符 = 1 token。
Token 效率的工程影响:
- 同样 1 万字中文 prompt 比 1 万字英文 prompt 多消耗 2-3 倍 token
- 直接影响 TTFT(prefill 计算量更大)和成本(按 token 计费)
- 国内业务做成本估算时按中文 token 算,别套英文 benchmark
Tokenizer(分词器)#
Tokenizer 负责在文本和 token 之间转换:
- 编码(encode):
"你好"→[57668, 53974](token IDs) - 解码(decode):
[57668, 53974]→"你好"
常用的 tokenizer 算法:
| 算法 | 代表模型 | 特点 |
|---|---|---|
| BPE(Byte-Pair Encoding) | GPT 系列、Llama | 按频率合并字节对,子词粒度 |
| SentencePiece | LLaMA、Qwen | 直接处理原始文本,支持多语言 |
| WordPiece | BERT | 类似 BPE,按似然合并 |
不同模型的 tokenizer 不通用——DeepSeek 的 tokenizer 和 LLaMA 的 tokenizer 对同一段中文的分词结果可以差 30%。部署时 tokenizer 必须和权重严格匹配,否则生成的 token ID 对不上模型词表,输出乱码。
# 使用 HuggingFace tokenizer
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-72B-Instruct")
tokens = tokenizer.encode("什么是AI Infra?")
print(f"Token IDs: {tokens}") # [104130, 98715, 102863, ...]
print(f"Token数量: {len(tokens)}") # 7
print(tokenizer.decode(tokens)) # "什么是AI Infra?"Prefill 与 Decode:推理的两个阶段#
一次 LLM 推理请求分为两个阶段,它们是理解所有推理优化(TTFT、TPOT、KV Cache、PD 分离)的基础。
Prefill(预填充阶段)#
是什么:模型一次性处理输入 prompt 的所有 token,计算并缓存每一层的 Key 和 Value 矩阵(KV Cache),同时生成第一个输出 token。
特征:
- 计算密集型(compute-bound):需要同时处理所有输入 token 的矩阵乘法
- GPU 的 SM(流处理器)利用率高(80-95%)
- 延迟与输入长度成正比:1K token 的 prompt 比 100 token 慢 10 倍
Prompt: "请用中文写一首关于春天的五言绝句"(15个token)
Prefill阶段:
一次性将15个token送入模型
→ 计算所有层的 attention + FFN
→ 保存每一层的 Key/Value(KV Cache)
→ 生成第一个输出token: "春"Decode(解码阶段)#
是什么:从第二个 token 开始,每次只用上一个生成的 token 和之前缓存的 KV Cache 来计算下一个 token,自回归地逐个生成。
特征:
- 访存密集型(memory-bound):每次只算 1 个新 token 的 attention,大部分时间在读取 KV Cache
- GPU 利用率低(单 token 喂不饱 GPU,SM 利用率 20-40%)
- 输出 500 个 token 就需要 500 次前向传播
Decode阶段(逐token生成):
token "春" → 与KV Cache计算 → 生成 "风"
token "风" → 与KV Cache计算 → 生成 "拂"
token "拂" → 与KV Cache计算 → 生成 "面"
...继续直到生成 EOS(结束符)对比总结#
| 维度 | Prefill | Decode |
|---|---|---|
| 处理方式 | 并行处理所有输入 token | 串行逐个生成 |
| 计算特征 | Compute-bound | Memory-bound |
| GPU SM 利用率 | 高(80-95%) | 低(20-40%) |
| 每次处理的 token 数 | input_len | 1 |
| 瓶颈 | 算力(FLOPS) | 显存带宽(HBM) |
| 优化方向 | 加大 batch、FP8 计算、Chunked Prefill | KV Cache 压缩、CUDA Graph、增大 batch |
Prefill 和 Decode 的资源需求截然相反——这是 PD 分离(Prefill/Decode Disaggregation)的核心驱动力。Prefill 要算力(GPU FLOPS),Decode 要带宽(HBM 带宽),两者放在同一张 GPU 上会互相干扰:Prefill 的算力突发抢走 Decode 的显存带宽,Decode 的低 GPU 利用率拖累 Prefill 的效率。
Context Length(上下文长度)#
Context Length 指模型一次能处理的 token 总数上限(输入 + 输出),是推理服务的关键参数。
| 模型 | 最大 Context Length | 备注 |
|---|---|---|
| DeepSeek-V4 | 1M tokens | 2026 旗舰 |
| Llama 4 Scout | 10M tokens | 开源最长 |
| Claude Opus 4.8 | 1M tokens | 闭源 |
| GPT-5.5 | 256K tokens | — |
| Qwen3.6-MoE | 128K tokens | — |
对推理服务的影响:
- 更大的 context length 需要预留更多 KV Cache 显存
- 设得过大会减少并发容量(vLLM 中
max-model-len设 128K 时可能只能同时服务 3-4 个请求) - 建议按业务实际需求设置,99% 的业务 8K-32K 就够
Context Length 与 KV Cache 的关系:KV Cache 的最大显存占用 ≈ max_model_len × 每 token KV 大小 × 并发请求数。把 max_model_len 从 8K 调到 128K,同样的显存能服务的并发数直接掉到 1/16。这是"max-model-len 是最大的隐式性能杀手"的根本原因。
Streaming(流式输出)#
Streaming 不是推理加速技术,而是用户体验优化。非流式模式下,用户要等所有 token 生成完毕才能看到完整回复。流式模式下,每生成一个 token 就立即返回给客户端:
from openai import OpenAI
client = OpenAI(base_url="http://vllm:8000/v1", api_key="EMPTY")
stream = client.chat.completions.create(
model="qwen2.5-72b",
messages=[{"role": "user", "content": "写一首诗"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)实现原理:底层推理引擎在 decode 的每一步产生 token 后立刻通过 HTTP SSE(Server-Sent Events)或 gRPC 流推送给客户端。这在 OpenAI-Compatible API 中是标准能力。
生产注意:
- 中间代理(Nginx/Ingress)要关闭 buffering,否则流会被攒成块再发
proxy_read_timeout要足够长(输出 500 token 可能要 30s+)- 客户端要正确处理 SSE 重连,否则连接断开后用户看不到完整回复
Checkpoint 与 Model Artifact#
Checkpoint#
Checkpoint 是保存模型权重和配置的文件集合,通常包含:
Qwen2.5-72B-Instruct/
├── config.json # 模型架构配置
├── tokenizer.json # 分词器
├── tokenizer_config.json
├── model-00001-of-00003.safetensors # 权重分片1
├── model-00002-of-00003.safetensors # 权重分片2
├── model-00003-of-00003.safetensors # 权重分片3
└── generation_config.json- safetensors:替代 pytorch .bin,更安全(不含可执行代码,防止反序列化攻击),加载更快(支持零拷贝 mmap)
- 分片:72B FP16 约 144 GB,通常切成多个文件便于下载和加载
- config.json:定义层数、hidden_size、num_heads、vocab_size 等架构参数
Model Artifact#
在 MLOps 语境中,Model Artifact 是一个更广义的概念,包括:
- 模型的完整权重文件(safetensors)
- tokenizer 文件
- 量化配置(如 AWQ 的
quantize_config.json) - LoRA adapter 文件(如有)
- 推理引擎编译产物(如 TRT-LLM 的
.engine文件)
在 Model Registry 中,一个"模型版本"的 Artifact 是上述全部文件的集合,而不是单个权重文件。
模型类别:Chat / Embedding / Rerank / 多模态#
Chat Model(对话模型)#
最常见的 LLM,接收自然语言输入,生成自然语言输出。如 GPT-5.5、Claude Sonnet、Qwen3。
输入: "1+1等于几?"
输出: "1+1等于2。"Chat 模型的推理是 compute-bound(prefill)+ memory-bound(decode)的混合负载,是本路线主要讨论的对象。
Embedding Model(向量化模型)#
将文本转化为固定维度的向量,用于语义搜索、聚类、分类。
# BGE-M3 生成 1024 维向量
text = "AI Infra是AI时代的基础设施"
embedding = model.encode(text) # shape: [1024,]特点:输出不是文本而是数值向量,推理通常在 CPU 或小 GPU 上完成,对延迟要求高(RAG 检索链路的前置步骤)。Embedding 模型的推理优化思路与 Chat 模型不同——它只有 prefill 没有 decode,重点是 batch 处理和向量索引。
Rerank Model(重排序模型)#
对检索召回的多篇文档进行精排序。输入是一对 (query, document),输出是相关性分数。
pairs = [[query, doc1], [query, doc2], [query, doc3]]
scores = reranker.predict(pairs) # [0.92, 0.45, 0.78]与 Embedding Model 的区别:Embedding 做粗排(速度快,精度低),Rerank 做精排(速度慢,精度高)。RAG 系统通常 Embedding 召回 Top-50 → Rerank 精排 Top-5。
多模态模型#
可同时处理文本、图像、音频等多种输入。2026 年闭源旗舰(GPT-5.5、Claude Sonnet 5)均已支持图像等多模态输入。
输入: 一张图片 + "请描述这张图片"
输出: "图片中是一只趴在沙发上的橘猫..."对推理基础设施的挑战:
- 图像 token 通常是文本 token 的数十倍(一张图 ≈ 1K-4K token)
- KV Cache 占用更大,并发容量显著下降
- 多模态模型通常需要 vision encoder + LLM 两段推理,延迟更高
MoE 模型:总参数 vs 激活参数#
什么是 MoE#
MoE(Mixture of Experts,混合专家)是 2026 年主流大模型的架构范式。前六大模型全是 MoE,Dense 旗舰已经绝迹。
核心思想:模型中包含多个"专家"子网络,每次推理只激活其中的一部分。
以 DeepSeek-V4 为例:
- 总参数:1.6T(1.6 万亿)
- 激活参数:49B(490 亿,约占总参数 3%)
- 含义:模型有 1.6T 的"知识容量",但每次前向传播只用到其中 49B 参数
MoE 一次推理的路径:
Input → Router(决定用哪些 Expert)
→ Expert_3(激活)
→ Expert_7(激活)
→ ...(其余 expert 不计算)
→ Output
对比 Dense 模型:所有参数每次都要计算MoE 的关键组件#
1. Router(路由器):一个小型线性层,对每个 token 输出一个专家分配概率
2. Expert(专家):通常是 FFN 层,每个 expert 独立处理被路由到它的 token
3. Top-K 选择:每个 token 只激活 K 个专家(如 K=2 或 K=8)
4. Shared Expert(共享专家):DeepSeek 引入,部分 expert 对所有 token 都激活,
保证基础计算能力,减少路由抖动为什么 MoE 是主流#
| 维度 | Dense 模型 | MoE 模型 |
|---|---|---|
| 模型能力 | 受限于单次计算参数 | 总参数可以很大(知识容量大) |
| 推理速度 | 所有参数都参与 | 只算激活部分,更快 |
| 显存需求 | 需加载全部权重 | 需加载全部权重(但计算量小) |
| 部署挑战 | 相对简单 | 专家路由不均衡、EPLB、EP 并行 |
关键认知:MoE 的显存需求并不比同量级 Dense 模型小(所有 expert 权重都要加载),但推理计算量大幅降低。这意味着 MoE 推理对显存的要求仍然高,但 GPU 算力的要求相对较低。
显存计算示例:
DeepSeek-V4-Pro (1.6T 总参数, FP8):
权重显存 = 1.6T × 1 byte = 1.6 TB
20 张 H100-80G(80GB/卡 × 20 = 1.6TB)刚好装下权重,
还要给 KV Cache/激活留空间 → 实际需 24 张以上或多机
但每次推理只激活 49B 参数:
单 token 计算量 ≈ 49B × 2 = 98 GFLOP
比同等总参数量的 Dense 模型快约 32 倍MoE 推理的特殊挑战:专家路由不均衡#
MoE 模型的 expert 路由是不均衡的。DeepSeek-V2/V3 的生产数据显示,某些热门 expert 的负载是冷门 expert 的 10-20 倍。
问题表现:
Expert 3 所在 GPU: 显存 95%,QPS 到上限
Expert 7 所在 GPU: 显存 25%,GPU 几乎空闲
→ 整体集群吞吐被热门 expert 所在 GPU 卡死解决方案是 EPLB(Expert Parallelism Load Balancer),DeepSeek 开源,通过动态调整 expert 到 GPU 的映射实现负载均衡。详见第 3 章。
MLA:Multi-head Latent Attention(KV 压缩)#
MLA 是 DeepSeek-V2/V3 带火的核心技术,核心是大幅压缩 KV Cache 的显存占用(V4 已进一步升级为 CSA/HCA 稀疏压缩注意力,见下文)。
Attention 演进:MHA → GQA/MQA → MLA#
| Attention 类型 | KV Cache 大小 | 代表模型 | 思路 |
|---|---|---|---|
| MHA(Multi-Head Attention) | 最大 | LLaMA 2、GPT | 每个 head 独立 K/V |
| GQA(Grouped Query Attention) | 中等(1/4~1/8) | LLaMA 3、Qwen3 | 多个 Q head 共享一组 K/V |
| MQA(Multi-Query Attention) | 最小(1/num_heads) | PaLM、StarCoder | 所有 Q head 共享一组 K/V |
| MLA(Multi-head Latent Attention) | 极小(1/8~1/16)+ 质量保留 | DeepSeek-V2/V3 | 低秩压缩,缓存 latent vector |
KV Cache 膨胀问题#
以 LLaMA 3.1 70B 为例(注意它用的是 GQA,只有 8 个 KV head,并非每个 head 独立存 K/V 的传统 MHA):
KV Cache 每 token = 2 × 80层 × 8个KV头 × 128维 × FP16(2字节) ≈ 320KB/token
10万token的KV Cache ≈ 32GB如果换成传统 MHA(64 个 attention head 各自独立存 K/V),同规模模型的 KV Cache 会是上面的 8 倍(约 2.5MB/token)——这也是"别把 GQA 数字当 MHA"的典型陷阱。长上下文场景下,KV Cache 成为显存的主要消耗者。
MLA 的压缩思路#
MLA 通过在 K 和 V 的计算中插入低秩瓶颈(latent space),使实际需要缓存的 KV 维度大幅降低。DeepSeek-V3 的 MLA 将 KV 压缩到约传统 MHA 的 1/8~1/16。
传统 MHA: Hidden → Q, K, V(全部缓存)
MLA: Hidden → Q, K_latent → K(只缓存 K_latent,极小)
Hidden → V_latent → V(只缓存 V_latent,极小)与 GQA/MQA 的区别:GQA/MQA 通过减少 KV head 数量来压缩,但会损失精度(Q head 共享 K/V 后表达能力下降)。MLA 通过低秩投影压缩,decode 时从 latent vector 恢复完整 K/V,质量接近 MHA。
对推理的影响:
- 同样显存能服务更多并发请求
- 长上下文场景收益最大(128K 上下文下 MLA 省出的显存可以多服务 3-5 个请求)
- DeepSeek-V2/V3 的长上下文能力主要靠 MLA;到 DeepSeek-V4 则进一步用 CSA/HCA(沿序列维度压缩 + 稀疏注意力)把 1M 上下文的 KV Cache 压到 V3.2 的约 10%——否则 1M 上下文的 KV Cache 会消耗数百 GB 显存
推理请求的资源消耗模型#
把以上知识串起来,一个推理请求的资源消耗可以量化:
显存 = 模型权重(固定) + KV Cache(随 context 长度和并发增长) + 激活值(临时)
算力(FLOPS)=
Prefill: 2 × 参数量 × input_tokens(MoE 用激活参数算)
Decode: 2 × 参数量 × 1(每步一个 token,重复 N 次)
延迟 =
TTFT ≈ Prefill 计算时间 + 排队时间
总延迟 = TTFT + output_tokens × TPOT资源消耗的工程意义:
- 权重是固定开销,加载一次常驻显存
- KV Cache 是变动开销,随并发和上下文长度增长
- 长上下文场景下,KV Cache 显存 > 权重显存是常态
- 这就是为什么 KV Cache 优化(MLA、FP8 KV、分级 KV)是降本核心
一次完整的 LLM 推理请求(全链路)#
把以上知识串起来,看一次完整的 ChatGPT 风格对话请求:
步骤 1: 用户输入 prompt
"请用中文解释什么是KV Cache"
步骤 2: Tokenizer 编码
prompt → [104130, 98715, 102863, 100860, 3837, 419, 342, 374, 3201, 8656, 28]
(约11个 token,含开始符)
步骤 3: Prefill 阶段
11个 token 一次性送入模型
→ 所有层计算 attention + FFN(如果模型有80层)
→ 每层保存 KV Cache(MLA 下被压缩)
→ 生成第1个 token: "KV"
步骤 4: Decode 阶段(串行,逐token生成)
"KV" + KV Cache → "Cache"
"Cache" + KV Cache → "是"
"是" + KV Cache → "一种"
...(重复直到生成 EOS 或达到 max_tokens)
步骤 5: Tokenizer 解码
token IDs → 完整中文回复文本
步骤 6: 流式输出(如果 streaming=True)
步骤4的每个token生成后立即推送客户端性能指标对应:
- TTFT(Time To First Token):步骤 3 的耗时(用户感知的"首token延迟")
- TPOT(Time Per Output Token):步骤 4 中每个 token 的平均耗时
- 总延迟 = TTFT + 输出token数 × TPOT
实战要点#
Tokenizer 必须和模型匹配:vLLM 部署时如果 tokenizer 路径错误,会导致生成的 token ID 对不上,输出乱码。生产环境确保模型目录下的
tokenizer.json和tokenizer_config.json与权重一致。换模型版本时连 tokenizer 一起换,不要复用。Context Length 按需设置:不要图大设到模型上限。大部分业务 8K-32K 就够,设小了让 KV Cache 池子变大,并发数提升。vLLM 的
--max-model-len是控制这一点的关键参数。设到 128K 但业务只用 8K,等于把 15/16 的 KV Cache 池子浪费掉。MoE 的显存计算与 Dense 不同:MoE 模型的全部 expert 权重都要常驻显存(DeepSeek-V4 约 1.6T × 1 字节 FP8 ≈ 1.6TB),但每 token 只激活 49B 参数、单 token 计算量约 98 GFLOP。部署时必须把全部权重装进显存,但推理速度快于同等总参数量的 Dense 模型。
理解 Prefill 和 Decode 的差异是一切优化的起点:Prefill 需要算力、Decode 需要显存带宽。后面要讲的 Continuous Batching、Chunked Prefill、PD 分离都是利用这两个阶段的不同特征做优化。面试时"为什么 TTFT 高不一定 TPOT 高"考的就是这个认知。
MLA 不是每个模型都有:它是 DeepSeek 系列的核心特性。部署 LLaMA、Qwen 等传统 MHA/GQA 架构的模型时,KV Cache 消耗更大,需要预留更多显存。GQA 已经是现代 Dense 模型的标配,但压缩比不如 MLA。
System Prompt 稳定性影响所有缓存优化:Prefix Cache、RadixAttention、分级 KV 都依赖前缀稳定。如果 system prompt 里塞了时间戳、随机 ID 等动态字段,所有缓存命中率归零。把动态内容移到 user message 里。
BF16 是推理默认精度,FP8 是 2026 高并发基线:H100/H200 上 FP8(权重+激活+KV Cache)是无脑选择。A100 上用 AWQ INT4 或 SmoothQuant INT8。
小结#
这一章覆盖了一个 LLM 推理请求的完整生命周期:
prompt → tokenizer → prefill(计算KV Cache,出首token)→ decode(逐token自回归生成)→ detokenizer → 输出文本核心认知:
- Prefill 是 compute-bound(算力瓶颈),Decode 是 memory-bound(显存带宽瓶颈)——这个差异是整个推理优化领域的基础
- MoE 让模型能力(总参数)和推理成本(激活参数)解耦,是 2026 年的主流架构,但带来专家路由不均衡新挑战
- MLA 通过低秩压缩解决了长上下文推理的显存瓶颈,是 DeepSeek 系列的标志性技术
- Context Length 设多大直接影响并发能力,max-model-len 是最大的隐式性能杀手
- KV Cache 是推理显存的第一消耗者,所有降本优化(MLA、FP8 KV、分级 KV、PD 分离)都围绕它展开
下一章将进入 推理服务化——如何把模型变成一个可被业务调用的标准 API 服务,以及如何用多卡分布式部署单卡放不下的大模型。