微调LLM前你需要了解的一些概念

1. LLM 到底在做什么

大语言模型的核心任务很朴素:

给定前面的 token,预测下一个 token。

例如输入:

text 复制代码
法国 的 首都 是

模型要预测:

text 复制代码
巴黎

训练时,模型会不断看到类似样本:

text 复制代码
输入:法国 的 首都 是
目标:巴黎

如果模型给"巴黎"的概率高,loss 就小;如果模型把"伦敦"预测得更高,loss 就大。训练过程就是不断调整参数,让正确 token 的概率越来越高。

整体流程可以画成这样:
flowchart LR A"输入文本" --> B"Tokenizer 切成 token" B --> C"Token Embedding" C --> D"多层 Transformer Blocks" D --> E"最后位置 hidden state" E --> F"输出层 W_out / LM Head" F --> G"logits" G --> H"softmax" H --> I"下一个 token 概率分布" I --> J"选择或采样 token"

注意:模型内部不是直接处理汉字或单词,而是处理 token id 和高维向量。

2. Token、Embedding 和 Hidden State

一句话进入模型前,会先经过 tokenizer:

text 复制代码
"法国的首都是" → ["法国", "的", "首都", "是"]

每个 token 会被映射成一个向量,这一步叫 embedding:

text 复制代码
法国 → [0.12, -0.08, 0.31, ...]
的   → [0.03,  0.22, -0.11, ...]
首都 → [0.44, -0.19, 0.07, ...]
是   → [-0.21, 0.16, 0.28, ...]

如果模型的 hidden size 是 4096,那么每个 token 就会对应一个 4096 维向量。

一开始的 embedding 只是比较基础的 token 表示。经过多层 Transformer 之后,每个 token 的向量会融合上下文,变成 hidden state。

例如最后一个 token "是"的 hidden state,经过多层加工后,可以粗略理解为:

text 复制代码
h_last ≈ "当前上下文在问:法国的首都是哪个城市"

当然,模型里实际存的是高维数字向量,不是中文句子。中文解释只是帮助我们理解。

3. Transformer Block 的整体结构

LLM 通常不是只有一个 Transformer Block,而是很多层 Block 堆叠起来。

常见数量大致是:

text 复制代码
小模型:6 - 12 层
中等模型:24 - 32 层
大模型:40 - 80 层
超大模型:80 层以上

例如:

text 复制代码
GPT-2 small:12 层
GPT-2 medium:24 层
GPT-3 175B:96 层
LLaMA 7B:32 层
LLaMA 13B:40 层
LLaMA 65B:80 层

一个现代 Decoder-only Transformer Block 通常包含:

text 复制代码
Norm
Self-Attention
Residual Add
Norm
MLP / FFN
Residual Add

图示如下:
flowchart TD X"输入 x" --> N1"LayerNorm / RMSNorm" N1 --> A"Self-Attention" A --> ADD1"残差相加 x + Attention(...)" X --> ADD1 ADD1 --> N2"LayerNorm / RMSNorm" N2 --> M"MLP / FFN" M --> ADD2"残差相加 x' + MLP(...)" ADD1 --> ADD2 ADD2 --> Y"输出 y,传给下一层"

公式可以简化为:

text 复制代码
x' = x + SelfAttention(Norm(x))
y  = x' + MLP(Norm(x'))

其中 y 就是这一层 Block 的最终输出,会作为下一层 Block 的输入。

4. 每一层的输出会作为下一层输入吗

是的。

可以写成:

text 复制代码
X0 = Embedding(tokens)
X1 = Block1(X0)
X2 = Block2(X1)
X3 = Block3(X2)
...
XN = BlockN(XN-1)

每一层都会拿上一层输出的 hidden states 作为输入,并重新计算自己的 Q、K、V:

text 复制代码
第 1 层:Q1 = X0 Wq1, K1 = X0 Wk1, V1 = X0 Wv1
第 2 层:Q2 = X1 Wq2, K2 = X1 Wk2, V2 = X1 Wv2
第 3 层:Q3 = X2 Wq3, K3 = X2 Wk3, V3 = X2 Wv3

