图解LLM推理是如何工作的

admin 2026-07-02 06:00:59 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细解析了大语言模型推理的两个核心阶段:prefill(计算受限)和decode(内存受限)。prefill阶段并行处理所有输入token生成首个输出token并填充KV缓存,decode阶段逐个生成token依赖KV缓存导致内存带宽瓶颈。文章还介绍了KV缓存优化、量化技术及服务基础设施(连续批处理、推测解码等)对提升推理效率的关键作用。 综合评分: 85 文章分类: AI安全,技术标准,解决方案


cover_image

图解LLM 推理是如何工作的

ThinkInAI ThinkInAI

ThinkInAI社区

2026年6月28日 23:07 上海

在小说阅读器读本章

去阅读

原文:https://x.com/_avichawla/status/2071201619530956863

每次对 LLM 调用 generate(),都会在同一块 GPU 上运行两个截然不同的计算阶段:

  • prefill(处理提示词)是计算受限的
  • 而 decode(逐个生成 token)是内存受限的。

大多数推理优化都针对其中某一个阶段,而判断哪个阶段是瓶颈,是让部署变得更快的第一步。

在这篇文章中,我会带你走完整条流水线:从分词后的输入到流式输出,并看看每个阶段的时间都花在了哪里。

分词与嵌入

像字节对编码(Byte Pair Encoding,BPE)这样的分词器,会把原始文本转换成来自一个大约包含 50,000 个 token 的词表中的整数 ID。

prompt = "How does inference work?"ids = tokenizer.encode(prompt)# ids -> [2437, 1374, 32278, 670, 30]

每个 ID 都映射到嵌入表中的一行。嵌入表是一个形状为 [vocab_size, hidden_dim] 的可学习矩阵。对于隐藏维度为 4,096 的模型,每个 token 会变成一个 4,096 维向量。

# embedding_table has shape [vocab_size, hidden_dim]vectors = embedding_table[ids]   # shape: [num_tokens, 4096]

位置信息会在这一阶段被注入。

大多数现代架构使用旋转位置嵌入(Rotary Position Embeddings,RoPE),它不是额外添加一个位置向量,而是通过旋转嵌入向量来编码位置。

Transformer 层

嵌入后的序列会通过一叠 Transformer 层(通常是 32 到 80+ 层,取决于模型大小)。

每一层按顺序执行两个操作:

1)自注意力 通过可学习的权重矩阵,为每个 token 计算三个投影(query Q、key K、value V)。

每个 token 的 query 会与其他所有 token 的 key 进行打分,这些分数(经过缩放和 softmax 后)决定了每个 token 的 value 会以多大比例被混合进来。

# scores: how much each token attends to every other tokenQ, K, V  = x @ Wq, x @ Wk, x @ Wvscores = (Q @ K.T) / sqrt (d_k)weights = softmax(scaled) # one row per token, sums to 1attn_output  = weights @ V
  • 前馈网络(FFN)

    通过一个两层 MLP 独立处理每个 token 的向量。注意力在不同位置之间传递信息,FFN 则对这些信息进行变换。

最后一层之后,模型会把最后一个 token 的隐藏状态投影回词表大小([hidden_dim, vocab_size]),应用 softmax,然后从得到的分布中采样,生成第一个输出 token。

Prefill:计算受限阶段

处理输入提示词是第一个阶段。所有 token 会被并行处理:每个 token 的 Q、K、V 会同时计算,注意力则作为一次大规模矩阵-矩阵乘法运行。

这是计算受限的工作。GPU 的算术吞吐量是瓶颈,利用率很高。衡量这一阶段的指标是首 token 时间(Time to First Token,TTFT),也就是第一个输出 token 出现之前的延迟。

在 prefill 期间,模型还会填充 KV 缓存:每一层的 K 和 V 张量都会被存储在 GPU 内存中,以便复用。

# Prefill: process the whole prompt in one shothidden = embed(prompt_tokens) + positionsfor layer in model.layers:    Q, K, V = project(hidden)             # for ALL tokens at once    hidden  = attention(Q, K, V) + hidden    hidden  = feedforward(hidden) + hidden    cache_kv(layer, K, V)                 # save for laterfirst_token = sample(project_to_vocab(hidden[-1]))

