LLM学习:从 Pretraining 到 Decoder 推理

大语言模型看起来很神秘,一个重要原因是它把很多层东西叠在了一起:

  • 数据收集与清洗;
  • tokenization;
  • 大规模 pretraining;
  • Transformer decoder block;
  • instruction tuning;
  • preference alignment;
  • 推理时的 prefill 和 decode;
  • RAG、工具调用、系统提示词和部署优化。

这篇笔记试着把 LLM 的完整流程放在同一张图里理解。

最简单的核心观点是:

LLM 本质上是在学习预测下一个 token。现代 LLM 系统中的很多技术,都是围绕这个 next-token predictor,让它更有用、更可控、更高效,并且能连接外部知识。


1. 整体流程

一个现代 LLM 系统一般可以分成两个大阶段:训练阶段推理阶段

训练阶段的目标是得到一个模型:

  1. 收集和清洗文本或多模态数据;
  2. 训练 tokenizer;
  3. 用 next-token prediction 做大规模预训练;
  4. 可选地在领域数据上做 continued pretraining;
  5. 用指令数据做 supervised fine-tuning;
  6. 用偏好数据做 alignment;
  7. 评测安全性、推理、事实性、代码、数学和领域能力。

推理阶段的目标是使用这个模型:

  1. 接收用户 prompt;
  2. 可选地检索相关文档;
  3. 将 system、developer、user、tool 等消息整理成模型输入;
  4. 对 prompt 做 prefill
  5. 进入 decode 循环,一个 token 一个 token 地生成;
  6. 对输出做后处理,或者调用工具。

目前主流 LLM 的核心结构通常是 decoder-only Transformer。这里的 decoder 容易让人误解。在经典 encoder-decoder 模型里,encoder 负责编码输入,decoder 负责生成输出;而很多 LLM 只有自回归 decoder stack。它通过 causal self-attention 读取过去 token,并预测下一个 token。


2. 文本如何变成 Token

神经网络不能直接读自然语言字符。它读的是整数 token ID。

Tokenizer 会把文本映射成一个序列:

\[\text{text} \rightarrow (x_1, x_2, \ldots, x_T),\]

其中每个 (x_t) 都是词表 (V) 里的一个 token ID。

很多 LLM 使用 BPE、byte-level BPE、SentencePiece 或类似的 subword tokenizer。比如一句话:

Large language models are useful.

可能会被切成:

Large | language | models | are | useful | .

也可能根据词表被切成更细的 subword。

几个基本概念:

  • Vocabulary size:词表大小,也就是可能 token 的总数。
  • Token:模型处理的最小离散单位,可能是单词、子词、字符、字节或标点。
  • Context window:模型一次最多能处理多少个 token。
  • Embedding:每个 token 对应的可学习向量。

Token ID 进入模型后,会先被映射成向量:

\[h_t^{(0)} = E[x_t] + p_t,\]

其中 (E[x_t]) 是 token embedding,(p_t) 表示位置信息。很多现代 LLM 不直接使用简单的绝对位置向量,而是使用 RoPE,也就是 rotary positional embedding。


3. Pretraining:学习预测下一个 Token

Pretraining 是 LLM 最重要的阶段。模型在海量数据中学习语言结构、知识模式、代码规律、推理痕迹和世界常识。

对自回归语言模型来说,一个 token 序列的概率可以分解为:

\[p_\theta(x_1, x_2, \ldots, x_T) = \prod_{t=1}^{T} p_\theta(x_t \mid x_{<t}).\]

训练目标是最大化正确 token 的 likelihood,等价于最小化 cross-entropy loss:

\[\mathcal{L}_{\text{pretrain}} = - \sum_{t=1}^{T} \log p_\theta(x_t \mid x_{<t}).\]

这就是 next-token prediction

训练时模型可以一次看到整个序列,但 causal mask 会阻止位置 (t) 看到未来 token (x_{>t})。所以模型实际学习的是:

给定过去,预测接下来最可能出现什么。

这个目标看似简单,但很多任务都可以被写成文本补全:

  • 问答;
  • 摘要;
  • 翻译;
  • 代码生成;
  • 数学推理;
  • 对话;
  • 工具调用规划。