重点是:

每一层输入不同,每一层 Q/K/V 参数也不同,每一层都会重新做一次注意力计算。

低层可能更偏局部搭配、词法和位置;中层可能更偏语法和实体关系;高层可能更偏语义、任务意图和预测。这个说法只是直觉,不是人工规定。

5. Self-Attention:让 token 理解上下文

Self-Attention 要解决的问题是:

当前 token 应该重点关注上下文里的哪些 token?

例如:

text 复制代码
小明 把 苹果 放进 书包 因为 它 太甜 了

"它太甜"里的"它"更可能指"苹果",因为"甜"和"苹果"的语义关系更强。

如果句子变成:

text 复制代码
小明 把 苹果 放进 书包 因为 它 太小 了

"它太小"更可能指"书包",因为"太小"更像是在描述容器容量。

模型并不是写死规则,而是在大量训练中学到这些统计和语义关系。

6. Q、K、V 到底是什么

Q、K、V 分别是:

text 复制代码
Q = Query,查询
K = Key,键 / 标签
V = Value,值 / 内容

一句话记:

text 复制代码
Q:我想找什么?
K:我有什么标签,能不能被别人匹配到?
V:如果别人关注我,我能提供什么内容?

每个 token 都会同时生成 Q、K、V。

例如 token "它":

text 复制代码
Q("它") ≈ 我指代的是前面哪个东西?

前面的 token 有各自的 K:

text 复制代码
K("苹果") ≈ 水果、物体、可被描述味道
K("书包") ≈ 容器、物体、可被描述大小和容量

如果后面出现"太甜",那么"它"的 Q 会更匹配"苹果"的 K。模型就会更多读取"苹果"的 V。

如果后面出现"太小",那么"它"的 Q 会更匹配"书包"的 K。模型就会更多读取"书包"的 V。

QKV 计算公式是:

text 复制代码
Q = X Wq
K = X Wk
V = X Wv

注意力公式是:

text 复制代码
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V

流程图:
flowchart TD X"输入 hidden states X" --> Q"Q = X Wq" X --> K"K = X Wk" X --> V"V = X Wv" Q --> S"QK\^T 计算相似度" K --> S S --> SCALE"除以 sqrt(d_k) 缩放" SCALE --> SM"softmax 得到注意力权重" SM --> OUT"权重加权求和 V" V --> OUT OUT --> H"融合上下文后的表示"

为什么要除以 sqrt(d_k)

因为维度较大时,Q 和 K 点积的数值可能很大,softmax 会变得过于尖锐,训练不稳定。除以 sqrt(d_k) 可以稳定数值范围。

7. 用一个例子看模型如何理解上下文

输入:

text 复制代码
法国 的 首都 是

模型要预测下一个 token:

text 复制代码
巴黎

在最后一个 token "是"的位置,模型可能需要关注:

text 复制代码
法国
首都

可以粗略理解为:

text 复制代码
Q("是"):这个句子需要补充什么事实?
K("法国"):国家实体
K("首都"):需要城市答案
V("法国"):法国相关语义信息
V("首都"):首都关系相关信息

Attention 聚合之后,最后位置的 hidden state 逐渐包含:

text 复制代码
国家 = 法国
关系 = 首都
答案类型 = 城市

最后输出层再把这个 hidden state 映射到词表,得到:

text 复制代码
巴黎: 高分
伦敦: 低分
苹果: 极低分

这就是"理解上下文"和"预测下一个 token"之间的桥。

8. Multi-Head Attention:从多个角度看上下文

一个注意力头只能从一种子空间理解关系。多个头可以同时关注不同关系。

例如:

text 复制代码
Head 1:关注语法关系
Head 2:关注实体关系
Head 3:关注指代关系
Head 4:关注位置关系

Multi-Head Attention 的直觉是:

让模型从多个角度同时理解上下文。