Decode:内存受限阶段

一旦生成了第一个 token,模型就会切换到一次生成一个 token。对于每个新 token,它只会为这一个 token 计算 Q、K、V。所有之前 token 的 K 和 V 已经在缓存中了。

# Decode: one token per iterationtoken = first_tokensteps =&nbsp;0while token != STOP and steps < MAX_STEPS:&nbsp; &nbsp; x =&nbsp;embed(token) +&nbsp;position(steps)&nbsp; &nbsp; for layer in model.layers:&nbsp; &nbsp; &nbsp; &nbsp; q, k, v =&nbsp;project(x)&nbsp; &nbsp; &nbsp; &nbsp; K_all, V_all = caches[layer].append(k, v) # cached history + new&nbsp; &nbsp; &nbsp; &nbsp; x = layer.forward(q, K_all, V_all, x) &nbsp;# attention + FFN, residuals&nbsp; &nbsp; token =&nbsp;sample(project_to_vocab(x))&nbsp; &nbsp; steps +=&nbsp;1&nbsp; &nbsp; yield token

每一步的算术量非常小(是一个 query 向量与缓存中的 key 矩阵相乘,而不是完整的矩阵-矩阵乘法)。但 GPU 仍然需要为这次很小的计算从内存中加载每个权重矩阵以及整个缓存的 K/V。瓶颈从计算转变成了内存带宽。

衡量这一阶段的指标是 token 间延迟(Inter-Token Latency,ITL):连续输出 token 之间的时间。低 ITL 会让模型感觉响应更快。

KV 缓存

如果没有缓存,生成一个 1,000 token 的回答,就需要在每一步都对不断增长的完整序列重新计算注意力,复杂度会变成二次方。

KV 缓存会把每一层的 K 和 V 张量存储一次,并随着新 token 逐步追加新的条目。

下面的视频展示了有无 KV 缓存时的 LLM 推理速度对比:

对于长生成任务,加速大约是 5 倍或更多。

代价是缓存会随着序列长度线性增长,并且是逐层存在的。对于一个 13B 参数模型,缓存大约每个 token 消耗 1 MB。一个 4K token 的上下文,仅缓存就会消耗 4 GB 显存。

这就是长上下文变得昂贵的原因。缓存会直接与批大小竞争 GPU 内存,也就是说,每个请求占用的缓存越多,每块 GPU 上能并发处理的请求就越少。

标准缓解方法包括:将缓存量化到 INT8 或 INT4、滑动窗口注意力(丢弃固定窗口之外的 token)、分组查询注意力(GQA,在注意力头之间共享 K/V,以减少缓存张量数量),以及 PagedAttention(vLLM 背后的内存管理技巧,像操作系统分页虚拟内存一样对缓存进行分页,从而消除碎片)。

关于 KV 缓存管理,我还讨论过另一个有趣的想法:

嵌入推文 · Avi Chawla · @_avichawla · Jun 27

一个棘手的 LLM 面试题:

你正在 vLLM 上部署一个推理模型,它在长 trace 上不断耗尽 GPU 内存。

于是你加入了 KV 缓存压缩,并驱逐了 90% 的缓存 token。

显存使用量保持不变,GPU 仍然会内存耗尽。

为什么?

(答案见下方) 查看原文

围绕缓存重新设计注意力

量化和分页把 KV 缓存视为一个需要管理的固定成本。DeepSeek 的 V4 系列(2025 年 4 月发布)采用了另一种方法:重新设计注意力,让缓存从结构上在一开始就更小。

V4 使用了两种压缩注意力机制的混合方案。

压缩稀疏注意力(Compressed Sparse Attention,CSA)使用 softmax 门控池化将 KV 条目压缩 4 倍,然后在压缩后的 token 上应用稀疏注意力。

重度压缩注意力(Heavily Compressed Attention,HCA)则更加激进。它把跨 128 个 token 的 KV 条目整合成一个压缩条目,并在这些表示上应用密集注意力。

