---
title: "昨天面试官问我：一个 Prompt 进入大模型后，内部到底发生了什么？"
description: "昨天面试时，面试官抛给我一道很典型的问题：“描述一下一个请求 prompt 经过 LLM 直到返回结果，这中间"
date: 2026-03-06T03:44:58Z
canonical: https://xiaobox.github.io/p/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/
author: 小盒子
categories: ["AI"]
tags: ["LLM", "ChatGPT", "Prompt", "Embedding", "缓存", "面试", "架构"]
source: https://mp.weixin.qq.com/s/kqlIWt_7izyV0HJC_LZEjg
license: CC BY-NC-SA 4.0
license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
---

# 昨天面试官问我：一个 Prompt 进入大模型后，内部到底发生了什么？

昨天面试时，面试官抛给我一道很典型的问题：

**“描述一下一个请求 prompt 经过 LLM 直到返回结果，这中间的推理过程，越详细越好。”**

这类题看起来开放，实际上很考验基本功。

因为它不是在问你会不会背几个名词，而是在看你是否真的理解：

●一个请求在系统里是怎么流动的

●进入模型之后到底算了什么

●为什么大模型是一个 token 一个 token 地往外生成

●为什么会有 prefill、decode、KV cache、sampling 这些概念

●为什么工程侧还要引入 batching、FlashAttention、continuous batching 之类的优化

如果回答得太浅，就会变成泛泛而谈；如果一上来就扎进公式，又很容易失去结构。

我后来复盘了一下，觉得这道题最好的答法，不是“想到哪说到哪”，而是按一条完整链路去讲：**服务层怎么处理请求，LLM 内部怎么做前向计算，生成阶段又是如何一步步产出结果的**。 这也是 GPT-3 所代表的自回归语言模型在推理时的基本工作方式：它不会在一次请求里更新参数，而是在固定权重下做前向传播，并逐 token 预测后续内容

## 一个高分回答，最好先把整体框架立住

如果让我在面试里先用一句话概括，我会这样回答：

**一个 prompt 从输入到输出，大体会经历 6 个阶段：请求封装、tokenization、推理调度、prefill、decode、结果反解码返回。其核心本质是：模型先并行“读懂”整段输入，建立上下文状态和 KV cache，然后再进入自回归生成循环，每次只预测下一个 token。** 这种“自回归 + 不做本次梯度更新”的推理方式，正是 GPT 类语言模型的基本范式；而 Transformer 则提供了它内部 attention 和前馈网络的计算骨架。

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/001-6e34d687.png)

这句话为什么重要？

因为它先把**系统层和模型层**分开了，也先把**prefill和decode**分开了。很多人答这道题失分，不是因为不会，而是因为把所有层次混在一起，听起来就没有脉络。

## 第一阶段：用户输入的 Prompt，并不是模型真正看到的内容

我们在聊天框里看到的是自然语言，但模型真正接收到的，通常不是这段原始文本本身。

在送入模型之前，服务层一般会先把 system、user、assistant 等多轮消息按固定模板组织起来，再补上一些特殊标记。随后，文本会经过 tokenizer，被切成 token 序列。像 OpenAI 开源的 tiktoken 就明确说明，它是一个用于模型的 BPE tokenizer。也就是说，对模型来说，文本首先会被变成一串离散的 token IDs，而不是“句子”本身。

这一层很多人容易忽略，但它很关键。

因为后面所有推理，都是建立在 token 序列上的。你输入的是一句中文、一段英文、还是一段代码，对模型来说，第一步都得先转换成 token IDs。

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/002-48de7d31.png)

## 第二阶段：请求不会立刻进模型，而是先进入推理服务和调度层

在真实工程系统里，一个请求到达后，通常不会马上冲进 GPU 执行。

它往往还要经过一层推理服务框架，比如 TGI、vLLM 这一类系统。它们会负责请求排队、动态 batching、缓存管理、流式返回等工作。Hugging Face 的 TGI 文档明确把 **continuous batching、token streaming、Flash Attention、Paged Attention** 等列为核心特性；而 Transformers 的 continuous batching 文档也说明，这种动态调度的目的是提高 GPU 利用率、降低延迟，并允许请求在每一步动态加入和退出批次。

