⚡ LLM 推理管线基于 hammadabbasi.com/under-the-hood/inference

LLM 推理管线
一次请求从进门到吐字的全过程

把 10 大主题浓缩成一条主线:请求进来 → 组装上下文 → 预填充 → 逐字解码 → 流式返回。所有性能优化的本质,都是在攻这条链上的瓶颈。

① 请求生命周期

01一次 API 调用经过的流水线

确定性管线,每一步都有耗时。模型那步(预填充+解码)占绝大多数墙钟时间。原文用餐厅后厨类比:服务员下单=网关,领位查预订=鉴权,后厨备料=上下文+分词,主厨做菜=预填充+解码,一道道上菜=流式输出。

浏览器 API 网关
~2ms
鉴权
~5ms
上下文组装
~10ms
分词
~1ms
模型预填充+解码
~200–2000ms
反分词
~0.5ms
流式返回客户端
② 上下文组装

02把所有素材塞进 token 预算

服务层在 token 上限内拼接:系统提示 + 对话历史 + RAG 文档 + 用户消息。算笔账(32K 窗口示例):

组成token说明
系统提示500角色/规则
对话历史2,000之前几轮
RAG 文档4,000检索来的——通常最大头
用户消息200本轮输入
输出预留4,096给生成留空间
合计输入6,700 / 28,672在预算内

超了怎么办?三种截断:砍最旧 / 滑动窗口 / 摘要压缩。生产常见套路:先过量检索,再重排序 + 截断

③④ 两个阶段(核心)

03·04Prefill vs Decode:瓶颈完全不同

这是整篇最关键的一组对照。预填充是算力受限,解码是显存带宽受限——不同瓶颈决定不同优化方向。

🟢 Prefill 预填充compute-bound
  • 整个输入一次前向,所有 token 并行处理
  • 瓶颈在 GPU 张量核心(算力)
  • 计算并存储所有输入 token 的 KV-cache
  • 决定 TTFT(首 token 时间)≈ prefill + 调度开销
  • 随 prompt 长度近似线性增长
🟣 Decode 解码memory-bound
  • 预填充后一次一个 token自回归生成
  • 每个新 token 依赖前面所有 token
  • 瓶颈在显存带宽,不是算力
  • 每步:读全部权重 + 读 KV-cache + 一次矩阵向量乘 + 写一个 KV 项
  • 算术强度约 1 FLOP/byte(极低)

📊 Prefill 耗时随 prompt 长度(估算):128 token ≈ 2ms · 2K ≈ 37ms · 8K ≈ 147ms · 16K ≈ 295ms。重复前缀可用 prompt 缓存省掉冗余预填充。

为什么 Decode 慢?

70B FP16 模型权重约 140GB,每次解码都要把这 140GB 从 HBM 读一遍——但只算一次矩阵向量乘。算得少、搬得多,所以卡在"搬运速度"(带宽)而非"计算速度"。单卡 H100(3.35TB/s)理论上限约 24 token/s批处理能把"读权重"的成本摊给多个请求。

⑤ KV-Cache

05KV-Cache:把复杂度从 O(n²) 降到 O(n)

缓存预计算的 Key/Value 张量,避免每个解码步重算。没有它生成是 O(n²)/token,有它 O(n)/token

序列长度 4096 时的注意力操作数: 16.8M 无缓存 · O(n²) 每次解码都重算所有 4,096 有缓存 · O(n) 只算新 token 的 ↓ 4096×
KV-cache 把每 token 复杂度从 O(n²) 降到 O(n)。但缓存本身吃显存——Llama3 70B @ FP16、序列 4096 时约占 1.25GB

PagedAttention(vLLM):像虚拟内存一样管理 KV-cache——按需分配固定大小页,而非预留连续大块。消除碎片,批大小提升 2–4×。KV-cache 显存往往是批大小的真正约束:70B + 128K 上下文 @ FP16,单请求 KV-cache 就 ~10GB