在 1M token 上下文下,与 DeepSeek-V3.2 相比,V4-Pro 只需要 27% 的单 token 推理 FLOPs,以及 10% 的 KV 缓存。

按绝对值计算,在 bf16 下,1M 上下文时每个序列的 KV 缓存为 9.62 GiB;而 V3.2 风格架构的估算值为 83.9 GiB。如果再叠加 fp4/fp8 量化,缓存还会再缩小 2 倍。

KV 缓存已经成为整个领域围绕模型架构进行优化的约束。

量化

训练会使用 FP32 或 BF16 来保证梯度稳定性。推理不需要这种精度。降低比特宽度带来的内存节省是线性的:

  • 7B 参数,FP32:28 GB
  • 7B 参数,FP16/BF16:14 GB
  • 7B 参数,INT8:7 GB
  • 7B 参数,INT4:3.5 GB

INT4 是 7B 模型能在拥有 4-6 GB 显存的笔记本 GPU 上运行的原因。GPTQ 和 AWQ 等方法使用按通道缩放因子,来尽量减少有损压缩带来的质量下降。

如果做得好,INT4 在标准基准测试上的表现会落在全精度模型的 1-2 个百分点以内。

从 FP16 切到 INT8 往往可以让推理延迟减半,同时几乎没有质量损失,这使得量化成为大多数部署中杠杆最高的优化手段。

服务基础设施

现代推理服务器会用几种优化来封装 prefill-decode 循环:

  • 连续批处理

    会在同一个 GPU step 中交错处理来自多个请求的 token,即使在内存受限的 decode 阶段,也能保持较高利用率。

  • 推测解码

    使用一个小型草稿模型提出多个 token,然后由大模型在一次前向传播中验证它们。当草稿模型的接受率较高时,这实际上会把多个顺序 decode step 转换成一次并行验证。

我在这里详细讲过推测解码:

Article

如何通过推测解码让 LLM 推理快 2-3 倍(Google 已在生产中使用)

  • PagedAttention

    (vLLM)以固定大小的块来管理 KV 缓存内存,消除碎片,并让每块 GPU 能承载更多并发请求。

vLLM、TensorRT-LLM 和 Text Generation Inference(TGI)等框架会结合这些技术。一块 GPU 可以服务数十个并发用户,因为 decode 会让大部分算术能力处于空闲状态,而连续批处理会用其他请求填满这些空闲能力。

完整推理路径

  • 分词:

    文本通过 BPE 变成整数 ID。

  • 嵌入:

    ID 变成向量。RoPE 编码位置。

  • Prefill:

    所有输入 token 会并行通过每一层进行处理。计算受限。填充 KV 缓存。输出第一个 token。

  • Decode 循环:

    每一步一个 token:为新 token 投影 Q,关注缓存的 K/V,运行 FFN,采样。将新的 K/V 追加到缓存。内存受限。

  • 反分词:

    token ID 被映射回文本并流式输出。

一些实际启示

  • 长提示词在 TTFT(prefill)上很昂贵
  • 长输出在 ITL(decode)上很昂贵
  • 而且它们会给不同的硬件资源带来压力。
  • 上下文长度不是免费的,因为它会膨胀 KV 缓存,并直接降低批处理容量。
  • 即使服务器已经满载,decode 期间的 GPU 利用率也可能降到 30%,因为瓶颈是内存带宽,而不是算术计算。
  • 解决办法不是更多算力,而是更快的内存、更小的缓存,或者更好的批处理。

当有人告诉你他们的模型很慢时,第一个诊断点是:它是启动慢(prefill 受限,优化 TTFT),还是流式输出慢(decode 受限,优化 ITL)。


加入ThinkInAI社区

#

如果你也对AI充满兴趣,欢迎加入我们的ThinkInAI社区,在这里,你可以:

  • 获取最新AI工具资讯
  • 参与实战经验分享
  • 结识志同道合的伙伴
  • 共同探讨AI应用方向

扫描文末二维码,加入ThinkInAI社区,一起拥抱AI新时代!


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:ThinkInAI社区 ThinkInAI ThinkInAI《图解LLM 推理是如何工作的》

评论:0   参与:  0