所以，从系统视角看，链路通常是这样的：

**用户输入 → prompt 模板展开 → tokenization → 请求调度 / batching → 送入模型**

这一步的意义在于：

模型推理不是单个请求的“裸跑”，而是和其他请求一起，由推理引擎统一组织和优化的。

我们上一阶段说的 tokenization ，**严格来说， 不属于 Transformer 前向推理本身，模型只接收 input\_ids。但在现代推理服务里，tokenizer 往往和 serving 引擎绑定在一起，所以工程上看起来像是推理引擎在处理原始字符串。像 vLLM 就同时支持 text prompt 和 pre-tokenized prompt，两种模式都能跑。**

> 用户通常把原始字符串发给后端；后端中的推理服务通常持有 tokenizer，先把字符串编码成 token IDs，再交给模型执行 prefill/decode。只有在某些架构下，tokenization 才会提前在客户端或独立预处理层完成。

## 第三阶段：进入模型后，token 会先变成向量表示

真正进入 LLM 后，第一步不是“开始回答”，而是把 token IDs 映射成高维向量。

这一步叫 **embedding lookup**。每个 token 都会查一张巨大的 embedding 表，得到自己的向量表示。到这时，模型才真正进入连续空间的数值计算。Transformer 的基础论文《Attention Is All You Need》所定义的，就是这样一种基于 attention 的序列建模方式。

不过只有 token 向量还不够，因为模型还得知道“谁在前、谁在后”。

早期 Transformer 使用位置编码，后来很多大模型会用 **RoPE**（Rotary Position Embedding）。RoPE 的核心价值，是把位置信息融入 attention 计算中，让模型在处理 token 时同时保留相对位置信息。

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/003-100bf39a.png)

## 第四阶段：真正的“推理核心”发生在一层层 Transformer Block 里

这是这道题最核心的部分。

如果面试官说“越详细越好”，你就必须把 Transformer Block 讲清楚。

一个典型的 decoder-only LLM，每一层大体都会做两件事：

●**第一，Self-Attention**

●**第二，FFN / MLP（前馈网络**）

中间再配合残差连接和归一化。Transformer 论文给出的主体结构就是这样。

你可以把它想成：

●attention 负责“读群聊”

●FFN 负责“自己想一想、整理一下”

### Self-Attention 在干什么？

可以把它理解成：**当前位置的 token，要去看上下文里哪些 token 最相关。**

模型会把当前隐藏状态投影成 Query、Key、Value 三组向量，然后通过 Query 和所有 Key 的相似度算出注意力权重，再对 Value 做加权求和。Transformer 论文把它定义为 **Scaled Dot-Product Attention**。

对于生成式语言模型，还有一个必须强调的点：causal mask。

也就是当前位置只能看见自己和前面的 token，不能偷看未来。这一点决定了模型天然是自回归生成的：它永远只能基于已有上下文，去预测下一个 token。GPT-3 论文里所讨论的 few-shot/in-context learning，本质上也是建立在这种**自回归**预测机制之上的。

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/004-a52cdfd4.png)

关于 Q、K、V，可以简单这样理解：

Q = 我现在想找什么

K = 每个词身上贴的“索引标签”

V = 每个词真正携带、可被取走的信息。

最通俗的比喻是“图书馆检索”：

> 你现在脑子里有一个问题，这就是 Q（Query）；书架上每本书卡片上的主题标签，是 K（Key）；书里真正的内容，是 V（Value）。系统先拿你的问题 Q 去和所有标签 K 比一比，看看“像不像、相关不相关”；相关度高的那些书，它们的内容 V 就会被更多地取出来，最后合成当前这一步该看的信息。Transformer 论文对 attention 的定义，本质上就是“一个 query 对一组 key-value 对做匹配，输出是 values 的加权和”。

### FFN 又在干什么？

如果说 attention 负责“从上下文搬运信息”，那么 FFN 更像是“对当前位置做进一步加工”。

它不会跨位置交互，而是对每个 token 的表示单独做非线性变换，把特征进一步提纯和增强。Transformer 论文把它称为 position-wise feed-forward network。

所以一个 Transformer Block 可以粗略理解成：