每个 head 都有自己的 Q/K/V 投影,最后多个 head 的结果会拼接或合并,再经过一个输出投影矩阵 Wo
flowchart LR X"输入 X" --> H1"Head 1 Attention" X --> H2"Head 2 Attention" X --> H3"Head 3 Attention" X --> H4"Head 4 Attention" H1 --> C"Concat / 合并" H2 --> C H3 --> C H4 --> C C --> WO"输出投影 Wo" WO --> Y"Attention 输出"

9. MLP / FFN:对信息做加工

Self-Attention 更像"信息检索":

text 复制代码
当前 token 应该从哪些上下文 token 里拿信息?

MLP / FFN 更像"信息加工":

text 复制代码
拿到信息之后,如何进一步变换、提炼、组合?

MLP 和 FFN 在 Transformer 语境下基本可以认为是同一个模块:

text 复制代码
MLP = Multi-Layer Perceptron,多层感知机
FFN = Feed-Forward Network,前馈神经网络

它通常对每个 token 的 hidden state 单独处理,不负责 token 之间互相通信。token 之间的信息交换主要发生在 Attention 里。

传统 FFN 结构:

text 复制代码
hidden_size → intermediate_size → hidden_size

例如:

text 复制代码
4096 → 11008 → 4096

公式:

text 复制代码
FFN(x) = W2 * activation(W1 * x + b1) + b2

常见激活函数有:

text 复制代码
GELU
SiLU
ReLU
SwiGLU

现代 LLM 常用 SwiGLU 一类门控结构,可以理解为:

text 复制代码
哪些特征应该通过,哪些特征应该被抑制。

Attention 和 MLP 的区别可以这样记:

text 复制代码
Attention:token mixing,不同 token 之间交换信息
MLP:channel mixing,同一个 token 向量的不同维度之间加工组合

一句话:

Attention 负责"看谁",MLP 负责"想明白"。

10. 残差相加是什么

残差连接不是让一层完全替换输入,而是:

text 复制代码
输出 = 原输入 + 本层新加工的信息

在 Attention 后:

text 复制代码
x' = x + Attention(Norm(x))

在 MLP 后:

text 复制代码
y = x' + MLP(Norm(x'))

直觉是:

text 复制代码
新表示 = 旧理解 + 本层补充的新理解

这有几个好处:

text 复制代码
保留原始信息
让每一层学习增量修改
缓解深层网络梯度传播困难
让模型在某层没学到有用东西时,也可以近似保持原样

你可能会问:处理后的向量会不会盖过原向量?

理论上会。如果 Attention(x)MLP(x) 数值特别大,确实可能主导结果。但实际模型有机制控制:

text 复制代码
LayerNorm / RMSNorm 稳定数值范围
参数初始化控制初始输出幅度
训练过程会惩罚不合适的过大修改
有些模型还会使用残差缩放、门控或 Dropout

所以残差连接不是简单粗暴地覆盖,而是让每层在旧表示上做可学习的增量修正。

11. 输出层 W_out:从 hidden state 到 token 概率

经过最后一层 Transformer 后,每个位置都有一个 hidden state。

对于自回归语言模型,预测下一个 token 时,通常使用最后一个位置的 hidden state:

text 复制代码
h_last

例如输入:

text 复制代码
法国 的 首都 是

最后位置"是"的 hidden state 可以理解为:

text 复制代码
h_last ≈ "这个句子在问法国的首都是哪个城市"

输出层的任务是:

h_last 映射成整个词表上每个 token 的分数。

公式:

text 复制代码
logits = h_last W_out + b

如果:

text 复制代码
hidden_size = 4096
vocab_size = 50000

那么:

text 复制代码
h_last shape = 4096
W_out shape = 4096 × 50000
logits shape = 50000

也就是说:

text 复制代码
一个 4096 维向量
→ 输出层
→ 50000 个 token 的原始分数

这些原始分数叫 logits:

text 复制代码
巴黎: 15.2
伦敦: 7.1
苹果: -2.5
的: 0.8

logits 还不是概率,需要经过 softmax:

text 复制代码
P(token_i) = exp(logit_i) / sum(exp(logit_j))

得到:

text 复制代码
巴黎: 0.86
伦敦: 0.04
柏林: 0.03
苹果: 0.000001

图示:
flowchart LR H"最后位置 hidden state h_last" --> W"线性输出层 W_out" W --> L"logits:每个 token 的原始分数" L --> S"softmax" S --> P"概率分布" P --> T"选择或采样下一个 token"

输出层可以理解为:

当前 hidden state 和词表中每个 token 的"答案向量"做匹配。

很多模型会让输入 embedding 和输出层权重共享参数,这叫 weight tying。直觉上就是:

text 复制代码
输入层:把 token 变成向量
输出层:把向量再匹配回 token

12. Wq/Wk/Wv 和 W_out 的关系

模型的参数是一个大集合:

text 复制代码
模型参数 =
Embedding 参数
+ 多层 Transformer Block 参数
+ Final Norm 参数
+ 输出层 W_out 参数

每个 Transformer Block 里面又有:

text 复制代码
Attention 参数:Wq, Wk, Wv, Wo
MLP / FFN 参数:W_up, W_down, W_gate 等
Norm 参数

结构可以画成:
flowchart TD P"模型总参数" --> E"Embedding 参数" P --> B"Transformer Blocks 参数" P --> FN"Final LayerNorm / RMSNorm 参数" P --> O"输出层 W_out / LM Head 参数" B --> A"Attention: Wq, Wk, Wv, Wo" B --> M"MLP / FFN: W_up, W_down, W_gate" B --> N"Block 内 Norm 参数"

它们的关系是:

text 复制代码
Wq/Wk/Wv:在每一层 Attention 里,用来理解上下文
Wo:Attention 内部的输出投影
W_out:模型最后的输出层,用来预测 token

注意不要混淆:

text 复制代码
Wo:Transformer Block 内部 Attention 的输出投影
W_out:整个模型最后映射到词表的输出层

13. 训练时它们如何一起更新

训练时,模型会做:

text 复制代码
前向传播:输入 tokens,计算预测概率
计算 loss:看正确 token 概率高不高
反向传播:计算每个参数对 loss 的影响
优化器更新:调整参数

语言模型最常用的是交叉熵损失:

text 复制代码
Loss = -log P(正确 token)

例如目标 token 是"巴黎"。

如果模型输出:

text 复制代码
巴黎: 0.90
伦敦: 0.04
苹果: 0.0001

loss 较小。

如果模型输出:

text 复制代码
巴黎: 0.02
伦敦: 0.80
苹果: 0.01

loss 较大。

反向传播会把误差信号传回所有相关参数:

text 复制代码
W_out
Wq / Wk / Wv / Wo
MLP 参数
Norm 参数
Embedding 参数

梯度下降更新公式:

text 复制代码
参数 = 参数 - 学习率 × 梯度
θ = θ - η ∇L

现代 LLM 常用 AdamW 等优化器,而不是最朴素的 SGD。

训练链路图:
flowchart TD A"输入 tokens" --> B"模型前向传播" B --> C"输出概率分布" C --> D"和真实下一个 token 计算交叉熵 loss" D --> E"反向传播计算梯度" E --> F"AdamW / 梯度下降更新参数" F --> G"W_out 更新" F --> H"Q/K/V 矩阵更新" F --> I"MLP 参数更新" F --> J"Embedding 等其他参数更新"

14. 推理时的 KV Cache

训练时,模型通常可以并行处理完整序列。

推理时,GPT 类模型是自回归生成:

text 复制代码
法国 的 首都 是 → 巴黎
法国 的 首都 是 巴黎 → 。

每一步只新增一个 token。历史 token 的 K/V 不会改变,所以可以缓存起来:

text 复制代码
KV Cache = 缓存历史 token 的 Key 和 Value

这样下一步生成时,就不需要重新计算所有历史 token 的 K/V,只需要计算新 token 的 Q/K/V,并拿新 Q 去和缓存的 K 做注意力。

