训练 · 预训练之后

RLHF 与 DPO

学会判断两个回答哪个更好

策略
GPT-2 small + LoRA 秩 4
参考
GPT-2 small,冻结
β
0.1 25 步
奖励
玩具规模 RLHF 步骤

全部步骤

  1. 是偏好,而不是答案

    指令微调之后,模型还会在偏好上微调:一条提示词、两个回答,以及人们更喜欢哪一个。评判比撰写容易。在这三组里,GPT-2 small 的倾向正好相反:在 “The cat sat on the” 之后,它认为 “floor.” 的可能性是 “mat.” 的 21 倍。

    提示词 · 被选中 ≻ 被拒绝

  2. RLHF:奖励模型

    经典的 RLHF 先在这样的回答对上训练一个奖励模型:一个读入提示词和回答、输出一个分数的网络,训练目标是让更受欢迎的回答得分更高。这里它给 “The cat sat on the” 之后六个可能的下一个词元打分;这些分数是为本例编造的。

    P(chosen ≻ rejected) = σ(rchosen − rrejected)

  3. RLHF:采样、打分、调整

    接着是强化学习:模型采样一个回答,奖励模型给它打分,概率向得分高的回答移动。对偏离起点(描边的柱)的惩罚会把它往回拉,所以它最终停在 πref · exp(r / β),而不是全押在得分最高的那个词元上。改变 β 可以放松或收紧这股拉力。

    max E[r] − β · KL(π ‖ πref)

  4. DPO:不要奖励模型

    DPO 去掉了奖励模型和采样。它的损失直接看每一对:模型让被选中回答比参考模型更可能多少,对比被拒绝回答的同一个量,并把这个差距拉开。β 同样决定它能走多远。

    −log σ(β [Δ log π(chosen) − Δ log π(rejected)])

  5. 一次真实的 DPO 运行

    在 GPT-2 small 上的真实运行:秩 4 适配器,冻结的模型作参考,β = 0.1,在三组回答对上训练 25 步。每个回答都停在它的对数概率上;差距不断拉开,直到损失从 0.693 降到 0.005。差距大多来自被拒绝回答的下跌。

    损失 0.693 → 0.005

  6. 概率去了哪里

    概率去了哪里(“The cat sat on the” 之后的下一个词元):GPT-2 把它分给 floor、bed、couch 等;25 步之后几乎全部落在 “mat” 上。只有三组回答对,模型干脆把它们背了下来。真实训练用成千上万组回答对,β 和参考模型让它不至于偏离这么远。

    被拒绝的被压下去的,比被选中的被拉上来的多

代码

def logp(model, prompt, answer):              # Σ log p of the answer tokens
    logits = model(prompt + answer).logits[len(prompt) - 1:-1]
    return logits.log_softmax(-1).gather(-1, answer[:, None]).sum()
r_w = beta * (logp(policy, x, y_w) - logp(ref, x, y_w))    # implicit rewards
r_l = beta * (logp(policy, x, y_l) - logp(ref, x, y_l))
loss = -F.logsigmoid(r_w - r_l)
loss.backward(); opt.step()                   # ref is frozen; only the policy moves

延伸阅读