**先决定我该关注上下文里的谁，再把取回来的信息做一轮更深的特征变换**

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/005-ea012f28.png)

注意在整个流程中，**prefill 和 decode 阶段，都要做 self-attention 和 FFN。**

但要分清楚：“都要做”不等于“做法完全一样”。

●Prefill 把整段 prompt 一次性送进去。 这时每一层都会对这批 token 做 masked self-attention，然后再过 FFN。因为整段 prompt 一开始就都已知，所以这一步可以在单个请求内部并行处理很多 token。Hugging Face 对 prefill 的描述也是：prefill 会处理整段输入，并建立 KV cache。

●Decode 开始一个 token 一个 token 往后生成。 这时每生成一个新 token，它仍然要在每一层里经过：一次 self-attention，一次 FFN

decode 不是把旧 token 全部再跑一遍 attention 和 FFN。有了 KV cache 后，旧 token 的 K/V 会被缓存起来；新 token 到来时，只需要为这个新 token 计算当前层需要的表示，再和历史 K/V 做注意力计算，然后继续过 FFN。Hugging Face 官方缓存文档明确说了：后续生成时，只传入尚未处理的新 token，并把 key/value 写入和读取自 cache。

> FFN 就是 Transformer 每层里、紧跟在 self-attention 后面的前馈网络，本质上是对每个 token 单独做的 MLP 加工。在标准 LLM 里，prefill 和 decode 两个阶段都要经过 self-attention 和 FFN；区别只是 prefill 处理整段已知 token，decode 只处理当前新 token，并复用历史 KV cache

## 第五阶段：Prefill——先把整段 Prompt “读完”

很多人会误以为模型一进来就开始逐字生成。

其实不是。生成前通常会先有一个很重要的阶段：**Prefill**。

Prefill 的意思是：

**先把整段 prompt 一次性跑完整个前向过程。**

在这个阶段，模型会为输入中的所有 token 计算各层隐藏状态，并且生成后面 decode 要用到的 KV cache。Hugging Face 的缓存文档明确指出，KV cache 会把注意力层中之前 token 产生的 key-value 对存下来，后续生成时直接复用，从而避免重复计算。

Prefill 的一个重要特点是：

**它通常可以高度并行。**

因为整段输入已经完整给定了，GPU 能把很多矩阵操作一起做完。所以 prefill 更像“先整体读题”，吞吐通常更高。vLLM 文档也明确把 prefill 归类为更偏 compute-bound 的阶段

你可以把 prefill 想象成一个正在考试的人，prefill 就是他正在读题，把题目先读到脑子里，填充好上下文，然后再开始做答（输出 token）

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/006-a96fea1e.png)

## 第六阶段：KV Cache——为什么不会每次都重算全文

这部分是面试里非常加分的点。

因为它体现你不只懂“算法”，还懂“推理为什么能跑得起来”。

如果没有 KV cache，那么每生成一个新 token，模型都要把整个历史上下文从头再算一遍，成本会非常高。

而有了 KV cache 后，历史 token 在每层 attention 中算出的 K 和 V 都会被缓存起来。下一个时间步只需要为新 token 计算新的 Query、Key、Value，再用新的 Query 去和历史缓存里的 Key 做匹配即可。Hugging Face 的官方文档把这一点解释得很清楚：KV cache 的目标就是消除重复计算，加速自回归生成。

一句话说明就是：

●**没有 KV cache，像每次都重读整篇文章**

●**有 KV cache，则像前文已经做好笔记，现在只补最后一句。**

### 为什么 KV cache 只缓存 K 和 V，而不缓存 Q？

**一个东西值不值得缓存，不看它“重不重要”，而看它“后面还会不会再次被用到”。**

KV cache 只缓存 K 和 V，不缓存 Q，不是因为 Q 不重要，而是因为 Q “只在当前这一步有用一次”；而 K、V 会在后面每一步继续被反复用到。 这正是 Hugging Face 官方对缓存机制的解释：过去 token 的 K 和 V 可以缓存并复用，而在推理时，只需要“最后一个 token 的 query”来计算当前步的表示。

## 第七阶段：Decode——开始逐 token 生成答案

当 prefill 完成后，模型已经“读懂”了整段输入。