优点:

text 复制代码
显著减少重复计算
加快推理速度

代价:

text 复制代码
占用更多显存
上下文越长,KV Cache 越大

15. 一条完整主线总结

以输入:

text 复制代码
法国 的 首都 是

预测:

text 复制代码
巴黎

完整过程是:

text 复制代码
1. Tokenizer 把文本切成 token
2. Embedding 把 token id 映射成向量
3. 第 1 层 Transformer Block 加工这些向量
4. 每层 Attention 用 Q/K/V 让 token 关注相关上下文
5. 每层 MLP 对每个 token 的向量做非线性加工
6. 残差连接保留旧信息并叠加新信息
7. 多层 Block 逐步形成更丰富的 hidden states
8. 最后位置 hidden state 表示整个前缀的预测语境
9. 输出层 W_out 把 hidden state 映射到词表 logits
10. softmax 把 logits 转成概率分布
11. 模型选择或采样出下一个 token
12. 训练时用 loss 衡量预测错多少
13. 反向传播和优化器更新所有相关参数

16. 面试高频回答模板

Q1:Self-Attention 是什么?

Self-Attention 是 Transformer 的核心机制,它让序列中每个 token 根据与其他 token 的相关性,动态聚合上下文信息。相比 RNN,它可以并行计算,并且更容易捕捉长距离依赖。

Q2:Q/K/V 分别是什么?

Q 是当前位置想查询什么信息,K 是每个位置可被匹配的特征,V 是每个位置实际提供的信息。Attention 通过 Q 和 K 的点积计算相关性,经 softmax 得到权重,再对 V 加权求和。

Q3:Transformer Block 里有什么?

典型 Decoder-only Transformer Block 包含 Self-Attention、MLP/FFN、LayerNorm/RMSNorm 和 Residual Connection。Attention 负责 token 间信息交互,MLP 负责非线性加工,Norm 稳定训练,Residual 保留信息并改善梯度传播。

Q4:MLP / FFN 的作用是什么?

MLP/FFN 对每个 token 的 hidden state 独立做非线性变换。它通常先升维,再经过激活函数或门控结构,最后降回 hidden size。Attention 更偏信息检索,MLP 更偏信息加工和知识表达。

Q5:残差连接为什么重要?

残差连接把子层输出和原输入相加,例如 x + Attention(x)。它让每层学习增量修改,而不是完全重写表示,有助于保留原始信息、改善梯度传播,使深层模型更容易训练。

Q6:输出层如何预测下一个 token?

Transformer 最后一层会输出 hidden state。预测下一个 token 时,模型取最后位置的 hidden state,通过线性输出层 W_out 映射到词表大小的 logits,再经过 softmax 得到每个 token 的概率分布。

Q7:Wq/Wk/Wv 和 W_out 的关系是什么?

Wq/Wk/Wv 是每层 Attention 内部的参数,用来生成 Query、Key、Value,从而理解上下文。W_out 是模型最后的语言建模输出头,用来把最终 hidden state 映射成词表 logits。它们都属于模型参数,训练时会通过同一个 loss 一起更新。

17. 最短记忆版

text 复制代码
Embedding:把 token 变成向量
Self-Attention:决定每个 token 该看谁
Q:我想找什么
K:我有什么标签
V:我能提供什么内容
MLP / FFN:对拿到的信息做加工
Residual:旧理解 + 新补充
LayerNorm / RMSNorm:稳定数值
Transformer Blocks:多层逐步深化表示
W_out:把最终 hidden state 映射到词表分数
softmax:把分数转成概率
Loss:衡量正确 token 概率够不够高
Gradient Descent:根据错误更新参数
KV Cache:推理时缓存历史 K/V,加速生成

一句话总结:

LLM 先把 token 变成向量,再通过多层 Transformer 用 Q/K/V 聚合上下文,用 MLP 加工表示,用残差和归一化稳定深层训练,最后通过输出层把最终 hidden state 映射为词表概率,并用 loss 和梯度下降不断更新所有参数。