推理与解码
两个阶段:Prefill 与 Decode
LLM 推理的性能特征完全不同的两个阶段,是理解一切推理优化的前提:
| 阶段 | 做什么 | 瓶颈 | 指标 |
|---|---|---|---|
| Prefill(预填充) | 并行处理整个 prompt,算出所有位置的 KV | 计算密集(compute-bound),GPU 算力打满 | TTFT(首 token 延迟) |
| Decode(解码) | 逐个生成 token,每步只处理 1 个 | 显存带宽密集(memory-bound),要把全部权重从 HBM 读一遍才算 1 个 token | TPOT(每 token 延迟) |
关键结论:decode 阶段 GPU 算力大量空闲,瓶颈在把模型权重搬进计算单元。所以提升吞吐的手段是增大 batch —— 一次读入的权重服务更多请求,算力利用率上升而延迟几乎不变。这是 continuous batching 的理论基础。
采样参数
greedy(贪心) —— 每步取概率最大的 token。确定性输出,但容易陷入重复循环(「的的的的」),且文本呆板。
temperature —— 在 softmax 前除以 T:softmax(logits / T)
T → 0退化为贪心T = 1原始分布T > 1分布变平坦,低概率 token 机会增加,更有创造性也更容易胡说- 代码生成、信息抽取用 0~0.3;创意写作用 0.8~1.0
top-k —— 只在概率最高的 k 个 token 里采样。缺点是 k 固定:当分布很尖锐时(下一个词几乎确定)k 太大会引入噪声;分布很平坦时 k 太小会限制多样性。
top-p(核采样,nucleus sampling) —— 按概率降序累加,取累积概率刚超过 p 的最小集合。候选数量随分布自适应,所以通常比 top-k 更好,是现在的默认选择(典型值 0.9~0.95)。
repetition / frequency / presence penalty —— 对已出现的 token 降低 logits,抑制重复。注意用力过猛会导致模型无法正常使用必需的高频词。
:::warning 为什么 LLM 不用 beam search 机器翻译、摘要等任务上 beam search 效果很好,但开放式生成上反而更差,原因:
- 它优化的是整句的联合概率最高 —— 而人类写的自然文本恰恰不是高概率路径。研究显示人类文本的 token 概率是高低起伏的,而 beam search 产出的高概率序列读起来平淡、重复、空洞(「这是一个很好的问题。这是一个很好的问题。」)
- 退化与重复 —— 最大化概率会偏好安全、通用、反复出现的表达
- 工程代价 —— beam 宽度为 k 就要维护 k 份 KV Cache,显存和计算都翻 k 倍,且难以流式输出
所以开放式生成用带约束的随机采样(temperature + top-p),而不是搜索最优路径。 :::
推理优化手段
KV Cache —— 见Transformer 与注意力。核心是用显存换计算。
PagedAttention / vLLM —— 传统实现为每个请求预分配「最大长度」的连续显存,实际用不满,浪费率可达 60~80%。PagedAttention 借用操作系统的虚拟内存分页思想:KV Cache 切成固定大小的块(block),用页表映射,物理上可以不连续。于是:
- 显存碎片几乎消除,有效 batch size 大幅提升
- 前缀共享 —— 多个请求共享相同的 system prompt 时,对应的 KV 块只存一份(copy-on-write)
Continuous Batching(连续批处理) —— 传统静态批处理要等整批里最慢的请求生成完才能换下一批,短请求被长请求拖着。连续批处理在每一步迭代后检查,完成的请求立即退出、新请求立即插入。吞吐提升可达数倍。
Speculative Decoding(投机解码) —— 用一个小的草稿模型(draft model)快速生成 k 个候选 token,再用大模型一次前向并行验证这 k 个。接受的部分直接采用,第一个被拒的位置用大模型的输出替换。
为什么能加速:decode 是 memory-bound,大模型验证 5 个 token 和验证 1 个 token 的耗时几乎一样(都要读一遍权重)。输出分布与原模型严格一致(靠拒绝采样保证),这是它优于其他近似加速方法的关键。变体有 Medusa(加多个预测头)、Lookahead Decoding、EAGLE。
Prefix Caching —— 把常用前缀(system prompt、few-shot 示例、长文档)的 KV Cache 持久化复用,直接削掉 prefill 耗时。对「同一份文档多轮问答」场景效果极其明显。
量化 —— 见微调与量化。
关键性能指标
| 指标 | 含义 | 影响 |
|---|---|---|
| TTFT | Time To First Token | 用户感知的「响应快不快」,由 prefill 决定 |
| TPOT / ITL | 每个输出 token 的时间 | 感知的「打字速度」,由 decode 决定 |
| 吞吐 Throughput | 总 token/s | 成本效率,由 batch 和显存决定 |
延迟与吞吐是矛盾的 —— 增大 batch 提升吞吐但拉长单请求延迟。面向用户的在线服务优先 TTFT,离线批量任务优先吞吐。
幻觉与上下文
幻觉的根本原因:训练目标是「预测最可能的下一个 token」,而不是「说真话」。模型没有「我不知道」这个概念的内在表征,遇到不确定的事实时会流畅地编造一个统计上合理的答案。
缓解手段按有效性排序:
- RAG —— 把事实外置,让模型基于给定材料回答(见 RAG 与 Agent)
- 要求引用来源 —— 并在后处理中校验引用是否真实存在
- 降低 temperature —— 对事实性任务用接近 0 的温度
- 自我一致性(self-consistency) —— 采样多次,取多数答案;分歧大说明模型不确定
- 明确授权拒答 —— prompt 里写「如果材料中没有答案就回答不知道」,SFT 阶段也要训练这个行为
Lost in the Middle —— 长上下文里中间位置的信息最容易被忽略,模型对开头和结尾的内容记得更牢(U 形曲线)。工程含义:RAG 检索结果要把最相关的放在最前或最后,不要堆在中间。这也是「长上下文不能完全替代 RAG」的实证依据之一。