接下来，系统会取最后一个位置的隐藏状态，通过输出层映射成整个词表上的 logits，也就是“下一个 token 的打分”。随后再通过 softmax 和解码策略，决定下一个 token 输出什么。Transformer 的输出逻辑与 Hugging Face 的生成文档都说明了这一点。

这里又有一个容易被问到的点：

**下一个 token 是怎么选出来的？**

并不是只有“选概率最大”这一种方式。常见解码策略包括 greedy、sampling、top-k、top-p 等。不同策略会影响文本的稳定性、多样性和创造性。Hugging Face 的生成策略文档对此有系统说明。

然后，流程进入一个循环：

●把刚生成的 token 接到上下文后面

●复用 KV cache

●只为这个新 token 跑一遍前向计算

●再得到新的 logits

●再生成下一个 token

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/007-469317f3.png)

这就是为什么你看到的大模型回答，总是一个 token 一个 token 流式地吐出来，而不是整段瞬间出现。

## 为什么“第一个字慢，后面快”？

这也是一个非常像面试 follow-up 的问题。

很多候选人知道 prefill 和 decode，但解释不清为什么两者速度特征不同。

vLLM 的优化文档明确提到，**prefill 更偏 compute-bound，decode 更偏 memory-bound。**

原因在于：prefill 可以把整段输入并行做大矩阵乘法，吃满 GPU 算力；而 decode 虽然每步只算一个 token，但它强依赖历史 KV cache，频繁访问显存，并且步骤之间有严格的顺序依赖。

这也是为什么工程上会有很多针对推理性能的优化，比如：

●FlashAttention：通过 IO-aware 的 attention 计算方式，减少显存读写

●continuous batching：动态调整批次，减少 GPU 空转

●chunked prefill / Paged Attention：改进长上下文和缓存管理效率

要注意，这些技术优化的是执行效率，不是模型的“语义本质”。模型本质上做的事情仍然是：基于已有上下文，反复预测下一个 token

我现在觉得，这道题最稳妥的回答方式，就是最后收束成一句话：

**一个 LLM 请求的推理过程，本质上是：先把 prompt 模板化并 token 化，经由推理服务调度进入 GPU；模型通过 embedding 和多层 Transformer block 并行完成 prefill，建立上下文表示和 KV cache；随后进入 decode 循环，基于历史缓存逐 token 执行注意力、前馈网络和采样，直到生成结束，再把 token 序列反解码成文本返回。 这条链路同时体现了 Transformer 的计算机制、自回归生成范式，以及现代推理系统在 batching、缓存和 attention kernel 上的工程优化**

## 看起来都是推理引擎的活儿啊？

从整个流程上看，几乎都是推理引擎在负责，所以可以这么理解，但要再往前走半步：

●从“流程编排”角度看，LLM 本体确实很被动；

●从“核心计算与语义生成”角度看，LLM 才是全链路里最不可替代的部分。

如果把整个链路拆开，职责大致是这样的：

1.**推理引擎 / serving 系统负责**：接 HTTP 请求、做 tokenization / 输入处理、调度 batching、管理 KV cache、协调 GPU worker、流式返回结果、做一部分采样与系统优化。vLLM 的官方文档甚至把这几层写得很直白：最少会有 1 个 API server 负责 HTTP、tokenization 和输入处理，1 个 engine core 负责 scheduler 和 KV cache 管理，再加上 N 个 GPU worker 负责执行模型前向计算。

2.**LLM 模型本体负责**：对 input\_ids 做 embedding，经过多层 Transformer block 的 self-attention 和 feed-forward network，输出 logits，也就是“下一个 token 的分数分布”。Transformer 论文给出的核心结构就是 attention + FFN；Transformers 文档也明确说 causal language modeling 本质上是在左侧上下文条件下做 next-token prediction，而模型输出里的 logits 是对词表中每个 token 的预测分数。

所以，**推理引擎决定“怎么高效地跑”，模型决定“到底生成什么”。**前者偏“编排与优化”，后者偏“语义计算与内容生成”

![图片](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2026-03-06-zuo-tian-mian-shi-guan-wen-wo-yi-ge-prompt-jin-ru-da-mo-xing/008-d8a4beaa.png)

