Agent 工程训练 - 测试题答案


选择题答案

1. SFT 的主要局限是什么?

答案:B

解析:SFT(监督微调)只使用正例数据(好的回答)进行训练,模型只能学习"应该这样做",但缺乏负例对比,无法学习"不应该那样做"。这就是为什么需要后续的 DPO 或 GRPO 等方法来引入对比学习。


2. DPO 损失函数中的 $\pi_{ref}$ 的作用是什么?

答案:C

解析:$\pi_{ref}$ 是参考模型(通常是 SFT 后的模型),在 DPO 损失函数中通过 $\log \frac{\pi}{\pi_{ref}}$ 项隐式地约束当前模型不要偏离参考模型太远,这等价于 RLHF 中的 KL 散度惩罚项 $\beta \cdot KL(\pi || \pi_{ref})$。


3. GRPO 中的"组内相对优势"是指什么?

答案:C

解析:GRPO 对同一个 prompt 采样 G 个回答,计算每个回答相对于这一组回答的优势:$\hat{A}_i = \frac{r_i - \text{mean}(r)}{\text{std}(r)}$。这是组内的相对比较,而不是与其他 prompt、参考模型或人类标注比较。


4. DPO 的长度偏差问题主要是因为?

答案:A

解析:序列概率 $\log \pi(y|x) = \sum_{t=1}^{T} \log P(y_t|x, y_{<t})$,每个 token 的 $\log P < 0$,因此长序列累加更多负数,导致概率天然更低。虽然 DPO 使用 log ratio 部分缓解了这个问题,但长度偏差仍然存在。


5. GRPO 的熵坍塌问题可以通过什么方法缓解?

答案:C

解析:熵坍塌是指模型输出分布的熵趋近于 0,变得过度自信。添加熵正则化项可以显式地鼓励模型保持输出多样性,防止坍塌。其他方法还包括增加采样温度、使用更大的采样组等。


简答题答案

6. 解释为什么 DPO 被认为是"隐式强化学习"?它与传统 RLHF 的主要区别是什么?

答案

为什么是隐式强化学习

  • DPO 本质上是通过数学推导,将 RLHF 的优化目标重新参数化
  • 原始 RLHF 需要显式训练 reward model,然后用 PPO 等 RL 算法优化
  • DPO 通过 Bradley-Terry 模型的数学变换,将 reward 表达为策略的函数,从而消除了显式的 reward model

与传统 RLHF 的区别

维度RLHFDPO
Reward Model需要单独训练不需要,隐式表达
训练算法PPO/TRPO(复杂)简单的监督学习式损失
KL 约束显式添加惩罚项通过 log ratio 隐式约束
训练稳定性较难调参相对稳定
计算成本高(需要多个模型)低(只需策略和参考模型)

7. 在 GRPO 中,如果对同一 prompt 采样的 4 个回答的 reward 分别是 [0.8, 0.75, 0.72, 0.70],请计算每个回答的相对优势。这说明了什么问题?

答案

计算过程

1
2
3
4
5
6
7
8
9
rewards = [0.8, 0.75, 0.72, 0.70]
mean = 0.7425
std ≈ 0.0374

相对优势:
A₁ = (0.8 - 0.7425) / 0.0374 ≈ +1.54
A₂ = (0.75 - 0.7425) / 0.0374 ≈ +0.20
A₃ = (0.72 - 0.7425) / 0.0374 ≈ -0.60
A₄ = (0.70 - 0.7425) / 0.0374 ≈ -1.14

说明的问题

  1. 强制竞争:即使所有 reward 都很高(0.70-0.80),仍必须分出"赢家"和"输家"
  2. 相对性:回答3和4的 reward 是 0.72 和 0.70(绝对值不错),但因相对较低而被抑制
  3. 马太效应风险:回答1获得最大优势,会被强化最多,可能导致后续采样更频繁

8. 为什么说 SFT 只能学会"应该做什么"而不能学会"不应该做什么"?请举例说明。

答案

原因

  • SFT 使用单向监督学习,只有正例(好的回答)
  • 损失函数 $\mathcal{L} = -\log P(y|x)$,只优化提高正确回答的概率
  • 没有负例对比,模型不知道哪些回答是不好的

举例:训练医疗咨询助手

SFT 训练数据:

1
2
Q: "我头痛怎么办?"
A: "建议多休息,保持充足睡眠。如果持续疼痛,请就医检查。"

SFT 的效果:

  • ✅ 学会了给出合理建议
  • ❌ 但不知道以下回答是不好的:
    • “吃点止痛药就行,不用看医生”(过于武断)
    • “可能是脑瘤,赶紧去医院”(过度恐慌)

DPO 如何解决:通过偏好对明确告诉模型好坏对比,既提升 chosen 概率,又降低 rejected 概率。


应用题答案

9. 设计偏好对数据

答案

Prompt(用户问题)

1
"如何在 Python 中读取 CSV 文件?"

Chosen(优选回答)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 使用 pandas 库读取 CSV 文件是最常用的方法:

import pandas as pd

# 读取 CSV 文件
df = pd.read_csv('data.csv')

# 查看前几行
print(df.head())

# 如果不想使用 pandas,也可以用标准库 csv:
import csv

with open('data.csv', 'r', encoding='utf-8') as file:
    csv_reader = csv.reader(file)
    for row in csv_reader:
        print(row)

Rejected(拒绝回答)

1
用 pandas 的 read_csv 就行了。

为什么 Chosen 更好

  1. 完整性:提供了完整的代码示例,可以直接运行
  2. 多样性:给出了两种方法(pandas 和标准库 csv),适应不同需求
  3. 实用性:包含了常用操作(如 head())
  4. 可读性:有注释说明,易于理解
  5. 编码处理:考虑了 encoding 参数,避免中文乱码

而 Rejected 回答过于简略,缺乏实际可用的代码,对初学者帮助有限。


10. 分析熵坍塌场景

答案

a) 这是熵坍塌的表现吗?为什么?

是的,这是典型的熵坍塌表现。

判断依据

  • 训练初期:输出分布熵高(5种不同回答),多样性好
  • 训练中期:熵下降(80%相同),多样性降低
  • 训练后期:熵接近0(100%相同),完全坍塌

熵的定义:$H = -\sum p(y) \log p(y)$

  • 初期:$H \approx \log 5 = 1.61$(均匀分布)
  • 后期:$H \approx 0$(单点分布)

b) 可能的原因是什么?

  1. 马太效应

    • 某个回答A在早期获得较高reward
    • 采样时A出现频率增加
    • 组内比较时A经常获胜
    • A的概率被进一步强化
    • 形成正反馈循环
  2. 采样多样性不足

    • 当P(A) = 0.8时,采样4个回答可能全是A
    • 组内无法比较,梯度信号退化
    • 无法探索其他可能更好的回答
  3. KL约束不足

    • β参数可能设置过小
    • KL散度约束无法有效限制模型偏离参考模型
  4. 缺乏熵正则化

    • 目标函数中没有显式鼓励多样性的项

c) 提出2-3种解决方案

方案1:添加熵正则化

1
2
3
4
5
# 修改损失函数
loss = -advantage * log_prob + β_kl * kl_term - α_entropy * entropy

# 其中 entropy = -Σ p(y) log p(y)
# α_entropy 是熵正则化系数(如0.01)

效果:显式鼓励模型保持输出多样性

方案2:增加采样温度和组大小

1
2
3
4
5
6
7
# 使用更高的采样温度
temperature = 1.2  # 原来可能是1.0

# 增加组大小
G = 16  # 原来可能是4

# 更大的组和更高的温度增加采样多样性

效果:提高采样多样性,减少"全是A"的情况

方案3:使用Top-k或Top-p采样

1
2
3
4
5
6
7
8
# 限制采样范围,避免过度集中
responses = model.generate(
    prompt,
    do_sample=True,
    top_k=50,      # 只从概率最高的50个token中采样
    top_p=0.9,     # 累积概率达到0.9的token集合
    temperature=1.0
)

效果:在保持质量的同时增加多样性

方案4:定期重置或混合参考模型

1
2
3
# 每N步更新参考模型
if step % 1000 == 0:
    π_ref = copy.deepcopy(π)

效果:防止模型偏离初始分布太远


总结:熵坍塌是GRPO训练中的常见问题,需要通过熵正则化、增加采样多样性、调整KL约束等多种手段综合解决。


📝 学习提示:理解这些训练方法的优缺点,有助于在实际项目中选择合适的训练策略。