⑥ 采样

06从 logits 到下一个 token

模型对词表每个 token 输出原始 logits,采样策略把它转成概率分布。原文用灌铅骰子类比:temperature 控制骰子多偏,top-p 去掉最稀有的面,top-k 只留最重的 k 个面。

参数作用建议
Temperature控制随机性。低=确定,高=创意
Top-K只保留概率最高的 K 个
Top-P(核采样)保留到累计概率 ≥ P 为止创意 0.9
Min-P丢掉低于阈值的
Repetition Penalty重复惩罚

例:"法国的首都是" → Paris 85.6%、Lyon 3.9%… 事实类任务用 temperature 0–0.3 + 不开 top-p;创意写作用 0.8–1.2 + top-p 0.9。

⑦ 连续批处理

07最有性价比的优化:~3× 吞吐

静态批处理逼所有请求等最慢那个;连续批处理(iteration 级调度)让请求在每个解码步动态进出。原文称这是单项最有效的服务优化——2–4× 吞吐且无单请求延迟损失。

静态批处理:R1 早做完也得等 R2 R1 (10步) R2 (50步) R3 (30步) ≈ 15 req/s 连续批处理:R1 走了 R4 立刻补位 R1 R2 R3 R4 补位 ← ≈ 45 req/s (~3×)
vLLM / TensorRT-LLM / SGLang 都实现了它。原文比作空中交通管制员——飞机随时起落,塔台动态调度。
⑧ 投机解码

08小模型猜,大模型验:2–3× 加速

小而快的草稿模型先生成候选 token,大目标模型一次前向验证全部候选。猜对时,一次验证换回多个 token。数学上无损——输出分布与单独跑大模型完全一致。

  • 验证便宜:验证 N 个 token 的成本 ≈ 生成 1 个(大模型并行处理 N 个,像 prefill)
  • 何时有效:草稿与目标模型一致性高时(样板代码、套话、重复模式)
  • 70% 接受率 → 有效加速约 3.8×(每次验证出 3.8 个 token)
  • <50% 接受率 → 开销超过收益,得不偿失

原文比作快速结账通道——先快速扫一遍,再集中核对。

⑨ GPU 架构

09H100 与张量并行

NVIDIA H100 SXM 规格:80GB HBM3 · 3.35 TB/s 带宽 · 989 TFLOPS FP16 张量核心 · 1979 TFLOPS FP8 · 900 GB/s NVLink。

  • 70B FP16 = 140GB,单卡装不下(超 80GB)→ 张量并行把权重矩阵切到多卡
  • 每层后要 all-reduce,靠 NVLink 900GB/s 才可行
  • 但扩展次线性:8 卡约只有单卡的 5–6×(通信开销吃掉一部分)
⑩ 可观测性

10生产指标:TTFT P95 是命脉

模拟仪表盘:TTFT P50 180ms · token/s 52 · 延迟 P50 45ms / P95 210ms · GPU 利用率 82% · 队列深度 12。

SLA 项目标
TTFT P95< 300ms
TPS P50> 40 tok/s
错误率< 0.1%
GPU 显存< 90%
队列深度< 25
TTFT P95 是最重要的生产指标

它一飙,按顺序查:① 队列深度 ② prompt 长度 ③ KV-cache 驱逐。自动扩容示例:50 req/s 需 2× H100(每卡约 45 req/s)。

一句话串起全部

请求进来 → 组装上下文塞进预算 → Prefill 算力受限决定首字延迟 → Decode 带宽受限逐字生成 → KV-Cache降复杂度 + PagedAttention省显存 → 连续批处理摊成本提吞吐 → 投机解码无损加速 → 张量并行装下大模型 → TTFT P95盯生产命脉。

中文精简讲解,基于 hammadabbasi.com/under-the-hood/inference 的要点重构(非逐字翻译,原文 CC BY-NC-ND 4.0 禁止演绎)。数字与结构均来自原文。· 2026-07-30