Pretraining 并不会直接把模型训练成一个礼貌、有边界、有格式意识的助手。它主要学习一般文本分布。因此后面还需要 post-training。


4. Decoder-Only Transformer

当前主流 LLM 通常由很多层 decoder Transformer block 堆叠而成。

设第 (l) 层输入 hidden states 为 (H^{(l)}),一种 pre-norm Transformer 层可以近似写成:

\[\tilde{H}^{(l)} = H^{(l)} + \mathrm{Attention}(\mathrm{Norm}(H^{(l)})),\] \[H^{(l+1)} = \tilde{H}^{(l)} + \mathrm{MLP}(\mathrm{Norm}(\tilde{H}^{(l)})).\]

每一层主要包含两部分:

  • causal self-attention;
  • feed-forward network,也常叫 MLP 或 FFN。

4.1 Self-Attention

对 hidden states (H),模型会投影得到 queries、keys 和 values:

\[Q = HW_Q, \quad K = HW_K, \quad V = HW_V.\]

Attention 的形式是:

\[\mathrm{Attention}(Q,K,V) = \mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}} + M\right)V.\]

这里 (M) 是 causal mask,用来屏蔽未来位置。

直观理解:

  • query:我现在想找什么信息?
  • key:我这里有什么信息,是否值得被别人关注?
  • value:如果我被关注,应该传递什么内容?

Self-attention 让每个 token 可以回看前面的相关 token。比如生成右括号时,模型可以关注前面对应的左括号。

4.2 Multi-Head Attention

Transformer 不只做一次 attention,而是使用多个 head:

\[\mathrm{head}_i = \mathrm{Attention}(Q_i,K_i,V_i).\]

然后把多个 head 拼接,再做线性投影:

\[\mathrm{MHA}(H) = \mathrm{Concat}(\mathrm{head}_1,\ldots,\mathrm{head}_m)W_O.\]

不同 attention head 可能关注不同模式:

  • 语法结构;
  • 长距离依赖;
  • 代码缩进;
  • 实体追踪;
  • 类似复制或检索的行为;
  • 推理中的中间步骤。

4.3 Feed-Forward Network

Attention 之后,每个 token 会独立经过 MLP:

\[\mathrm{MLP}(h) = W_2 \sigma(W_1 h),\]

其中 (\sigma) 可以是 GELU、SwiGLU 等激活函数。

Attention 负责让 token 之间交换信息;MLP 负责在每个 token 内部做非线性变换。

4.4 最终 Decoder 输出

经过最后一层 Transformer 后,位置 (t) 的 hidden state 会被投影到词表大小的 logits:

\[z_t = W_{\text{out}} h_t.\]

然后通过 softmax 得到下一个 token 的概率分布:

\[p_\theta(x_{t+1}=i \mid x_{\le t}) = \frac{\exp(z_{t,i})}{\sum_{j \in V}\exp(z_{t,j})}.\]

模型从这个分布中选择或采样一个 token,把它追加到上下文后面,然后重复这个过程。

所以推理时最终 decoder 的行为可以理解为:

prompt tokens -> Transformer decoder -> logits -> next token -> append -> repeat

5. Post-Training:从文本模型到助手

Pretraining 得到的是强大的 base model,但 base model 本质上只是文本补全器。为了让它成为可用助手,需要 post-training。

5.1 Supervised Fine-Tuning

Supervised fine-tuning,简称 SFT,会用 instruction-response 数据训练模型:

User: Explain self-attention.
Assistant: Self-attention is ...

损失函数仍然是 next-token cross-entropy,只是数据格式变成了指令和回答:

\[\mathcal{L}_{\text{SFT}} = - \sum_t \log p_\theta(y_t \mid x, y_{<t}),\]

其中 (x) 是指令,(y) 是目标回答。

SFT 主要教会模型:

  • 回答格式;
  • helpfulness;
  • 跟随指令;
  • 多轮对话风格;
  • 如果数据中有工具调用示例,也会学习工具调用格式。

5.2 Preference Alignment

Preference alignment 的目标是让模型更偏好好回答,而不是差回答。

常见数据形式是:

prompt x
chosen answer y+
rejected answer y-

方法包括 RLHF、RLAIF、PPO 风格优化和 DPO 等。一个简化的 DPO 目标可以写成:

\[\mathcal{L}_{\text{DPO}} = -\log \sigma\left( \beta \left[ \log \frac{\pi_\theta(y^+|x)}{\pi_{\text{ref}}(y^+|x)} - \log \frac{\pi_\theta(y^-|x)}{\pi_{\text{ref}}(y^-|x)} \right]\right).\]

Alignment 的目标不只是让模型更聪明,而是让输出更有帮助、更安全、更诚实,也更符合用户意图。


6. Inference:Prefill 和 Decode

很多 LLM 工程概念都出现在推理阶段。

假设用户 prompt 有 (n) 个 token:

\[x_1, x_2, \ldots, x_n.\]

模型需要处理 prompt,然后生成:

\[y_1, y_2, \ldots, y_m.\]

6.1 Prefill

Prefill 是对整个 prompt 做的第一次 forward pass。

在 prefill 阶段,模型会:

  • 对所有 prompt token 做 embedding;
  • 经过所有 Transformer layers;
  • 为每个 prompt 位置计算 keys 和 values;
  • 把这些 keys 和 values 存进 KV cache
  • 产生第一个待生成 token 的 logits。

Prefill 通常比较吃算力,因为 prompt 可能很长。不过 prompt 内的所有位置可以在 GPU 上并行计算。

从请求到第一个 token 出来的延迟常叫 TTFT,也就是 time to first token。长 prompt、长 RAG 上下文都会增加 prefill 成本。

6.2 KV Cache

在 attention 中,每个新 token 都需要关注前面的 keys 和 values。

如果没有 cache,每一步生成都要重新计算所有历史 token 的 (K) 和 (V),这非常浪费。

KV cache 存储的是:

\[K_{1:t}, V_{1:t}\]

而且每一层、每个 attention head 都要存。

在生成第 (t+1) 个 token 时,模型只需要为新 token 计算 (Q_{t+1}, K_{t+1}, V_{t+1}),然后让它关注缓存中的 (K_{1:t+1}, V_{1:t+1})。

KV cache 大幅加速生成,但也占显存。长上下文模型部署时,瓶颈经常不是参数本身,而是 KV cache。

6.3 Decode

Prefill 之后,模型进入 decode 循环:

  1. 从 logits 中选择或采样一个 token;
  2. 把这个 token 追加到上下文;
  3. 更新 KV cache;
  4. 对新 token 做一次 forward pass;
  5. 重复,直到遇到停止条件。

Decode 通常是串行的,因为 (y_t) 依赖 (y_{t-1})。这也是为什么生成速度常用 tokens per second 衡量。

6.4 Sampling

Logits 可以通过 temperature 转成概率:

\[p_i = \frac{\exp(z_i / \tau)}{\sum_j \exp(z_j / \tau)}.\]

这里 (\tau) 是 temperature。

  • temperature 低:更确定,更保守;
  • temperature 高:更多样,但也更容易发散;
  • greedy decoding:每次选择概率最高 token;
  • top-k sampling:只在概率最高的 (k) 个 token 中采样;
  • nucleus sampling:选择累计概率超过 (p) 的最小 token 集合采样。

Decoding 不是小细节。同一个模型,在不同 decoding 参数下会表现出明显不同的风格。


7. RAG:Retrieval-Augmented Generation

RAG 的核心思想是把 LLM 和外部文档连接起来。

一个基本 RAG 流程是:

  1. 把文档切成 chunks;
  2. 用 embedding model 把每个 chunk 编码成向量;
  3. 把向量存到 vector database 或索引中;
  4. 将用户 query 编码成向量;
  5. 检索相似 chunk;
  6. 把检索结果插入 prompt;
  7. 让 LLM 基于这些上下文回答。

相似度常用点积或 cosine similarity:

\[\mathrm{sim}(q,d) = \frac{q^T d}{\|q\|\|d\|}.\]

有了检索上下文 (C),生成就变成:

\[p(y \mid x, C).\]

RAG 有价值,是因为 base model 的参数是固定的。它可能不知道私有信息、最新信息或领域知识。RAG 可以在不重新训练模型的情况下,在推理时把相关知识交给模型。

但 RAG 不是万能的。常见问题包括:

  • chunk 切分不好;
  • 检索到无关文档;
  • 真正相关的文档没被召回;
  • 上下文过长;
  • 检索文档互相矛盾;
  • 模型忽略证据;
  • 引用格式不稳定。

