LLM 算法岗 | 八股问答(2)· 大模型训练流程与微调技术
完整题库链接:LLM 算法岗 | 面试常问的 LLM 八股题目汇总
- 1. 从 txt 文本预处理到 SFT 训练的全流程
- 2. Pretrain、SFT、RLHF 的区别
- 3. Pretrain 和 SFT 优化目标的区别
- 4. SFT 核心流程及数据集构建策略
- 5. SFT 的 Loss 及多 Token 计算
- 6. SFT 与预训练样本 Loss 计算区别及屏蔽方法
- 7. SFT Loss 计算代码(含 shift right)
- 8. SFT 之后的常见 Post-Training 及目的区别
- 9. 为什么 SFT 后还要做 RL?为何偏好对齐不能用偏好数据直接做 SFT?
- 10. LoRA 的核心原理
- 11. 秩 \(r\) 的选择对模型表现的影响及选择方法
- 12. LoRA 是否只能嵌入 Linear 层?为什么不能插在 LayerNorm 之后?对训练稳定性有什么影响?
- 13. LoRA 微调推理时是否要挂着 Adaptor?合并 Adapter 权重时有没有遇到梯度爆炸?
- 14. QLoRA 降低资源成本的机制、量化方式、NF4 和 FP16 组合原因及 NF4 分布拟合逻辑
- 15. 训练 LoRA 模型时,如何选择冻结层?依据是什么?
- 16. Tokenizer 是怎么做的?有哪些实现方式?
- 17. Embedding 是怎么做的?从 ID 到 Embedding 有哪些实现方式?
- 18. 控制模型生成多样性的参数有哪些?如何控制?
- 19. top-k 与 top-p 的区别?除了贪心,还有哪些生成策略?
- 20. 介绍一下常见的优化算法优缺点。为什么 Adam 不一定最优而 SGD 最优?怎么理解分析?
- 21. 怎么解决模型的冷启动问题?LLM 在冷启动方面能够起到什么作用?
- 22. 大模型幻觉是什么?怎么缓解大模型幻觉?
- 面试背诵要点(仅供参考)
1. 从 txt 文本预处理到 SFT 训练的全流程
步骤详解:
- 文本预处理:
- 清洗原始文本,去除无关字符、HTML 标签、乱码、去重等;质量过滤:基于规则(长度、乱码率)+ 基于模型(困惑度打分)筛选;
- 统一编码和格式;可能进行句子分割或段落划分;
- 对于多轮对话数据,需结构化处理,构建 JSON / Parquet 格式,比如统一为 {"instruction": "...", "input": "...", "output": "..."} 或对话格式。
- Tokenization:
- 使用分词器(如 BPE、SentencePiece)将文本转换为 token IDs,添加特殊 token(如
[BOS]、[EOS]、[PAD])。 - 对话模板(Chat Template):不同模型格式不同(Llama-3、Qwen、ChatGLM 等)。
- 使用分词器(如 BPE、SentencePiece)将文本转换为 token IDs,添加特殊 token(如
- 构建输入:
max_length截断,将 token IDs 序列进行 padding 至统一长度,padding="max_length"或padding="longest"(batch 内动态),生成input_ids;- 创建
attention_mask标识有效 token,区分 pad token(mask=0)和真实 token(mask=1); - 构造
labels,其中 prompt 部分设为忽略索引(如 -100),response 部分为对应的 token IDs。
- Forward:
- 将
input_ids和attention_mask输入模型,得到logits,形状为[batch_size, seq_len, vocab_size]。
- 将
- Loss 计算:
- 采用交叉熵损失,通常需要 shift right:用当前 token 预测下一个 token,即取
logits[:, :-1, :]和labels[:, 1:],然后计算损失,忽略labels中为 -100 的位置。
- 采用交叉熵损失,通常需要 shift right:用当前 token 预测下一个 token,即取
- 参数更新:
- 反向传播计算梯度,使用优化器(如 AdamW)更新模型参数,常配合学习率调度、梯度裁剪等技巧。
2. Pretrain、SFT、RLHF 的区别
| 维度 | Pretrain(预训练) | SFT(监督微调) | RLHF(人类反馈强化学习) |
|---|---|---|---|
| 目标 | 学习通用语言表示和世界知识 | 学习指令遵循 + 任务格式 | 对齐人类偏好(有用、无害、诚实) |
| 数据 | 海量无标注文本(网页、书籍、代码) | 高质量指令-输出对(数十万到数百万) | 偏好对/排序数据(A > B) |
| 任务定位 | 自监督学习,next token prediction;基础模型构建 | 有监督学习,条件生成;任务适配 / 对话能力培养 | 强化学习,优化奖励函数;价值观对齐 |
| 解决问题 | "模型会说话",从海量无标注文本中获取语言能力 | "模型听指令",让模型理解人类意图,输出符合期望的内容 | "模型说得好",纠正模型生成中不符合人类偏好的行为 |
| Loss | 纯交叉熵(所有 token) | 交叉熵(通常只算 answer 部分) | PPO / DPO 等(基于奖励模型) |
3. Pretrain 和 SFT 优化目标的区别
Pretrain:优化目标是自回归语言建模损失,即最大化整个序列中每个 token 的条件概率(通常忽略部分 token 如 mask)。学习文本的统计分布。
- 目标:$ \max_\theta \sum_{t=1}^{T} \log P_\theta(x_t | x_{<t}) $
- 特点:所有 token 都算 loss,无差别对待
- 本质:无条件的概率建模,学习 \(P(X)\)
SFT:优化目标是条件语言建模损失,即在给定指令下最大化目标回答的似然,损失仅计算 response 部分,不计算 prompt 部分。本质是让模型学会“回答问题”而非“预测所有文本”。
- 目标:$ \max_\theta \sum_{t=1}^{T} \log P_\theta(y_t | x, y_{<t}) $
- 特点:通常只计算 answer / output 部分的 loss,prompt 部分 mask 掉
- 本质:条件生成,学习 \(P(Y|X)\),优化指令遵循能力
核心差异:Pretrain 是无条件密度估计,SFT 是条件生成,且 SFT 通过 mask prompt 实现聚焦学习(不让模型浪费容量去学 prompt 的分布)。
4. SFT 核心流程及数据集构建策略
核心流程:
- 收集人工标注的(指令,回答)对。
- 清洗数据(去重、过滤低质 / 有毒内容、格式统一)。
- 格式化拼接指令和回答,添加角色标识(应用 Chat Template)。
- 分词(Tokenize)、构建 labels(prompt 部分设为 -100)。
- 微调模型(通常用较小学习率,1-3 个 epoch,lr 1e-5 ~ 5e-5,冻结部分层可选)。
- 验证 / 评测(MT-Bench、人工评估)
数据集构建策略:
- 多样性:覆盖不同领域、任务类型(问答、写作、翻译、推理等),避免单一分布。
- 质量:回答需准确、有用、无害,经人工审核或众包,可结合规则过滤和模型辅助筛选。
- 平衡:控制各类别比例,防止模型偏向某类任务。
- 难度分布:简单:中等:困难 ≈ 3:5:2,避免全是难题导致收敛慢。包含简单和复杂指令,逐步提升模型能力。
- 长度分布:短(<1k)、中(1k-4k)、长(>4k)混合,防止长度偏见。
5. SFT 的 Loss 及多 Token 计算
SFT 的 Loss 为交叉熵损失,计算模型对每个 token 预测的概率与真实 token 的差异。若 target 有 N 个 token,则损失是这 N 个 token 的交叉熵的平均值(或求和,通常取平均)。
实现时,通过设置 ignore_index(如 -100)忽略非 target 部分。
具体的,假设 prompt 有 \(L_p\) 个 token,answer 有 \(L_a\) 个 token(\(L_a\) = 10 或 100):
Full sequence: [P1, P2, ..., P_Lp, A1, A2, ..., A_La]
↑ prompt部分 ↑ answer部分(只算这些的loss)
计算步骤:
- Forward 得到 logits:
[batch, seq_len, vocab_size] - Shift right:logits 去掉最后一个,labels 去掉第一个
- Mask prompt:将 prompt 对应位置的 labels 设为
-100(ignore_index) - 只在 answer 部分计算 CE Loss
公式:$$ \mathcal{L} = -\frac{1}{L_a} \sum_{t=L_p+1}^{L_p+L_a} \log P_\theta(a_t | x, a_{<t}) $$
注意这个 loss -平均到每个 token**,最终 loss 是标量(mean over valid tokens)。序列长只是求和的项多,但除的也是 \(L_a\),所以不同长度样本的 loss 量级可比。
(所以在这个角度来说,SFT 是 offline 的,SFT 是 behavior cloning;RL PPO GRPO 等是 online 的)
交叉熵损失公式:
二分类交叉熵损失:
其中:
- $ y \in {0, 1} $ 是真实标签
- $ p \in (0, 1) $ 是模型预测为正类的概率
多分类交叉熵损失:
其中:
- $ C $ 是类别数
- $ y_i $ 是真实标签的 one-hot 编码
- $ p_i $ 是模型预测为第 $ i $ 类的概率
6. SFT 与预训练样本 Loss 计算区别及屏蔽方法
- 区别:预训练样本对整个序列计算损失(所有 token 参与),SFT 仅对response部分计算损失。
- 屏蔽方法:在
labels中将 prompt 对应位置设为特定的忽略索引(如 -100),损失函数自动忽略这些位置。
7. SFT Loss 计算代码(含 shift right)
import torch
import torch.nn.functional as F
from torch.nn import CrossEntropyLoss
def compute_sft_loss(logits, labels, ignore_index=-100):
"""
logits: [batch_size, seq_len, vocab_size] # 模型输出
labels: [batch_size, seq_len] # 目标 token IDs,prompt部分为-100
"""
# 1. Shift right:模型预测第 t 个,对应 label 第 t+1 个
shift_logits = logits[..., :-1, :].contiguous() # [batch, seq_len-1, vocab]
shift_labels = labels[..., 1:].contiguous() # [batch, seq_len-1]
# 2. Flatten
shift_logits = shift_logits.view(-1, shift_logits.size(-1)) # [(batch*(seq-1)), vocab]
shift_labels = shift_labels.view(-1) # [batch*(seq-1)]
# 3. 计算 loss,自动忽略 -100 的位置
loss_fct = CrossEntropyLoss(ignore_index=ignore_index, reduction='mean')
loss = loss_fct(shift_logits, shift_labels)
return loss
# ========== 完整训练步骤示例 ==========
def sft_train_step(model, batch, optimizer):
input_ids = batch['input_ids'] # [batch, seq_len]
attention_mask = batch['attention_mask']
labels = batch['labels'] # prompt部分为-100,answer部分为真实token id
# Forward
outputs = model(input_ids=input_ids, attention_mask=attention_mask)
logits = outputs.logits # [batch, seq_len, vocab_size]
# 计算 loss(注意:模型已经 shift 过,但 logits 和 labels 需要手动 align)
loss = compute_sft_loss(logits, labels)
# Backward
optimizer.zero_grad()
loss.backward()
# Gradient clipping(防止梯度爆炸)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
return loss.item()
关键检查点:
shift_logits和shift_labels长度必须一致(都减 1)labels中 prompt 对应位置必须是-100reduction='mean'自动只平均有效 token(非 -100)- 解释:
.contiguous()是 PyTorch 中张量(Tensor)的一个常用方法。如果张量已经是连续的,它返回自身;如果不是,它会复制一份数据,使其在内存中连续,并返回这个新的张量。
8. SFT 之后的常见 Post-Training 及目的区别
常见方法:
- RLHF(基于人类反馈的强化学习):训练奖励模型,用 PPO 等算法优化策略,使模型生成更符合人类偏好的内容。目的是深度对齐人类价值观。
- DPO(直接偏好优化):直接使用偏好数据优化模型,无需奖励模型,简化流程。目的是高效对齐。
- RLAIF(基于AI反馈的强化学习):用 AI 生成偏好反馈,降低成本。目的同RLHF但更自动化。
- RLVR(基于可验证奖励的强化学习):通过使用可验证的、基于规则的奖励函数,为模型提供明确的二元反馈(正确为 1,错误为 0),从而优化其性能。
- 其他:如拒绝采样、RFT(拒绝微调)等,通过采样和筛选高质量回答进一步微调。
9. 为什么 SFT 后还要做 RL?为何偏好对齐不能用偏好数据直接做 SFT?
- SFT 的局限性:
- SFT 仅让模型模仿人类标注的回答,只能复制训练分布,无法学习" A 比 B 更好"的相对关系。
- 同时,标注数据可能非最优,SFT 性能受限于训练数据质量,无法超越标注者水平。导致模型可能生成不符合偏好的内容(如安全、有用性权衡)。而 RLHF 通过人类偏好反馈,让模型学会在生成时权衡多方面因素,生成更符合人类期望的回答。
- 偏好数据不适合直接 SFT:
- 偏好数据通常是成对比较(如 A 比 B 好),而非绝对最优答案。然而,SFT 需要明确的“正确答案”,无法直接利用相对偏好信息。RL 可以通过奖励模型建模偏好,并优化策略以最大化期望奖励,同时允许模型探索超越示范的答案。
- 此外,RL 能更好地处理多目标优化(如帮助性、安全性)。
- 优化相对偏好:直接最大化"好回答 vs 坏回答"的 margin。
- RL 可以生成训练时未见过的回答并评估,SFT 只能复制见过的。RL 可以用奖励模型泛化到未标注场景,SFT 不行。
10. LoRA 的核心原理
LoRA(Low-Rank Adaptation)的核心原理是在预训练模型的基础上,通过引入低秩矩阵来近似模型权重更新的增量,从而高效地进行微调。具体来说,对于预训练权重矩阵 \(W_0 \in \mathbb{R}^{d \times k}\),LoRA 将其更新约束为低秩分解形式:
其中 \(B \in \mathbb{R}^{d \times r}\),\(A \in \mathbb{R}^{r \times k}\),且秩 \(r \ll \min(d, k)\)。训练时,\(W_0\) 被冻结,仅优化 \(A\) 和 \(B\)。在前向传播中,对于输入 \(x\),输出为:
这样既保持了预训练权重的知识,又通过少量可训练参数(约 \(r \times (d+k)\))实现了针对下游任务的适配。
初始化时,\(A\) 采用高斯分布,\(B\) 初始化为零,确保训练开始时增量部分为零。
11. 秩 \(r\) 的选择对模型表现的影响及选择方法
- 影响:秩 \(r\) 决定了低秩矩阵的表示能力。
- 较小的 \(r\)(1-4)会限制模型学习复杂任务的能力,可能导致欠拟合;
- 较大的 \(r\)(≥ 32 64)虽能提升表达能力,但会增加参数量和过拟合风险,同时可能引入不必要的噪声。
- r 适中(8-32)可以平衡表达与效率,适用于大多数任务。
- 通常 \(r\) 越大,微调效果越接近全量微调,但收益递减。
- 选择方法:实际中可通过网格搜索或经验法则选择 \(r\)(如 1, 2, 4, 8, 16, 32 等)。常用方法包括:
- 验证集性能:对不同 \(r\) 进行实验,选择在验证集上表现最佳的 \(r\)。
- 任务复杂度:简单任务可用较小 \(r\)(如 4~8),复杂任务可能需要较大 \(r\)(如 16~32)。
- 参数效率:结合参数量限制,在资源允许范围内选择较大的 \(r\)。
- 自适应方法:如 AdaLoRA 可根据重要性动态调整各层的秩,如 attention 层 r=16,MLP 层 r=8。
12. LoRA 是否只能嵌入 Linear 层?为什么不能插在 LayerNorm 之后?对训练稳定性有什么影响?
- 应用范围:LoRA 不仅可用于 Linear 层,还可应用于其他权重矩阵层(如 Embedding、Attention 中的 Q/K/V/Out 投影、MLP 层等),但通常只对线性变换层(如全连接)生效。理论上,任何可微调的权重矩阵都可应用 LoRA。
- 不能插在 LayerNorm 之后的原因:
- LayerNorm 是对特征进行归一化,其输出是归一化后的向量。在 LayerNorm 之后插入 LoRA 会破坏归一化的统计特性,因为 LoRA 的增量是未归一化的。
- 若错误地将 LoRA 插入 LayerNorm 之后,会引入额外的未归一化信号,破坏 LayerNorm 的缩放不变性,可能导致梯度爆炸或消失,降低训练稳定性。
- 正确做法:正确的做法是将 LoRA 应用于权重矩阵、线性层内部(如对权重矩阵进行低秩更新),这样前向传播仍可保持原有结构,训练稳定。比如:
- Attention 内部:Q/K/V 投影之前(最常用)
- FFN 子层:第一个 Linear 之前或第二个 Linear 之前
- 跳过 LayerNorm:在残差连接之前,但在 LayerNorm 之后的位置效果差
13. LoRA 微调推理时是否要挂着 Adaptor?合并 Adapter 权重时有没有遇到梯度爆炸?
LoRA 推理时的两种模式:
| 模式 | 做法 | 适用场景 |
|---|---|---|
| 动态挂载 | 保持 \(W_0\) 和 \(BA\) 分离,推理时计算 \(h = W_0x + BAx\) | 多任务切换、需要灵活加载不同 LoRA |
| 权重合并 | 预计算 \(W = W_0 + BA\),替换原权重 | 单任务部署、追求最低延迟 |
工业实践:生产环境几乎都用合并模式,合并后模型结构与原模型完全相同,推理无额外开销。
合并权重时的梯度爆炸:合并操作本身是线性求和,不会引发梯度爆炸(因为不涉及梯度计算)。但在训练过程中,若学习率过大或初始化不当,可能导致 \(A\) 和 \(B\) 的数值过大,从而在合并后使模型输出异常。
但梯度爆炸通常发生在训练的反向传播中,合并阶段仅涉及推理,因此不会出现梯度爆炸。训练中可通过适当初始化(如 \(B\) 初始为零)和梯度裁剪来避免。
(这个我完全不懂,没深入研究过 LoRA)
合并公式:
其中 \(\alpha\) 是缩放因子(通常 \(\alpha=2r\) 或 \(\alpha=r\))。
梯度爆炸风险:
- 来源:如果训练时 \(\alpha\) 设置不当,或 \(BA\) 的数值范围过大
- 预防:
- 使用缩放因子 \(\frac{\alpha}{r}\) 控制更新幅度
- 训练时加入 weight decay 约束 \(A,B\) 的范数
- 合并前检查 \(||BA||\) 与 \(||W_0||\) 的比值,通常应 \(< 0.1\)
面试要点:合并是安全的,因为 \(W_0\) 冻结,\(BA\) 在训练中被约束在低秩子空间,数值范围可控。
14. QLoRA 降低资源成本的机制、量化方式、NF4 和 FP16 组合原因及 NF4 分布拟合逻辑
(这个我也完全不懂)
降低资源成本的机制:
- 4-bit 量化:将预训练模型量化为 4-bit(如 NF4),大幅减少显存占用(约 4 倍压缩)。
- 分页优化器:使用 NVIDIA 统一内存技术,在显存不足时自动将优化器状态换出到 CPU 内存,避免 OOM。
- 双重量化:对量化常数进行二次量化,进一步节省内存。
- LoRA 低秩适配:仅训练少量参数(以 16-bit 精度),其余权重保持 4-bit 冻结,显著降低显存和计算需求。
常见量化方式:包括 NF4(4-bit NormalFloat)、FP4(4-bit Floating Point)、INT8(8-bit 整数)等。QLoRA 主要采用 NF4 和 FP16 混合。
| 方法 | 位宽 | 特点 | 适用 |
|---|---|---|---|
| INT8 | 8-bit | 均匀量化,简单高效 | 推理加速 |
| INT4(GPTQ) | 4-bit | 分组量化,有损压缩 | 推理极致压缩 |
| FP4(E2M1) | 4-bit | 浮点表示,动态范围小 | 较少使用 |
| NF4(Normal Float 4) | 4-bit | 非均匀分布,拟合权重分布 | QLoRA 首选 |
NF4 和 FP16 组合原因:(这个我更不懂了)
- NF4 用于模型权重:NF4 是一种基于分位数的 4-bit 数据类型,能更好地拟合正态分布权重,量化误差小。
- FP16 用于梯度计算:LoRA 的适配器参数以 FP16 训练,保证梯度精度,避免 4-bit 量化带来的信息损失。
- 组合在保持模型性能的同时,最大化内存节省。
(kimi 的答案,看不懂)
NF4 的优势:
- 神经网络权重通常服从零均值正态分布(或近似高斯)
- 均匀量化(INT4)在分布尾部浪费精度,中心区域精度不足
- NF4 是信息论最优的 4-bit 表示,量化点密度匹配正态分布
FP16 计算的必要性:
- 4-bit 权重仅用于存储和传输
- 计算时反量化为 FP16,保证矩阵乘法的数值稳定性
- 激活值和梯度始终保持 FP16,避免精度损失累积
NF4 的分布拟合逻辑:核心思想:将标准正态分布 \(N(0,1)\) 的累积分布函数(CDF)均分为 \(2^4=16\) 个区间,取每个区间的期望值作为量化点。
具体步骤:
- 假设预训练权重近似服从均值为 0、方差固定的正态分布,权重 \(w \sim N(0, \sigma^2)\)。
- 将正态分布的累积分布函数(CDF)等分为 \(2^4 = 16\) 个区间,每个区间概率相等。
- 找到分位点 \(q_i\) 使得 \(\Phi(q_i) = \frac{i}{16}\),\(i=0,...,16\),每个区间的代表值为期望值 \(v_i = E[w | q_{i-1} < w \leq q_i]\)。
- 这些 \(v_i\) 就是 NF4 的 16 个量化级别,中心密集、尾部稀疏。这种分位数方法能保留更多信息,尤其对长尾分布(如 Transformer 权重)更有效,减少了量化误差。
15. 训练 LoRA 模型时,如何选择冻结层?依据是什么?
通常对所有预训练权重进行冻结,只对插入的 LoRA 参数(即 \(A\) 和 \(B\))进行训练。
但有时可根据需求选择性地解冻某些层:
- 全部冻结:默认做法,只训练 LoRA 参数 A B。
- 部分解冻:若任务与预训练领域差异大,可解冻输出层或特定模块(如 LayerNorm 的缩放参数),以增强适应性。
- 分层学习率:对不同层设置不同学习率,如高层(靠近输出)学习率较大,底层较小。
选择性解冻的考量
依据 1:任务相似度
- 领域适配(如医学→通用):冻结底层,解冻顶层 + LoRA
- 格式学习(如对话模板):可能需要解冻 Embedding 和 LM Head,但貌似这种情况少见
依据 2:参数效率分析
- Attention 层:包含语义和句法知识,优先加 LoRA
- FFN 层:存储事实知识,领域迁移时需适配
- LayerNorm:控制信息流,通常解冻 bias 有助于稳定
依据 3:层的重要性
- 底层(靠近输入):通用特征,少动
- 中层:任务相关特征,重点适配
- 顶层(靠近输出):任务特定,重点适配
实践经验
| 配置 | 适用场景 | 可训练参数量 |
|---|---|---|
| 仅 Attention + FFN Linear | 通用指令微调 | 0.1%-1% |
| + LayerNorm | 小数据、需快速收敛 | +0.01% |
| + Embedding | 词表扩展、多语言 | 较大 |
| 分层学习率 | 底层 LoRA lr 小,顶层 lr 大 | - |
模型容量:大模型通常只需少量适配,因此全部冻结是主流。
经验规则:通常只对 Attention 的 Q 和 V 投影应用 LoRA,或对全部线性层应用 LoRA,但保持其他层冻结。有研究表明,对更多层应用 LoRA 可能提升效果,但需权衡参数量。
在实际应用中,推荐从默认设置(如对所有线性层应用 LoRA,秩 \(r=8\))开始,根据验证集表现调整。
16. Tokenizer 是怎么做的?有哪些实现方式?
Tokenizer 是将原始文本(字符串)转换为模型可以处理的整数序列(token IDs)的组件。
主要步骤包括:文本规范化(如大小写转换、Unicode 归一化)、预分词(如按空格、标点切分)、基于词表的子词切分或字符切分,最后映射到 ID。
常见实现方式:
- 基于词(Word-based):直接按空格和标点分词,每个词一个 token。词表极大,存在 OOV(未登录词)问题。
- 基于字符(Character-based):每个字符作为一个 token。序列过长,缺乏语义信息。
- 基于子词(Subword-based):平衡词和字符,常见算法有:
- BPE(Byte Pair Encoding):从字符开始,逐步合并出现频率最高的相邻字节对,形成子词词表。GPT、BERT 等使用。
- WordPiece:类似 BPE,但合并依据是最大化训练数据似然,而非频率。BERT 使用。
- Unigram Language Model:从一个较大的词表开始,逐步剪枝保留概率最高的子词,最终得到词表。SentencePiece 支持。
- SentencePiece:将文本视为 Unicode 字符序列,可直接处理多语言,无需预先分词,支持 BPE 和 Unigram。
现代大模型多采用子词分词(如 BPE 或 SentencePiece),以平衡词表大小和覆盖度。
17. Embedding 是怎么做的?从 ID 到 Embedding 有哪些实现方式?
Embedding 是将离散的 token ID 映射为连续的稠密向量,使模型能够处理语义信息。
从 ID 到 Embedding 的实现方式的类别:
- 标准 Embedding 层:一个可训练的查找表(Lookup Table),维度为
[vocab_size, hidden_size]。输入 ID 通过索引直接取出对应向量,梯度通过反向传播更新该表。 - 随机初始化:Embedding 矩阵随机初始化,随训练优化。
- 预训练 Embedding:使用预训练的词向量(如 Word2Vec、GloVe)初始化 Embedding 层,然后微调或固定。
- 位置编码叠加:在 token embedding 基础上加上位置编码(如正弦位置编码、可学习位置编码),以注入序列位置信息。
- 其他变体:
- Byte-level Embedding(如 BPE 后直接映射)。
- 共享输入输出 Embedding:输入和输出层共用同一个 Embedding 矩阵,减少参数量(如 Transformer 中的 tied embeddings)。
- 分段 Embedding(如 BERT 的 segment embedding)用于区分不同句子。
实际中,LLM 通常使用可学习的 token embedding + 位置 embedding(或相对位置编码),并可能结合层归一化。
18. 控制模型生成多样性的参数有哪些?如何控制?
生成多样性是指避免模型总是输出重复或单一的文本。常用参数:
- 温度(Temperature, T):在 softmax 前对 logits 进行缩放,
logits = logits / T。T 越高,概率分布越平滑,低概率词更容易被选到,多样性增加;T 越低(趋近 0),分布越尖锐,趋于贪心。 - Top-k 采样:只保留概率最高的 k 个 token,重新归一化后采样。k 越大,多样性越高;k 小则更集中。
- Top-p(核采样):选择累积概率超过 p 的最小 token 集合,动态调整候选集大小。p 越大(如 0.9),候选越多,多样性高;p 小则候选少。
- 重复惩罚(Repetition Penalty):对已经生成的 token 的 logits 进行惩罚(如乘以小于 1 的系数),降低重复概率。
- 频率惩罚/存在惩罚:根据 token 在已生成序列中出现次数或是否出现过,调整其概率,减少重复。
- Beam Search 相关:beam size 越大,可能得到更多样化的候选,但 beam search 本身倾向于高概率序列,多样性有限,常结合随机采样。(不懂 beam search)
实际控制时,通常组合使用:如温度 + top-k + top-p,并调节惩罚系数。温度调节整体随机性,top-k/top-p 控制候选集,惩罚处理重复。
19. top-k 与 top-p 的区别?除了贪心,还有哪些生成策略?
- top-k:固定选取概率最高的 k 个 token 作为候选,然后重新归一化采样。缺点:k 固定,可能在某些分布下(如平坦分布)截断过多,或尖锐分布时引入低概率词。
- top-p:动态选择累积概率达到 p 的最小 token 集合,适应不同分布。比如,如果 p = 0.7,那么就贪心选择概率最大的 token 加入候选集合,直到集合内 token 的概率累加 ≥ 0.7。当分布尖锐时,候选集小;平坦时,候选集大。更灵活。
除了贪心(每次选概率最大 token),常见生成策略:
- 随机采样:根据概率分布直接采样,但可能产生不连贯文本,常与 top-k/top-p 结合。
- Beam Search:保留多个候选序列(beam),每一步扩展,最终选得分最高的序列。适合确定性任务(翻译、摘要),但多样性差。(不懂这个,但听说 minimax 会手撕 beam search)
- 对比搜索(Contrastive Search):考虑 token 概率与上下文相似度的平衡,促进生成连贯且新颖的文本。(不懂这个)
- 典型采样(Typical Sampling):选择信息量适中的 token,避免过高或过低概率,模仿人类写作。
- 惩罚机制:如重复惩罚、n-gram 惩罚,防止重复。
- 温度调节:缩放 logits 后采样。
实际中,常用 top-k + top-p + 温度 + 重复惩罚 的随机采样。
20. 介绍一下常见的优化算法优缺点。为什么 Adam 不一定最优而 SGD 最优?怎么理解分析?
常见优化算法:
- SGD(随机梯度下降):更新方向为当前梯度,可加动量。
- 优点:简单,泛化能力强,在充分调参下能达到极优;对学习率敏感但可手动调整;在 CV 等领域仍常用。
- 缺点:收敛慢,需要精心设计学习率调度,易陷入鞍点。
- Momentum:累积历史梯度,加速收敛,减少震荡。
- AdaGrad:自适应学习率,对稀疏特征友好。缺点:累积平方梯度不断增大,学习率过早衰减。
- RMSProp:改进 AdaGrad,使用指数移动平均,适合非平稳目标。
- Adam:结合 Momentum 和 RMSProp,带有偏差校正,自适应学习率。
- 优点:收敛快,对超参数鲁棒,适合大规模数据和稀疏梯度。
- 缺点:泛化性能有时不如 SGD(尤其在 CV 任务);可能收敛到尖锐极小值,泛化差;需要调整 β1, β2 等。
为什么 Adam 不一定最优而 SGD 最优?
Adam 的收敛性证明需要强假设,实际中可能不满足;SGD 在凸问题上有成熟理论。
实际上,很多现代大模型(如 Transformer)仍使用 Adam(或其变体 AdamW),因为 NLP 任务中 Adam 更稳定且收敛快。
21. 怎么解决模型的冷启动问题?LLM 在冷启动方面能够起到什么作用?
冷启动问题:新模型或新系统上线时缺乏历史数据,导致无法提供有效服务。常见于推荐系统、对话系统等。
解决冷启动的方法:
- 基于内容的推荐:利用用户/物品的元数据(如属性、标签)进行相似性推荐。
- 利用人口统计学信息:根据年龄、性别等粗粒度特征推荐热门内容。
- 探索与利用:采用 Bandit 算法(如 UCB、Thompson Sampling),在初期多探索。
- 迁移学习:利用预训练模型或源域数据微调,快速适应新域。
- 主动学习:让用户标注少量样本,快速构建初始模型。
- 利用外部知识:如知识图谱、常识库补充信息。
- 规则或专家系统:初期用规则兜底,积累数据后再切换模型。
LLM 在冷启动方面的作用:
- 零样本/少样本学习:LLM 通过提示工程(Prompting)可在无训练数据时执行任务,直接用于冷启动场景(如问答、对话、分类)。
- 生成合成数据:利用 LLM 生成符合分布的模拟数据,用于训练初始模型。
- 作为知识库:LLM 内置大量常识,可辅助推荐或决策,缓解数据稀疏。
- 快速原型:用 LLM 构建 demo,收集用户反馈后迭代。
- 语义理解:LLM 可理解用户意图,即使缺乏历史行为,也能基于语义做出合理响应。
例如,新上线的对话系统可先用 LLM(如 GPT-3)零样本回答用户,同时收集对话数据用于后续微调。
22. 大模型幻觉是什么?怎么缓解大模型幻觉?
大模型幻觉:指模型生成的内容与事实不符、无中生有或逻辑矛盾的现象。分为内在幻觉(输出与输入冲突)和外在幻觉(输出与真实世界事实不符)。
缓解方法:
- 检索增强生成(RAG):在生成前从外部知识库检索相关文档,作为上下文输入,让模型基于事实生成。
- 强化学习与人类反馈(RLHF):通过人类反馈训练奖励模型,优化生成内容的事实性(如 InstructGPT)。
- 解码策略优化:如使用对比解码(Contrastive Decoding),对比原始模型和经过微调的模型输出,减少幻觉。
- 事实核查后处理:生成后调用外部工具(如搜索引擎、知识库)验证事实,并修正。
- 训练时引入反事实样本:让模型学会区分事实与虚构。
- prompt engineering:明确要求模型“仅基于上下文回答”或“不知道时说不知道”,减少捏造。
- 对抗性训练:用对抗样本训练模型对幻觉鲁棒。
当前主流方法是 RAG 和 RLHF,结合解码约束和提示技巧。
面试背诵要点(仅供参考)
| 问题 | 一句话答案 |
|---|---|
| Pretrain/SFT/RLHF 区别 | 学知识 → 指令跟随 → 对齐价值观 |
| SFT Loss 怎么算 | Shift right,只算 answer,prompt 设 -100 |
| 为什么 SFT 后要 RL | SFT 只能模仿,RL 能比较,偏好是相对关系 |
| 为什么偏好不直接 SFT | 直接 SFT 会崩溃(平均好坏),必须用 RL 拉大 margin |
| DPO vs RLHF | DPO 省去 RM 和 PPO,直接用偏好对优化 |

浙公网安备 33010602011771号