目录
- 语言模型基础理论
- [Transformer 架构详解](#Transformer 架构详解)
- 预训练理论与策略
- 微调与对齐技术
- 推理与解码策略
- 上下文与长序列技术
- 高效训练与推理技术
- 评估与能力分析
- 多模态与智能体
- 术语速查表
1. 语言模型基础理论
1.1 什么是语言模型
语言模型 (Language Model, LM) 的定义:
给定一个词序列 w₁, w₂, ..., w_{n-1},预测下一个词 wₙ 的概率分布:
P(wₙ | w₁, w₂, ..., w_{n-1})
更一般地,建模整个序列的概率:
P(w₁, w₂, ..., wₙ) = Π_{i=1}^{n} P(wᵢ | w₁, ..., w_{i-1})
这称为自回归分解 (Autoregressive Factorization)
直觉理解:
语言模型 = "统计意义上的语言理解器"
它学习了:
- 词语之间的共现关系
- 语法结构
- 语义关联
- 世界知识
- 推理模式
1.2 核心术语
┌─────────────────────────────────────────────────────────────────────┐
│ 核心术语定义 │
├─────────────────┬───────────────────────────────────────────────────┤
│ 术语 │ 定义 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Token │ 文本的最小处理单位 │
│ │ 可以是字符、子词 (BPE)、词 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Tokenization │ 将文本切分为 token 序列的过程 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Vocabulary │ 词表,所有可能 token 的集合 │
│ │ GPT-2: 50,257 tokens │
│ │ LLaMA: 32,000 tokens │
├─────────────────┼───────────────────────────────────────────────────┤
│ Embedding │ 将 token 映射为稠密向量 │
│ │ Token ID → d_model 维向量 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Context │ 模型在生成时能"看到"的文本 │
│ │ Context Window = 最大上下文长度 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Prompt │ 输入给模型的文本/指令 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Completion │ 模型生成的输出文本 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Inference │ 使用模型生成文本的过程 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Training │ 使用数据训练模型参数的过程 │
└─────────────────┴───────────────────────────────────────────────────┘
1.3 Tokenization 详解
Tokenization 是 LLM 的第一步,将原始文本转换为模型可处理的数字序列
常见方法:
1. 字符级 (Character-level):
"hello" → ['h', 'e', 'l', 'l', 'o']
优点: 词表小 (26 + 标点)
缺点: 序列长,语义弱
2. 词级 (Word-level):
"hello world" → ['hello', 'world']
优点: 语义明确
缺点: 词表巨大 (100K+),OOV 问题
3. 子词级 (Subword-level) ← 主流方法:
"unhappiness" → ['un', 'happiness']
"tokenization" → ['token', 'ization']
优点: 平衡词表大小和序列长度
方法: BPE, WordPiece, SentencePiece, Unigram
BPE (Byte Pair Encoding)
BPE 算法:
训练阶段:
1. 初始化: 将所有词拆分为字符
2. 统计: 计算所有相邻字符对的频率
3. 合并: 将最高频的字符对合并为新 token
4. 重复: 直到达到目标词表大小
示例:
初始: ['l', 'o', 'w', ' '</], ['l', 'o', 'w', 'e', 'r', ' '</], ...
合并 'l' + 'o' → 'lo'
合并 'lo' + 'w' → 'low'
合并 'low' + ' '</ → 'low '</
编码阶段:
贪心匹配: 从左到右,匹配最长的已知 token
class BPETokenizer:
"""
BPE 分词器
理论:
通过统计学习最优的子词切分
高频词保持完整,低频词拆分为子词
"""
def __init__(self, vocab_size=1000):
self.vocab_size = vocab_size
self.merges = {} # 合并规则
self.vocab = {} # 词表
def train(self, corpus):
"""
训练 BPE
1. 统计词频
2. 迭代合并高频对
"""
# 统计词频
word_freq = self._count_words(corpus)
# 初始化: 拆分为字符
splits = {word: list(word) for word in word_freq}
# 迭代合并
while len(self.vocab) < self.vocab_size:
# 统计相邻对频率
pair_freq = self._count_pairs(splits, word_freq)
if not pair_freq:
break
# 找最高频对
best_pair = max(pair_freq, key=pair_freq.get)
# 合并
self.merges[best_pair] = len(self.vocab)
self.vocab[''.join(best_pair)] = len(self.vocab)
# 更新切分
splits = self._merge_pair(splits, best_pair)
def encode(self, text):
"""
编码: 文本 → token IDs
"""
tokens = list(text)
while len(tokens) > 1:
# 找可合并的对
pairs = [(tokens[i], tokens[i+1]) for i in range(len(tokens)-1)]
# 选择优先级最高的合并
mergeable = [(p, self.merges[p]) for p in pairs if p in self.merges]
if not mergeable:
break
best_pair = min(mergeable, key=lambda x: x[1])[0]
# 执行合并
new_tokens = []
i = 0
while i < len(tokens):
if i < len(tokens) - 1 and (tokens[i], tokens[i+1]) == best_pair:
new_tokens.append(tokens[i] + tokens[i+1])
i += 2
else:
new_tokens.append(tokens[i])
i += 1
tokens = new_tokens
return [self.vocab.get(t, 0) for t in tokens]
1.4 模型参数术语
┌─────────────────────────────────────────────────────────────────────┐
│ 模型参数术语 │
├─────────────────┬───────────────────────────────────────────────────┤
│ 参数 │ 含义与典型值 │
├─────────────────┼───────────────────────────────────────────────────┤
│ d_model │ 模型隐藏维度 │
│ │ GPT-3: 12,288; LLaMA-7B: 4,096 │
├─────────────────┼───────────────────────────────────────────────────┤
│ n_layers │ Transformer 层数 │
│ │ GPT-3: 96; LLaMA-7B: 32 │
├─────────────────┼───────────────────────────────────────────────────┤
│ n_heads │ 注意力头数 │
│ │ GPT-3: 96; LLaMA-7B: 32 │
├─────────────────┼───────────────────────────────────────────────────┤
│ d_head │ 每个注意力头的维度 = d_model / n_heads │
│ │ 通常 128 │
├─────────────────┼───────────────────────────────────────────────────┤
│ d_ff │ 前馈网络中间维度 │
│ │ 通常 d_model × 4 或 d_model × 8/3 │
├─────────────────┼───────────────────────────────────────────────────┤
│ vocab_size │ 词表大小 │
│ │ 32K - 100K+ │
├─────────────────┼───────────────────────────────────────────────────┤
│ max_seq_len │ 最大序列长度 │
│ │ 2K, 4K, 8K, 32K, 128K, 1M+ │
├─────────────────┼───────────────────────────────────────────────────┤
│ params │ 模型总参数量 │
│ │ 7B, 13B, 70B, 175B, 540B │
└─────────────────┴───────────────────────────────────────────────────┘
参数量估算:
Transformer 参数 ≈ 12 × n_layers × d_model² (近似)
LLaMA-7B: 32 × 4096² × 12 ≈ 6.4B (接近 7B)
GPT-3: 96 × 12288² × 12 ≈ 174B (接近 175B)
2.1 整体架构
Transformer 架构 (Decoder-only, GPT 风格):
输入 Token IDs
│
▼
┌─────────────┐
│ Token Embed │ vocab_size × d_model
└──────┬──────┘
│
+ ─────── Positional Encoding / RoPE
│
┌──────┴──────┐
│ Transformer │ × n_layers
│ Block │
│ ┌─────────┐ │
│ │ RMSNorm │ │ (或 LayerNorm)
│ └────┬────┘ │
│ ┌────┴────┐ │
│ │ Multi │ │ Self-Attention
│ │ Head │ │
│ │Attention│ │
│ └────┬────┘ │
│ + (残差) │
│ ┌────┴────┐ │
│ │ RMSNorm │ │
│ └────┬────┘ │
│ ┌────┴────┐ │
│ │ FFN / │ │ 前馈网络 (SwiGLU)
│ │ MoE │ │ 或 混合专家
│ └────┬────┘ │
│ + (残差) │
└──────┬──────┘
│
┌──────┴──────┐
│ RMSNorm │
└──────┬──────┘
│
┌──────┴──────┐
│ LM Head │ d_model × vocab_size
└──────┬──────┘
│
▼
输出 Logits → Softmax → 下一个 Token 概率
2.2 自注意力机制(Self-Attention)
自注意力是 Transformer 的核心机制
数学定义:
给定输入序列 X ∈ ℝ^{n×d}:
Q = X·W_Q (Query, 查询)
K = X·W_K (Key, 键)
V = X·W_V (Value, 值)
其中 W_Q, W_K, W_V ∈ ℝ^{d×d_k}
注意力计算:
Attention(Q, K, V) = softmax(QK^T / √d_k) · V
详细展开:
步骤 1: 计算注意力分数
S = Q·K^T ∈ ℝ^{n×n}
S_ij = q_i · k_j = Σ_d Q[id] · K[jd]
含义: 位置 i 对位置 j 的关注程度
步骤 2: 缩放
S = S / √d_k
理论: 防止点积过大导致 softmax 饱和
当 d_k 大时,点积的方差为 d_k
除以 √d_k 使方差为 1
步骤 3: 因果掩码 (Causal Mask)
对于位置 i,只能看到位置 ≤ i
M_ij = -∞ if j > i
0 if j ≤ i
S = S + M
步骤 4: Softmax 归一化
A = softmax(S) ∈ ℝ^{n×n}
A_ij = exp(S_ij) / Σ_k exp(S_ik)
含义: 注意力权重,每行和为 1
步骤 5: 加权聚合
Output = A · V ∈ ℝ^{n×d_v}
output_i = Σ_j A_ij · v_j
含义: 用注意力权重对 Value 加权求和
直觉理解:
Q (查询): "我在找什么信息?"
K (键): "我有什么信息?"
V (值): "我的实际内容是什么?"
注意力: 根据查询和键的匹配度,聚合对应的值
class SelfAttention(nn.Module):
"""
自注意力机制
理论核心:
允许序列中每个位置关注所有其他位置
动态计算依赖关系 (不像 RNN 固定顺序)
"""
def __init__(self, d_model, n_heads, max_seq_len):
super().__init__()
self.d_model = d_model
self.n_heads = n_heads
self.d_head = d_model // n_heads
# QKV 投影
self.W_Q = nn.Linear(d_model, d_model, bias=False)
self.W_K = nn.Linear(d_model, d_model, bias=False)
self.W_V = nn.Linear(d_model, d_model, bias=False)
self.W_O = nn.Linear(d_model, d_model, bias=False)
# 因果掩码
self.register_buffer('causal_mask',
torch.triu(torch.ones(max_seq_len, max_seq_len), diagonal=1).bool()
)
def forward(self, x):
B, N, D = x.shape
# QKV 投影
Q = self.W_Q(x).view(B, N, self.n_heads, self.d_head).transpose(1, 2)
K = self.W_K(x).view(B, N, self.n_heads, self.d_head).transpose(1, 2)
V = self.W_V(x).view(B, N, self.n_heads, self.d_head).transpose(1, 2)
# Q, K, V: [B, H, N, d_head]
# 注意力分数
scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.d_head ** 0.5)
# scores: [B, H, N, N]
# 因果掩码
scores.masked_fill_(self.causal_mask[:N, :N], float('-inf'))
# Softmax
attn_weights = F.softmax(scores, dim=-1)
# 加权聚合
output = torch.matmul(attn_weights, V)
# output: [B, H, N, d_head]
# 合并多头
output = output.transpose(1, 2).contiguous().view(B, N, D)
output = self.W_O(output)
return output
"""
自注意力的计算复杂度:
时间复杂度: O(n² · d)
- QK^T: O(n² · d)
- softmax: O(n²)
- A·V: O(n² · d)
空间复杂度: O(n² + n·d)
- 注意力矩阵: O(n²)
- QKV: O(n·d)
当 n 很大时 (如 128K tokens),n² 成为瓶颈
这就是为什么需要 FlashAttention 等优化
"""
2.3 多头注意力(Multi-Head Attention)
理论:
将注意力分成多个"头",每个头学习不同的注意力模式
MultiHead(Q, K, V) = Concat(head_1, ..., head_h) · W_O
head_i = Attention(Q·W_i^Q, K·W_i^K, V·W_i^V)
其中:
W_i^Q, W_i^K ∈ ℝ^{d×d_k}, W_i^V ∈ ℝ^{d×d_v}
d_k = d_v = d_model / h
为什么需要多头?
单头注意力只能学习一种关注模式
多头注意力可以同时学习:
- 头 1: 关注语法结构 (主语-谓语)
- 头 2: 关注语义相似 (同义词)
- 头 3: 关注位置关系 (相邻词)
- 头 4: 关注长距离依赖 (指代消解)
不同的头有不同的注意力模式,互补
2.4 位置编码(Positional Encoding)
问题: 自注意力是排列不变的 (permutation invariant)
不知道 token 的位置信息
解决: 添加位置编码
1. 正弦位置编码 (Sinusoidal, 原始 Transformer):
PE(pos, 2i) = sin(pos / 10000^(2i/d))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d))
优点: 可以外推到更长序列
缺点: 不如学习的位置编码灵活
2. 可学习位置编码 (Learned):
PE = Embedding(pos)
优点: 灵活,效果好
缺点: 不能外推 (固定长度)
3. RoPE (旋转位置编码) ← 当前主流:
通过旋转矩阵编码相对位置
详见下文
RoPE (Rotary Position Embedding)
论文: "RoFormer: Enhanced Transformer with Rotary Position Embedding" (Su et al., 2021)
核心思想:
将位置信息编码为旋转操作
相对位置关系通过旋转角度差体现
数学推导:
对于位置 m 的 query 和位置 n 的 key:
q_m = R(m) · q
k_n = R(n) · k
其中 R(θ) 是旋转矩阵:
R(θ) = [[cos θ, -sin θ], [sin θ, cos θ]]
注意力分数:
<q_m, k_n> = <R(m)q, R(n)k> = <q, R(n-m)k>
关键: 只依赖相对位置 (n-m),而非绝对位置
优势:
1. 相对位置编码: 自然捕获相对位置关系
2. 长序列外推: 可以外推到训练时未见的长度
3. 计算高效: 只需逐元素乘法
4. 与线性注意力兼容
class RotaryPositionEmbedding(nn.Module):
"""
旋转位置编码 (RoPE)
理论:
通过旋转矩阵将位置信息注入 Q 和 K
相对位置通过旋转角度差体现
优势:
- 相对位置编码
- 可外推到更长序列
- 计算高效
"""
def __init__(self, d_head, max_seq_len=8192, base=10000):
super().__init__()
self.d_head = d_head
# 计算频率
inv_freq = 1.0 / (base ** (torch.arange(0, d_head, 2).float() / d_head))
self.register_buffer('inv_freq', inv_freq)
# 预计算旋转角度
t = torch.arange(max_seq_len).float()
freqs = torch.outer(t, inv_freq)
# freqs: [max_seq_len, d_head/2]
cos_cached = freqs.cos()
sin_cached = freqs.sin()
self.register_buffer('cos_cached', cos_cached)
self.register_buffer('sin_cached', sin_cached)
def forward(self, q, k, position_ids):
"""
q, k: [B, H, N, d_head]
position_ids: [B, N]
"""
cos = self.cos_cached[position_ids] # [B, N, d_head/2]
sin = self.sin_cached[position_ids]
# 扩展维度
cos = cos[:, None, :, :] # [B, 1, N, d_head/2]
sin = sin[:, None, :, :]
# 旋转
q_rot = self._rotate_half(q)
k_rot = self._rotate_half(k)
q_out = q * cos + q_rot * sin
k_out = k * cos + k_rot * sin
return q_out, k_out
def _rotate_half(self, x):
"""将后半部分取负并交换"""
x1, x2 = x[..., :self.d_head//2], x[..., self.d_head//2:]
return torch.cat([-x2, x1], dim=-1)
"""
RoPE 的外推性:
训练时: max_seq_len = 4096
推理时: 可以处理 > 4096 的序列 (外推)
但外推性能会下降
解决: NTK-aware Scaling, YaRN 等技术
NTK-aware Scaling:
调整 base 频率,使高频分量在外推时仍然有效
new_base = base * (scale_factor)^(d/(d-2))
"""
2.5 前馈网络(Feed-Forward Network, FFN)
FFN 的作用:
注意力层: 混合不同位置的信息
FFN 层: 对每个位置独立变换 (增加非线性)
标准 FFN:
FFN(x) = ReLU(x·W₁ + b₁)·W₂ + b₂
W₁ ∈ ℝ^{d×d_ff}, W₂ ∈ ℝ^{d_ff×d}
d_ff 通常 = 4 × d_model
SwiGLU (当前主流):
FFN(x) = (Swish(x·W₁) ⊙ x·W₃) · W₂
其中:
Swish(x) = x · σ(x)
⊙ 是逐元素乘法
理论:
GLU (Gated Linear Unit) 引入门控机制
Swish 激活比 ReLU 更平滑
效果通常优于标准 FFN
class SwiGLU(nn.Module):
"""
SwiGLU 前馈网络
FFN(x) = (Swish(x·W₁) ⊙ x·W₃) · W₂
理论:
GLU 门控: 一部分特征作为门,控制另一部分
Swish 激活: 比 ReLU 更平滑,梯度更好
优势:
- 更强的表达能力
- 训练更稳定
- 是 LLaMA, Mistral 等的默认选择
"""
def __init__(self, d_model, d_ff=None):
super().__init__()
if d_ff is None:
# LLaMA 使用 2/3 * 4 * d_model,再向上取整到 256 的倍数
d_ff = int(2 * d_model * 4 / 3)
d_ff = ((d_ff + 255) // 256) * 256
self.w1 = nn.Linear(d_model, d_ff, bias=False) # Gate projection
self.w2 = nn.Linear(d_ff, d_model, bias=False) # Down projection
self.w3 = nn.Linear(d_model, d_ff, bias=False) # Up projection
def forward(self, x):
# Swish(x·W₁) ⊙ (x·W₃)
gate = F.silu(self.w1(x)) # Swish = SiLU
up = self.w3(x)
return self.w2(gate * up)
"""
FFN 参数量:
标准 FFN: 2 × d × d_ff = 2 × d × 4d = 8d²
SwiGLU: 3 × d × d_ff = 3 × d × (8/3)d = 8d²
参数量相同,但 SwiGLU 效果更好
"""
2.6 归一化(Normalization)
LayerNorm vs RMSNorm:
LayerNorm:
LN(x) = γ · (x - μ) / √(σ² + ε) + β
μ = mean(x), σ² = var(x)
优点: 稳定训练
缺点: 计算 mean 和 var
RMSNorm (当前主流):
RMS(x) = √(mean(x²))
RMSNorm(x) = γ · x / RMS(x)
优点:
- 计算更简单 (不需要 mean)
- 效果与 LayerNorm 相当
- 训练更快
理论:
RMSNorm 假设均值为 0 (实践中近似成立)
只做缩放,不做偏移
class RMSNorm(nn.Module):
"""
RMSNorm 归一化
RMSNorm(x) = γ · x / √(mean(x²) + ε)
理论:
比 LayerNorm 更简单,计算更快
不需要减均值,只需要缩放
是 LLaMA, Mistral, Qwen 等的默认选择
"""
def __init__(self, d_model, eps=1e-6):
super().__init__()
self.weight = nn.Parameter(torch.ones(d_model))
self.eps = eps
def forward(self, x):
# RMS = √(mean(x²))
rms = torch.sqrt(torch.mean(x ** 2, dim=-1, keepdim=True) + self.eps)
# 归一化并缩放
x_norm = x / rms
return self.weight * x_norm
"""
Pre-Norm vs Post-Norm:
Post-Norm (原始 Transformer):
x = x + Attention(Norm(x))
x = x + FFN(Norm(x))
Pre-Norm (现代 LLM):
x = x + Attention(Norm(x))
x = x + FFN(Norm(x))
Pre-Norm 优势:
- 训练更稳定
- 梯度流更顺畅
- 不需要 warmup
- 是现代 LLM 的标准选择
"""
3. 预训练理论与策略
3.1 预训练目标
语言模型预训练的核心目标: 预测下一个 token
L = -E_{x~D}[Σ_t log P_θ(x_t | x_{<t})]
含义: 最小化负对数似然
等价于: 最大化数据的对数似然
为什么是"下一个 token"?
1. 自回归分解: 自然的序列建模方式
2. 无需标注: 文本本身就是标签
3. 通用性: 学会预测,就学会了语言理解
4. 涌现能力: 足够大的模型展现出推理、知识等能力
3.2 预训练数据
预训练数据的规模与质量:
规模:
GPT-3: ~300B tokens
LLaMA: ~1.4T tokens
LLaMA 2: ~2T tokens
Qwen: ~3T tokens
数据来源:
- Web 爬取 (Common Crawl): ~60%
- 书籍: ~15%
- 代码 (GitHub): ~10%
- 学术论文: ~5%
- 百科 (Wikipedia): ~3%
- 其他: ~7%
数据处理:
1. 去重 (Deduplication): 移除重复内容
2. 过滤 (Filtering): 移除低质量、有害内容
3. 打乱 (Shuffling): 随机化顺序
4. 混合 (Mixing): 按比例混合不同来源
数据质量 vs 数据数量:
理论:
Chinchilla 定律 (Hoffmann et al., 2022):
给定计算预算 C,最优的模型大小 N 和数据量 D 满足:
N ∝ C^0.5, D ∝ C^0.5
即: 参数量和数据量应该同比例增长
实践启示:
LLaMA-7B 使用 1T tokens (远超 Chinchilla 最优)
说明: 数据量多一些通常不会有害
数据质量的影响:
高质量数据 > 大量低质量数据
Phi 系列证明: 1.3B 参数 + 精选数据 ≈ 10B 参数 + 普通数据
3.3 训练超参数
┌─────────────────────────────────────────────────────────────────────┐
│ 预训练超参数 │
├─────────────────┬───────────────────────────────────────────────────┤
│ 超参数 │ 典型值与说明 │
├─────────────────┼───────────────────────────────────────────────────┤
│ 学习率 │ 1e-4 ~ 3e-4 │
│ │ 使用 Cosine Schedule + Warmup │
├─────────────────┼───────────────────────────────────────────────────┤
│ Batch Size │ 数百万 tokens │
│ │ 使用梯度累积达到有效大批量 │
├─────────────────┼───────────────────────────────────────────────────┤
│ 优化器 │ AdamW (β1=0.9, β2=0.95) │
│ │ 或 Adafactor (节省内存) │
├─────────────────┼───────────────────────────────────────────────────┤
│ 权重衰减 │ 0.1 │
├─────────────────┼───────────────────────────────────────────────────┤
│ 梯度裁剪 │ 1.0 │
├─────────────────┼───────────────────────────────────────────────────┤
│ Warmup │ 2000 步 │
├─────────────────┼───────────────────────────────────────────────────┤
│ 精度 │ BF16 (混合精度) │
│ │ 使用 Loss Scaling 防止下溢 │
├─────────────────┼───────────────────────────────────────────────────┤
│ 训练时长 │ 数周到数月 │
│ │ LLaMA-7B: ~21 天 (64 A100) │
└─────────────────┴───────────────────────────────────────────────────┘
3.4 Scaling Laws
Scaling Laws (缩放定律):
Kaplan et al. (2020) 发现:
模型性能 (loss) 与以下因素呈幂律关系:
L(N) ∝ N^(-0.076) --- 参数量
L(D) ∝ D^(-0.095) --- 数据量
L(C) ∝ C^(-0.050) --- 计算量
其中 L 是损失,N 是参数量,D 是数据量,C 是计算量
含义:
1. 更大的模型 → 更低的损失
2. 更多的数据 → 更低的损失
3. 更多的计算 → 更低的损失
4. 关系是幂律,没有饱和的迹象
Chinchilla 定律 (修正):
最优分配: N ∝ C^0.5, D ∝ C^0.5
即: 参数量和数据量应该同步增长
实践:
Chinchilla-70B: 70B 参数, 1.4T tokens
LLaMA-7B: 7B 参数, 1T tokens (数据更多)
对训练的指导:
1. 确定计算预算
2. 根据 Scaling Laws 选择模型大小和数据量
3. 训练更大、更多的模型通常更好
4. 微调与对齐技术
4.1 微调概述
预训练 vs 微调:
预训练 (Pre-training):
- 目标: 学习语言知识
- 数据: 大规模无标注文本
- 计算: 极大 (数千 GPU, 数周)
- 结果: 基础模型 (Base Model)
微调 (Fine-tuning):
- 目标: 适应特定任务或对齐人类偏好
- 数据: 小规模有标注数据
- 计算: 较小 (数 GPU, 数小时)
- 结果: 微调后模型 (Chat Model)
微调类型:
1. 指令微调 (Instruction Tuning)
2. RLHF (人类反馈强化学习)
3. DPO (直接偏好优化)
4. 参数高效微调 (LoRA, QLoRA)
4.2 指令微调(Instruction Tuning / SFT)
目标: 让模型学会遵循指令
数据格式:
{
"instruction": "请解释什么是机器学习",
"input": "",
"output": "机器学习是人工智能的一个分支..."
}
或对话格式:
{
"conversations": [
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "你好!有什么可以帮助你的吗?"}
]
}
训练目标:
只在 assistant 回复上计算损失
不在 user 输入上计算损失
L = -Σ_{t ∈ assistant} log P_θ(a_t | context)
理论:
让模型学会"给定指令,生成回复"
而非"预测所有文本"
4.3 RLHF(Reinforcement Learning from Human Feedback)
RLHF 流程:
阶段 1: 监督微调 (SFT)
使用高质量的指令-回复对微调模型
阶段 2: 训练奖励模型 (Reward Model)
收集人类偏好数据: 对于同一指令,人类选择更好的回复
训练奖励模型: R(x, y) → 标量分数
损失: L = -log σ(R(x, y_win) - R(x, y_lose))
阶段 3: 强化学习优化 (PPO)
使用 PPO 算法优化策略模型
目标: max E_{y~π_θ}[R(x, y)] - β·KL(π_θ ‖ π_ref)
其中:
π_θ: 当前策略
π_ref: 参考策略 (SFT 模型)
β: KL 惩罚系数
KL 惩罚的作用:
防止模型过度优化奖励 (reward hacking)
保持与参考模型的相似性
class PPOTrainer:
"""
PPO (Proximal Policy Optimization) 训练器
理论:
策略梯度方法,限制每步更新幅度
目标: max E[min(r_t·A_t, clip(r_t, 1-ε, 1+ε)·A_t)]
其中:
r_t = π_θ(a|s) / π_old(a|s) (概率比)
A_t: 优势函数估计
ε: 裁剪范围 (通常 0.2)
"""
def __init__(self, policy_model, ref_model, reward_model,
kl_coef=0.1, clip_range=0.2):
self.policy = policy_model
self.ref = ref_model
self.reward = reward_model
self.kl_coef = kl_coef
self.clip_range = clip_range
def compute_rewards(self, prompts, responses):
"""
计算奖励
总奖励 = 奖励模型分数 - KL 惩罚
"""
# 奖励模型分数
rm_scores = self.reward(prompts, responses)
# KL 惩罚
with torch.no_grad():
policy_logps = self.policy.log_prob(prompts, responses)
ref_logps = self.ref.log_prob(prompts, responses)
kl = policy_logps - ref_logps
# 总奖励
rewards = rm_scores - self.kl_coef * kl
return rewards
def ppo_step(self, batch):
"""
PPO 训练步骤
1. 采样回复
2. 计算奖励
3. 估计优势
4. PPO 更新
"""
# 采样
responses = self.policy.generate(batch['prompts'])
# 计算奖励
rewards = self.compute_rewards(batch['prompts'], responses)
# 估计优势 (GAE)
advantages = self.compute_gae(rewards)
# PPO 更新
for _ in range(self.ppo_epochs):
# 计算概率比
new_logps = self.policy.log_prob(batch['prompts'], responses)
old_logps = self.old_logps
ratio = torch.exp(new_logps - old_logps)
# 裁剪目标
surr1 = ratio * advantages
surr2 = torch.clamp(ratio, 1 - self.clip_range, 1 + self.clip_range) * advantages
policy_loss = -torch.min(surr1, surr2).mean()
# 更新
self.optimizer.zero_grad()
policy_loss.backward()
self.optimizer.step()
4.4 DPO(Direct Preference Optimization)
论文: "Direct Preference Optimization: Your Language Model is Secretly a Reward Model"
(Rafailov et al., 2023)
核心思想:
不需要显式训练奖励模型
直接从偏好数据优化策略
理论推导:
RLHF 的目标:
max E[R(x, y)] - β·KL(π ‖ π_ref)
最优解:
π*(y|x) = π_ref(y|x) · exp(R(x,y)/β) / Z(x)
可以反解出隐式奖励:
R(x, y) = β · log(π*(y|x) / π_ref(y|x)) + β·log Z(x)
代入 Bradley-Terry 偏好模型:
P(y_win > y_lose) = σ(R(x, y_win) - R(x, y_lose))
得到 DPO 损失:
L_DPO = -log σ(β · log(π_θ(y_win|x)/π_ref(y_win|x))
- β · log(π_θ(y_lose|x)/π_ref(y_lose|x)))
class DPOTrainer:
"""
DPO (Direct Preference Optimization) 训练器
理论:
直接从偏好数据优化策略
无需训练奖励模型
无需 RL 训练循环
损失:
L = -log σ(β · [log π(y_win)/π_ref(y_win) - log π(y_lose)/π_ref(y_lose)])
"""
def __init__(self, model, ref_model, beta=0.1):
self.model = model
self.ref = ref_model
self.beta = beta
def dpo_loss(self, prompts, y_win, y_lose):
"""
计算 DPO 损失
prompts: 输入指令
y_win: 人类偏好的回复
y_lose: 人类不偏好的回复
"""
# 计算策略模型的 log 概率
log_pi_win = self.model.log_prob(prompts, y_win)
log_pi_lose = self.model.log_prob(prompts, y_lose)
# 计算参考模型的 log 概率
with torch.no_grad():
log_ref_win = self.ref.log_prob(prompts, y_win)
log_ref_lose = self.ref.log_prob(prompts, y_lose)
# 计算隐式奖励差
logits = self.beta * (
(log_pi_win - log_ref_win) - (log_pi_lose - log_ref_lose)
)
# DPO 损失
loss = -F.logsigmoid(logits).mean()
return loss
"""
DPO vs RLHF 对比:
RLHF:
需要训练奖励模型
需要 PPO 训练循环
训练复杂,不稳定
但可以在线采样
DPO:
无需奖励模型
无需 RL 循环
训练简单,稳定
只需离线偏好数据
实践中 DPO 更常用
"""
4.5 参数高效微调(PEFT)
LoRA(Low-Rank Adaptation)
论文: "LoRA: Low-Rank Adaptation of Large Language Models" (Hu et al., 2021)
核心思想:
冻结原始模型参数
添加低秩分解的增量矩阵
W = W₀ + ΔW = W₀ + B·A
其中:
W₀ ∈ ℝ^{d×k}: 原始权重 (冻结)
B ∈ ℝ^{d×r}: 低秩矩阵
A ∈ ℝ^{r×k}: 低秩矩阵
r << min(d, k): 秩 (通常 8-64)
理论基础:
大模型的权重更新通常是低秩的
即 ΔW 可以用低秩矩阵近似
参数量: 原始 d×k → LoRA 2×d×r
当 r=16, d=k=4096 时: 4096² → 2×4096×16 = 131K (减少 99.5%)
class LoRALinear(nn.Module):
"""
LoRA 低秩适配层
W = W₀ + B·A
理论:
冻结原始权重 W₀
只训练低秩增量 B·A
大幅减少可训练参数
"""
def __init__(self, original_layer, rank=16, alpha=32):
super().__init__()
self.original = original_layer
self.original.weight.requires_grad_(False)
d_out, d_in = original_layer.weight.shape
# 低秩矩阵
self.lora_A = nn.Parameter(torch.randn(rank, d_in) * 0.01)
self.lora_B = nn.Parameter(torch.zeros(d_out, rank))
self.rank = rank
self.alpha = alpha
self.scaling = alpha / rank
def forward(self, x):
# 原始输出
original_output = self.original(x)
# LoRA 增量
lora_output = (x @ self.lora_A.T @ self.lora_B.T) * self.scaling
return original_output + lora_output
def merge(self):
"""合并 LoRA 到原始权重 (推理时)"""
self.original.weight.data += (self.lora_B @ self.lora_A) * self.scaling
"""
LoRA 应用位置:
- QKV 投影 (W_Q, W_K, W_V)
- 输出投影 (W_O)
- FFN (W1, W2, W3)
通常只在注意力层应用
效果与全参数微调相当
"""
QLoRA
论文: "QLoRA: Efficient Finetuning of Quantized Language Models" (Dettmers et al., 2023)
核心创新:
1. 4-bit 量化基础模型 (NF4)
2. LoRA 微调
3. 双重量化 (Double Quantization)
4. 分页优化器 (Paged Optimizer)
内存节省:
LLaMA-7B:
FP16 全参数微调: ~56 GB
QLoRA (4-bit): ~6 GB
使得单卡 24GB 可以微调 33B 模型
5. 推理与解码策略
5.1 自回归生成
自回归生成过程:
给定 prompt: "今天天气"
Step 1: P("好" | "今天天气") = 0.3
P("很" | "今天天气") = 0.2
P("不" | "今天天气") = 0.15
...
选择: "很"
Step 2: P("好" | "今天天气很") = 0.6
P("热" | "今天天气很") = 0.2
...
选择: "好"
Step 3: P("。" | "今天天气很好") = 0.7
P("," | "今天天气很好") = 0.1
...
选择: "。"
输出: "今天天气很好。"
关键参数:
- temperature: 控制随机性
- top_k: 只从概率最高的 k 个 token 中采样
- top_p: 从累积概率达到 p 的最小集合中采样
- do_sample: 是否使用采样 (否则使用贪心)
5.2 解码策略详解
┌─────────────────────────────────────────────────────────────────────┐
│ 解码策略对比 │
├───────────────┬─────────────────────────────────────────────────────┤
│ 策略 │ 描述 │
├───────────────┼─────────────────────────────────────────────────────┤
│ Greedy │ 每步选概率最高的 token │
│ │ 确定性,但可能不是全局最优 │
├───────────────┼─────────────────────────────────────────────────────┤
│ Beam Search │ 保留 top-k 个候选序列 │
│ │ 更好的全局最优,但计算量大 │
├───────────────┼─────────────────────────────────────────────────────┤
│ Temperature │ 调整 logits 的温度 │
│ │ T<1: 更确定; T>1: 更随机 │
├───────────────┼─────────────────────────────────────────────────────┤
│ Top-K │ 只从概率最高的 K 个 token 中采样 │
│ │ 过滤低概率 token │
├───────────────┼─────────────────────────────────────────────────────┤
│ Top-P │ 从累积概率达到 P 的最小集合中采样 │
│ │ 动态截断,比 Top-K 更灵活 │
├───────────────┼─────────────────────────────────────────────────────┤
│ Min-P │ 只保留概率 > p × max_prob 的 token │
│ │ 相对阈值,自适应 │
├───────────────┼─────────────────────────────────────────────────────┤
│ Repetition │ 惩罚重复 token │
│ Penalty │ 降低已出现 token 的概率 │
└───────────────┴─────────────────────────────────────────────────────┘
class SamplingStrategies:
"""采样策略集合"""
@staticmethod
def temperature_scaling(logits, temperature=1.0):
"""
温度缩放
P(token) = softmax(logits / T)
T < 1: 分布更尖锐 (更确定)
T = 1: 原始分布
T > 1: 分布更平坦 (更随机)
T → 0: 退化为贪心
T → ∞: 退化为均匀分布
"""
return logits / temperature
@staticmethod
def top_k_sampling(logits, k=50):
"""
Top-K 采样
只保留概率最高的 K 个 token
其他 token 概率设为 -∞
"""
values, indices = torch.topk(logits, k)
# 将非 top-k 的位置设为 -inf
logits[logits < values[:, -1:]] = float('-inf')
return logits
@staticmethod
def top_p_sampling(logits, p=0.9):
"""
Top-P (Nucleus) 采样
按概率降序排列
保留累积概率达到 P 的最小集合
理论:
动态截断
当分布尖锐时,只保留少数 token
当分布平坦时,保留更多 token
"""
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
cumulative_probs = torch.cumsum(F.softmax(sorted_logits, dim=-1), dim=-1)
# 找到累积概率超过 p 的位置
sorted_mask = cumulative_probs - F.softmax(sorted_logits, dim=-1) >= p
sorted_logits[sorted_mask] = float('-inf')
# 恢复原始顺序
logits.scatter_(1, sorted_indices, sorted_logits)
return logits
@staticmethod
def min_p_sampling(logits, min_p=0.1):
"""
Min-P 采样
只保留概率 > min_p × max_prob 的 token
理论:
相对阈值,自适应于分布的尖锐程度
比 Top-P 更稳定
"""
probs = F.softmax(logits, dim=-1)
max_prob = probs.max(dim=-1, keepdim=True).values
threshold = min_p * max_prob
mask = probs < threshold
logits[mask] = float('-inf')
return logits
"""
推荐参数组合:
代码生成:
temperature=0.2, top_p=0.95
(需要确定性)
创意写作:
temperature=0.8, top_p=0.9
(需要多样性)
对话:
temperature=0.7, top_p=0.9, repetition_penalty=1.1
(平衡质量和多样性)
翻译:
temperature=0.3, top_p=0.95
(需要准确性)
"""
5.3 KV Cache
KV Cache 的原理:
自回归生成时,每一步都需要计算所有位置的注意力
问题: 重复计算
Step 1: 计算 K₁, V₁
Step 2: 计算 K₁, K₂, V₁, V₂ (重复计算 K₁, V₁)
Step 3: 计算 K₁, K₂, K₃, V₁, V₂, V₃ (重复计算更多)
解决: 缓存历史的 K 和 V
Step 1: 计算 K₁, V₁, 缓存
Step 2: 从缓存读取 K₁, V₁, 只计算 K₂, V₂, 缓存
Step 3: 从缓存读取 K₁, K₂, V₁, V₂, 只计算 K₃, V₃, 缓存
效果: 每步只计算当前 token 的 K, V
时间复杂度从 O(n²) 降到 O(n)
class KVCache:
"""
KV Cache
理论:
缓存历史的 Key 和 Value
避免重复计算
内存占用:
2 × n_layers × n_heads × d_head × seq_len × batch_size × dtype_size
LLaMA-7B, seq_len=4096, FP16:
2 × 32 × 32 × 128 × 4096 × 1 × 2 = 2.1 GB
"""
def __init__(self, max_batch_size, max_seq_len, n_heads, d_head, n_layers):
self.max_seq_len = max_seq_len
# 预分配缓存
self.key_cache = torch.zeros(
n_layers, max_batch_size, n_heads, max_seq_len, d_head
)
self.value_cache = torch.zeros(
n_layers, max_batch_size, n_heads, max_seq_len, d_head
)
self.current_len = 0
def update(self, layer_idx, new_key, new_value):
"""更新缓存"""
batch_size, n_heads, seq_len, d_head = new_key.shape
self.key_cache[layer_idx, :batch_size, :, self.current_len:self.current_len+seq_len] = new_key
self.value_cache[layer_idx, :batch_size, :, self.current_len:self.current_len+seq_len] = new_value
if layer_idx == 0:
self.current_len += seq_len
def get(self, layer_idx, batch_size):
"""获取缓存"""
return (
self.key_cache[layer_idx, :batch_size, :, :self.current_len],
self.value_cache[layer_idx, :batch_size, :, :self.current_len]
)
"""
KV Cache 的内存优化:
问题: 长序列的 KV Cache 占用大量显存
解决方案:
1. GQA (Grouped Query Attention): 减少 K, V 的头数
2. MQA (Multi-Query Attention): K, V 只有 1 个头
3. 量化 KV Cache: 使用低精度存储
4. 滑动窗口: 只缓存最近的窗口
5. PagedAttention: 按需分配内存 (vLLM)
"""
6. 上下文与长序列技术
6.1 上下文长度的挑战
上下文长度的限制:
标准自注意力: O(n²) 时间和空间复杂度
当 n = 128K tokens:
注意力矩阵: 128K × 128K = 16.4B 个元素
FP16 存储: 16.4B × 2 bytes = 32.8 GB
这只是单层单头!
实际: 32 层 × 32 头 × 32.8 GB = 33.6 TB (完全不可行)
解决方案:
1. FlashAttention: IO 感知的精确注意力
2. 稀疏注意力: 只计算部分注意力
3. 线性注意力: O(n) 复杂度
4. 位置编码外推: RoPE + NTK-aware scaling
6.2 FlashAttention
论文: "FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness"
(Dao et al., 2022)
核心思想:
不是近似注意力,而是精确计算
通过 IO 感知的算法减少内存访问
技术细节:
标准注意力: 需要存储完整的 n×n 注意力矩阵
FlashAttention: 分块计算
1. 将 Q, K, V 分成小块
2. 逐块计算注意力
3. 使用在线 softmax 技巧,无需存储完整矩阵
内存: O(n) 而非 O(n²)
速度: 2-4 倍加速 (减少 HBM 访问)
6.3 GQA 与 MQA
Multi-Head Attention (MHA):
Q: h 个头
K: h 个头
V: h 个头
KV Cache: h × d_head × seq_len
Grouped Query Attention (GQA):
Q: h 个头
K: h/g 个头 (g 组)
V: h/g 个头
每 g 个 Q 头共享 1 个 K, V 头
KV Cache: (h/g) × d_head × seq_len
Multi-Query Attention (MQA):
Q: h 个头
K: 1 个头
V: 1 个头
所有 Q 头共享 1 个 K, V 头
KV Cache: 1 × d_head × seq_len
理论:
GQA 是 MHA 和 MQA 的折中
KV Cache 减少 g 倍
质量损失很小
LLaMA 2 70B 使用 GQA (g=8)
Mistral 使用 GQA
7. 高效训练与推理技术
7.1 混合精度训练
混合精度 (Mixed Precision):
FP32: 32 位浮点 (标准精度)
FP16: 16 位浮点 (半精度)
BF16: Brain Float 16 (Google 提出)
FP8: 8 位浮点 (最新)
BF16 vs FP16:
FP16: 1 符号 + 5 指数 + 10 尾数
范围: ±65504
问题: 容易溢出/下溢
BF16: 1 符号 + 8 指数 + 7 尾数
范围: 与 FP32 相同
精度: 略低于 FP16
优势: 不需要 Loss Scaling
现代 LLM 几乎都使用 BF16
训练流程:
1. 前向传播: BF16
2. 损失计算: FP32
3. 反向传播: BF16
4. 参数更新: FP32 (主权重)
7.2 分布式训练
分布式训练策略:
1. 数据并行 (Data Parallelism, DP):
每个 GPU 有完整模型副本
数据分片,梯度同步
2. 模型并行 (Model Parallelism):
张量并行 (Tensor Parallelism, TP):
将单个层的权重分片到多个 GPU
流水线并行 (Pipeline Parallelism, PP):
将不同层分配到不同 GPU
3. ZeRO (Zero Redundancy Optimizer):
ZeRO-1: 分片优化器状态
ZeRO-2: 分片优化器状态 + 梯度
ZeRO-3: 分片优化器状态 + 梯度 + 参数
4. FSDP (Fully Sharded Data Parallelism):
PyTorch 原生的完全分片数据并行
类似 ZeRO-3
7.3 模型量化
量化 (Quantization):
将模型权重从高精度 (FP16/BF16) 转换为低精度 (INT8/INT4)
理论:
权重分布通常近似正态分布
可以用更少的比特表示
量化方法:
1. 对称量化: q = round(x / scale)
2. 非对称量化: q = round((x - zero_point) / scale)
常见精度:
INT8: 8 位整数 (2x 压缩)
INT4: 4 位整数 (4x 压缩)
GPTQ: 4 位量化 + 误差补偿
AWQ: 4 位量化 + 激活感知
GGUF: CPU 推理友好格式
8. 评估与能力分析
8.1 评估基准
┌─────────────────────────────────────────────────────────────────────┐
│ LLM 评估基准 │
├─────────────────┬───────────────────────────────────────────────────┤
│ 基准 │ 评估内容 │
├─────────────────┼───────────────────────────────────────────────────┤
│ MMLU │ 多任务语言理解 (57 个学科) │
├─────────────────┼───────────────────────────────────────────────────┤
│ HumanEval │ 代码生成 (Python 函数) │
├─────────────────┼───────────────────────────────────────────────────┤
│ GSM8K │ 数学推理 (小学数学应用题) │
├─────────────────┼───────────────────────────────────────────────────┤
│ HellaSwag │ 常识推理 │
├─────────────────┼───────────────────────────────────────────────────┤
│ TruthfulQA │ 真实性问答 │
├─────────────────┼───────────────────────────────────────────────────┤
│ ARC │ 科学推理 │
├─────────────────┼───────────────────────────────────────────────────┤
│ MT-Bench │ 多轮对话质量 (GPT-4 评分) │
├─────────────────┼───────────────────────────────────────────────────┤
│ AlpacaEval │ 指令遵循 (GPT-4 评分) │
├─────────────────┼───────────────────────────────────────────────────┤
│ Chatbot Arena │ 人类偏好排名 (ELO 评分) │
└─────────────────┴───────────────────────────────────────────────────┘
8.2 涌现能力
涌现能力 (Emergent Abilities):
定义: 在小模型中不存在,但在大模型中突然出现的能力
理论:
当模型规模超过某个阈值时
某些能力会突然出现 (非线性增长)
例子:
- 少样本学习 (Few-shot Learning)
- 思维链推理 (Chain-of-Thought)
- 代码生成
- 指令遵循
争议:
一些研究认为涌现是评估指标的伪影
使用连续指标时,能力可能是平滑增长的
8.3 思维链(Chain-of-Thought, CoT)
Chain-of-Thought (CoT):
标准提示:
Q: Roger 有 5 个网球,他又买了 2 罐,每罐 3 个。他现在有多少个?
A: 11
CoT 提示:
Q: Roger 有 5 个网球,他又买了 2 罐,每罐 3 个。他现在有多少个?
A: Roger 开始有 5 个球。2 罐 3 个 = 6 个球。5 + 6 = 11。答案是 11。
理论:
让模型"思考"中间步骤
将复杂推理分解为简单步骤
显著提升数学和推理任务性能
变体:
- Zero-shot CoT: "Let's think step by step"
- Few-shot CoT: 提供 CoT 示例
- Self-Consistency: 多次采样取多数
- Tree-of-Thought: 树形推理
9. 多模态与智能体
9.1 多模态大模型
多模态大模型 (Multimodal LLM):
架构:
视觉编码器 → 投影层 → LLM → 文本输出
代表模型:
- GPT-4V: 文本 + 图像
- LLaVA: 开源多模态
- Qwen-VL: 通义千问视觉版
训练:
阶段 1: 预训练投影层 (对齐视觉和语言)
阶段 2: 指令微调 (视觉问答)
9.2 LLM 作为智能体
LLM Agent:
核心能力:
1. 规划 (Planning): 分解复杂任务
2. 工具使用 (Tool Use): 调用外部工具
3. 记忆 (Memory): 存储和检索信息
4. 反思 (Reflection): 自我评估和改进
框架:
ReAct: Reasoning + Acting
Reflexion: 自我反思
AutoGPT: 自主任务执行
10. 术语速查表
A. 基础术语
| 术语 |
英文 |
定义 |
| 语言模型 |
Language Model (LM) |
建模文本概率分布的模型 |
| 自回归 |
Autoregressive |
逐个 token 生成 |
| Token |
Token |
文本的最小处理单位 |
| 词表 |
Vocabulary |
所有可能 token 的集合 |
| 嵌入 |
Embedding |
将 token 映射为向量 |
| 上下文 |
Context |
模型能看到的文本 |
| 提示 |
Prompt |
输入给模型的文本 |
| 补全 |
Completion |
模型生成的输出 |
| 推理 |
Inference |
使用模型生成 |
| 训练 |
Training |
学习模型参数 |
B. 架构术语
| 术语 |
英文 |
定义 |
| Transformer |
Transformer |
基于注意力的架构 |
| 自注意力 |
Self-Attention |
序列内部的注意力 |
| 多头注意力 |
Multi-Head Attention |
多个并行的注意力头 |
| 因果掩码 |
Causal Mask |
防止看到未来 token |
| 位置编码 |
Positional Encoding |
编码位置信息 |
| RoPE |
Rotary Position Embedding |
旋转位置编码 |
| FFN |
Feed-Forward Network |
前馈网络 |
| SwiGLU |
SwiGLU |
门控激活函数 |
| RMSNorm |
RMSNorm |
均方根归一化 |
| 残差连接 |
Residual Connection |
跳跃连接 |
C. 训练术语
| 术语 |
英文 |
定义 |
| 预训练 |
Pre-training |
大规模无监督训练 |
| 微调 |
Fine-tuning |
任务特定的训练 |
| SFT |
Supervised Fine-Tuning |
监督微调 |
| RLHF |
RL from Human Feedback |
人类反馈强化学习 |
| DPO |
Direct Preference Optimization |
直接偏好优化 |
| LoRA |
Low-Rank Adaptation |
低秩适配 |
| 学习率 |
Learning Rate |
参数更新步长 |
| 批量大小 |
Batch Size |
每次训练的样本数 |
| 梯度 |
Gradient |
损失函数的导数 |
| 损失 |
Loss |
训练目标函数 |
D. 推理术语
| 术语 |
英文 |
定义 |
| 采样 |
Sampling |
从概率分布中抽取 |
| 贪心 |
Greedy |
每步选最高概率 |
| 束搜索 |
Beam Search |
保留多个候选 |
| 温度 |
Temperature |
控制随机性 |
| Top-K |
Top-K |
只从 K 个候选采样 |
| Top-P |
Top-P |
从累积概率 P 的集合采样 |
| KV Cache |
KV Cache |
缓存 Key-Value |
| 量化 |
Quantization |
降低权重精度 |
| 推测解码 |
Speculative Decoding |
使用小模型加速 |
E. 评估术语
| 术语 |
英文 |
定义 |
| 涌现 |
Emergence |
规模增大后突然出现的能力 |
| 幻觉 |
Hallucination |
生成虚假信息 |
| 对齐 |
Alignment |
符合人类价值观 |
| CoT |
Chain-of-Thought |
思维链推理 |
| Few-shot |
Few-shot |
少样本学习 |
| Zero-shot |
Zero-shot |
零样本学习 |
| Perplexity |
Perplexity |
语言模型评估指标 |
| BLEU |
BLEU |
翻译质量指标 |
| ROUGE |
ROUGE |
摘要质量指标 |