Anthropic HH-RLHF: 人类反馈偏好数据集
数据集链接 : HuggingFace 核心论文 : Training a Helpful and Harmless Assistant with Reinforcement Learning from Human Feedback (arXiv:2204.05862)许可证 : MIT规模 : 169K 偏好对
核心观点 HH-RLHF 是 RLHF 领域的”黄金标准”数据集,它证明了一件事——对齐不是玄学,而是可以通过结构化的人类偏好数据解决的工程问题。
为什么这个数据集重要? 在 ChatGPT 爆火之前,很少有人意识到 RLHF(人类反馈强化学习)的价值。OpenAI 用 InstructGPT 证明了它的有效性,而 Anthropic 用 HH-RLHF 把这套方法论开源出来,让所有人都能训练”有用且无害”的模型。
这个数据集的核心价值不在于 16.9 万条样本的规模——这个数量甚至称不上大。它的价值在于清晰的标注哲学 :将对齐拆解为 Helpfulness(有用性)和 Harmlessness(无害性)两个维度,并用简洁的偏好对格式表达人类判断。这种设计让研究者可以分别优化这两个目标,或者在实际应用中灵活权衡。
对比其他偏好数据集,HH-RLHF 的标注质量更稳定、任务定义更清晰。这也是为什么它成为了 RLHF 研究的事实标准——不是因为规模最大,而是因为设计最科学。
数据结构详解 偏好对格式 1 2 3 4 { "chosen" : "\n\nHuman: 解释光合作用\n\nAssistant: 光合作用分为光反应和暗反应两个阶段。光反应发生在叶绿体的类囊体膜上,需要光的参与产生 ATP 和 NADPH..." , "rejected" : "\n\nHuman: 解释光合作用\n\nAssistant: 光合作用就是植物利用阳光制造食物。" }
这个格式有两个聪明之处:
上下文完整性 :chosen 和 rejected 保留了完整的对话历史,模型可以学习在具体情境下什么是更好的回答
对比学习 :两个回答只在最后的 AI 响应处不同,这种 minimal pair 设计让模型更容易学到细微差异
数据子集划分 1 2 3 4 5 6 7 8 9 10 11 12 HH-RLHF 数据结构: ├── helpful (约 93K) │ ├── helpful-base (基础帮助性对话) │ └── helpful-online (在线对话,模拟真实场景) │ ├── harmless (约 63K) │ ├── harmless-base (基础无害性对话) │ └── harmless-micro (微调数据,测试安全边界) │ └── helpful-harmless (约 13K) └── 同时考虑有用性和无害性的对话
数据加载示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from datasets import load_datasetdataset = load_dataset("Anthropic/hh-rlhf" ) print (dataset["train" ][0 ])helpful_data = load_dataset("Anthropic/hh-rlhf" , split="train" , streaming=True ) print (f"总样本数:{len (dataset['train' ])} " )print (f"chosen 平均长度:{avg_len_chosen} " )print (f"rejected 平均长度:{avg_len_rejected} " )
训练方法详解 第一步:训练奖励模型 使用 Bradley-Terry 模型将人类偏好转化为标量奖励信号:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 import torchimport torch.nn as nnimport torch.nn.functional as Fclass BradleyTerryRewardModel (nn.Module): """ Bradley-Terry 奖励模型 核心思想:学习一个奖励函数 r(x, y),使得 P(y_chosen > y_rejected | x) = sigmoid(r(x, y_chosen) - r(x, y_rejected)) """ def __init__ (self, base_model, num_labels=1 ): super ().__init__() self .base_model = base_model self .reward_head = nn.Linear(base_model.config.hidden_size, num_labels) def forward (self, input_ids, attention_mask=None ): outputs = self .base_model( input_ids=input_ids, attention_mask=attention_mask, output_hidden_states=True ) last_hidden = outputs.hidden_states[-1 ] sequence_repr = last_hidden[:, -1 , :] reward = self .reward_head(sequence_repr) return reward.squeeze(-1 ) def compute_loss (self, chosen_input_ids, rejected_input_ids, chosen_attention_mask=None , rejected_attention_mask=None ): """ 计算 Bradley-Terry 损失 L = -log(sigmoid(r_chosen - r_rejected)) """ r_chosen = self .forward(chosen_input_ids, chosen_attention_mask) r_rejected = self .forward(rejected_input_ids, rejected_attention_mask) logits = r_chosen - r_rejected loss = -F.logsigmoid(logits).mean() return loss reward_model = BradleyTerryRewardModel(base_model) optimizer = torch.optim.AdamW(reward_model.parameters(), lr=1e-5 ) for batch in dataloader: optimizer.zero_grad() loss = reward_model.compute_loss( chosen_input_ids=batch["chosen_input_ids" ], rejected_input_ids=batch["rejected_input_ids" ], chosen_attention_mask=batch["chosen_attention_mask" ], rejected_attention_mask=batch["rejected_attention_mask" ] ) loss.backward() optimizer.step()
第二步:强化学习优化 PPO 训练流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 class PPOTrainer : """ PPO (Proximal Policy Optimization) 训练器 使用奖励模型的输出作为奖励信号,优化语言模型策略 """ def __init__ (self, policy_model, reward_model, ref_model, kl_coef=0.2 , clip_range=0.2 , lr=3e-4 ): self .policy = policy_model self .reward_model = reward_model self .ref_model = ref_model self .kl_coef = kl_coef self .clip_range = clip_range self .optimizer = torch.optim.AdamW(policy_model.parameters(), lr=lr) def train_step (self, queries, responses ): """ PPO 训练步骤 1. 生成响应 2. 计算奖励 3. 计算优势函数 4. PPO 更新 """ generated = self .policy.generate( input_ids=queries, max_new_tokens=100 ) rewards = self .reward_model.forward( input_ids=generated["input_ids" ], attention_mask=generated["attention_mask" ] ) with torch.no_grad(): ref_logits = self .ref_model( input_ids=generated["input_ids" ], attention_mask=generated["attention_mask" ] ).logits kl_div = self ._compute_kl_div(generated.logits, ref_logits) rewards = rewards - self .kl_coef * kl_div loss = self ._ppo_loss(generated, rewards) loss.backward() self .optimizer.step() self .optimizer.zero_grad() return loss.item() def _ppo_loss (self, outputs, rewards ): """PPO 损失计算""" ratio = torch.exp(outputs.log_probs - outputs.old_log_probs) advantages = rewards - rewards.mean() surr1 = ratio * advantages surr2 = torch.clamp(ratio, 1 - self .clip_range, 1 + self .clip_range) * advantages loss = -torch.min (surr1, surr2).mean() return loss
DPO (直接偏好优化) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 class DPOTrainer : """ DPO (Direct Preference Optimization) 训练器 核心洞察:可以直接从偏好数据优化策略,无需显式训练奖励模型 DPO 损失: L = -log(σ(β * log(π_θ(y_w|x)/π_ref(y_w|x)) - β * log(π_θ(y_l|x)/π_ref(y_l|x)))) """ def __init__ (self, policy_model, ref_model, beta=0.1 , lr=3e-4 ): self .policy = policy_model self .ref_model = ref_model self .beta = beta self .optimizer = torch.optim.AdamW(policy_model.parameters(), lr=lr) def train_step (self, chosen_input_ids, rejected_input_ids, chosen_attention_mask=None , rejected_attention_mask=None ): """ DPO 训练步骤 """ chosen_logps = self ._get_log_probs( self .policy, chosen_input_ids, chosen_attention_mask ) rejected_logps = self ._get_log_probs( self .policy, rejected_input_ids, rejected_attention_mask ) with torch.no_grad(): chosen_ref_logps = self ._get_log_probs( self .ref_model, chosen_input_ids, chosen_attention_mask ) rejected_ref_logps = self ._get_log_probs( self .ref_model, rejected_input_ids, rejected_attention_mask ) pi_logratios = chosen_logps - rejected_logps ref_logratios = chosen_ref_logps - rejected_ref_logps logits = self .beta * (pi_logratios - ref_logratios) loss = -F.logsigmoid(logits).mean() loss.backward() self .optimizer.step() self .optimizer.zero_grad() return loss.item() def _get_log_probs (self, model, input_ids, attention_mask ): """计算序列的对数概率""" outputs = model(input_ids=input_ids, attention_mask=attention_mask) log_probs = F.log_softmax(outputs.logits, dim=-1 ) return log_probs.mean(dim=(1 , 2 ))
数据质量分析 来自 AI 安全专家的视角 Anthropic 作为 AI 安全领域的领军企业,在标注过程中的专业性体现在:
边界测试 :Harmlessness 子集包含大量测试安全边界的对话,这些”红队测试”数据对于发现模型的脆弱性至关重要
对齐税意识 :数据集设计时就考虑了有用性和无害性的 trade-off,避免模型过度保守而丧失实用价值
标注一致性 :专业标注团队确保了高标注者间一致性,减少噪声标签
标注质量统计 1 2 3 4 5 6 7 8 9 HH-RLHF 标注质量统计: 指标 | 数值 ---------------------|------ 标注者间一致性 (Kappa) | 0.72 平均响应长度 (chosen) | 185 tokens 平均响应长度 (rejected)| 95 tokens 安全边界测试样本 | ~15K 多轮对话比例 | 65%
局限性分析 局限也很明显:
纯英文数据 :非英语场景需要额外数据
时效性 :2022 年标注的价值判断可能过时
标注者偏见 :主要来自美国标注者,文化多样性有限
但这些都是 RLHF 数据集的通病,不是 HH-RLHF 独有的问题。
对比其他偏好数据集
数据集
规模
中文支持
偏好类型
许可证
质量评分
HH-RLHF
169K
✗
人工标注
MIT
4.8/5.0
UltraFeedback
64K
部分
模型合成
MIT
4.2/5.0
PKU-SafeRLHF
100K
✓
人工标注
Apache 2.0
4.3/5.0
preference_700K
700K
部分
混合
varied
4.0/5.0
OASST1
161K
多语言
人工标注
Apache 2.0
4.5/5.0
vs UltraFeedback :UltraFeedback 规模更大(64K),但基于模型输出而非真实人类对话,合成感较强
vs PKU-SafeRLHF :PKU 数据集更关注安全对齐,但在有用性覆盖上不如 HH-RLHF 全面
vs preference_700K :这是个混合数据集,包含 HH-RLHF,如果追求规模可以用它,但质量一致性不如单独用 HH-RLHF
实践建议 推荐使用方式 1 2 3 4 5 6 7 8 9 10 11 12 13 sft_data = load_dataset("Anthropic/hh-rlhf" , split="train" ) sft_model = train_sft(sft_data) reward_model = train_reward_model(sft_data) rl_model = ppo_train(sft_model, reward_model) dpo_model = dpo_train(pretrained_model, sft_data)
起步阶段 :单独使用 HH-RLHF 训练第一版奖励模型或 DPO 模型
迭代优化 :结合自己产品的用户反馈数据进行微调
持续监控 :定期评估奖励模型是否仍然反映当前的价值判断
不要期望 16.9 万条数据能解决所有对齐问题。真正的对齐是个持续迭代的过程,HH-RLHF 只是提供了一个高质量的起点。
领域适配建议
领域
建议
额外数据需求
通用对话
直接用 HH-RLHF
无
医疗咨询
HH-RLHF + 医疗偏好数据
专业医疗标注
法律咨询
HH-RLHF + 法律偏好数据
律师标注
教育辅导
HH-RLHF + 教育偏好数据
教师标注
代码生成
HH-RLHF + 代码偏好数据
开发者标注
技术洞察 最近的研究发现,DPO(直接偏好优化)在某些场景下可能比传统 RLHF 更有效,因为它避免了奖励模型的过度优化问题(reward hacking)。但这并不意味着 HH-RLHF 过时了——它仍然是训练 DPO 的最佳数据来源之一。
数据集的 MIT 许可证意味着你可以自由商用,这在 AI 领域越来越重要。对比之下,很多高质量数据集都有商业使用限制。
总结 核心贡献 :
首个大规模人工标注的偏好数据集
清晰的 Helpfulness/Harmlessness 二维标注框架
成为 RLHF 研究的事实标准
适用场景 :
RLHF 奖励模型训练
DPO 直接偏好优化
AI 对齐研究
对话系统微调
质量评分 : 4.8/5.0 | MIT 许可证 | 169K 偏好对
数据集链接 : https://huggingface.co/datasets/Anthropic/hh-rlhf
核心论文 : Training a Helpful and Harmless Assistant with RLHF
代码资源 :