所以好的 RAG 系统既是信息检索系统,也是 prompt engineering 和 LLM 推理系统。


8. 常见概念扫盲

8.1 Context Window

Context window 是模型一次请求最多能读取的 token 数。

更长的 context window 有助于长文档、多轮对话和 RAG,但会增加 prefill 计算量和 KV cache 显存。

8.2 Prompt

Prompt 是输入给模型的文本或消息序列。在 chat model 中,prompt 可能包含:

  • system message;
  • developer message;
  • user message;
  • assistant history;
  • tool results;
  • retrieved documents。

Prompt 很重要,因为模型的每个输出 token 都条件化在前面的 token 上。

8.3 System Prompt

System prompt 用来给模型高层行为约束,比如角色、风格、安全规则、输出格式和工具使用规则。

它不会改变模型参数,只会改变当前上下文。

8.4 Hallucination

Hallucination 指模型生成看起来合理但实际错误或缺乏依据的内容。

从模型角度看,它是在预测高概率文本,并不会天然知道每句话是否真实。RAG、工具调用、外部验证和更好的 prompt 能降低 hallucination,但不能完全消除。

8.5 Embedding

Embedding 是 token、句子、图片或文档的向量表示。

Embedding model 常用于语义搜索:

query -> vector -> nearest documents

8.6 LoRA

LoRA 是 low-rank adaptation。它不直接更新全部模型参数,而是学习小的低秩矩阵。

权重更新可以写成:

\[W' = W + \Delta W, \quad \Delta W = BA.\]

其中 (A) 和 (B) 是低秩矩阵。

LoRA 显存友好,常用于领域适配和个性化微调。

8.7 Quantization

Quantization 是把模型权重从 FP16、BF16 等较高精度,压到 INT8、INT4 等更低精度。

它可以减少显存并提升推理速度,但如果量化过猛,也可能损失模型质量。

8.8 Distillation

Distillation 是让小模型学习大模型的输出。

目标是在降低成本和延迟的同时,尽量保留大模型能力。

8.9 MoE

MoE 是 Mixture-of-Experts。它包含多个 expert network,但每个 token 只激活其中一部分。

这样可以扩大总参数规模,同时保持每个 token 的计算量相对可控。

8.10 Tool Use

Tool use 指模型输出结构化动作,例如:

{"tool": "search", "query": "latest occupancy prediction paper"}

外部系统执行工具,把结果返回给模型。这样 LLM 就能连接计算器、浏览器、数据库、代码解释器和 API。


9. 和我的研究方向的联系

LLM 不只是文本系统。很多概念和三维感知、具身智能也有关:

  • tokenization 对应紧凑场景表示;
  • attention 对应特征交互;
  • KV cache 对应记忆;
  • RAG 对应外部知识检索;
  • tool use 对应智能体动作;
  • prefill/decode efficiency 对应实时部署;
  • long-context reasoning 对应时间场景理解。

对我自己的研究来说,最有意思的桥梁是 token-based representation。

在 LLM 中,token 是语言建模的基本单位;在感知中,token 可以成为空间、时间、记忆、语义、通信和规划的基本单位。

所以学习 LLM 不只是为了 NLP。它提供了一套思考表示、记忆、压缩、检索和序列决策的语言。


10. 总结

LLM 的核心可以概括为:

\[\text{previous tokens} \rightarrow \text{next-token distribution}.\]

围绕这个核心,现代 LLM 系统加入了:

  • 大规模 pretraining;
  • decoder-only Transformer;
  • instruction tuning;
  • preference alignment;
  • 高效 prefill 和 decode;
  • KV cache;
  • decoding 策略;
  • RAG;
  • 工具调用和 agent 系统。

理解 LLM 既要理解数学模型,也要理解围绕模型搭建的工程系统。

模型预测 token。系统把 token prediction 变成真正可用的智能助手。




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • LLM Learning: From Pretraining to Decoder Inference
  • Refining My PhD Research Direction Around 3D Perception
  • 围绕三维感知进一步明确 Ph.D. 研究方向
  • From Occupancy Prediction to Occupancy World Models
  • 从占用预测到占用世界模型