duxx/distilabel-intel-orca-dpo-pairs-tr
收藏distilabel Orca Pairs for DPO
该数据集是广泛使用的Intel/orca_dpo_pairs数据集的“distilabeled”版本。原始数据集已被数百名开源从业者和模型使用。通过改进UltraFeedback(以及之前的Alpacas和Dollys),我们知道这个数据集可以得到显著改进。
为了构建最适合开源LLMs和社区的对齐数据集,我们花费了几个小时使用distilabel对其进行改进。
我们的主要直觉是:原始数据集假设gpt4/3.5-turbo总是最佳响应。我们知道从UltraFeedback来看,情况并非总是如此。此外,DPO微调受益于偏好对的多样性。
此外,我们添加了一个新列,指示数据集中的问题是否属于gsm8k训练集的一部分(测试集中没有示例)。详见复现部分。
使用该数据集
该数据集适用于偏好调优,我们建议使用它而不是原始数据集。它已经以“标准”的选定、拒绝格式准备,并附带了进一步过滤和实验的额外信息。
主要变化包括:
- 约2K对被交换:拒绝的变为选定的响应。我们保留了原始的选定和拒绝在两个新的
original_*列中,以供复现。 - 4K对被标识为
tie:同样糟糕或好。 - 添加了选定分数:现在可以根据阈值进行过滤(参见我们的distilabeled Hermes 2.5模型示例)。
- 我们保留了使用gpt-4-turbo和distilabel生成的评分和理由,以便您可以根据需要准备数据。
- 我们添加了一个列,指示输入是否属于gsm8k训练集。
在我们的实验中,通过将数据集大小减少超过50%,我们取得了非常好的结果。以下是如何实现这一点的示例:
python from datasets import load_dataset
使用这个:
dataset = load_dataset("argilla/distilabel-intel-orca-dpo-pairs", split="train")
dataset = dataset.filter( lambda r: r["status"] != "tie" and r["chosen_score"] >= 8 and not r["in_gsm8k_train"] )
这导致样本数从12,859减少到5,922(减少了54%),并且性能优于使用原始数据集100%样本微调的相同模型。
复现数据集
在本节中,我们概述了复现该数据集的步骤。
对原始数据集对进行评分
使用distilabel构建偏好数据集:
python from distilabel.llm import OpenAILLM from distilabel.tasks import JudgeLMTask from distilabel.pipeline import Pipeline
from datasets import load_dataset
打乱chosen和rejected以避免位置偏差并跟踪顺序
def shuffle_and_track(chosen, rejected): pair = [chosen, rejected] random.shuffle(pair) order = ["chosen" if x == chosen else "rejected" for x in pair] return {"generations": pair, "order": order}
dataset = load_dataset("Intel/orca_dpo_pairs", split="train")
打乱对以缓解位置偏差
dataset = dataset.map(lambda x: shuffle_and_track(x["chosen"], x["rejected"]))
使用我们的JudgeLM实现对原始对进行评分
labeler = OpenAILLM( task=JudgeLMTask(), model="gpt-4-1106-preview", num_threads=16, max_new_tokens=512, )
dataset = dataset.rename_columns({"question": "input"})
distipipe = Pipeline( labeller=labeler )
计算每对的评分和自然语言批评
ds = distipipe.generate(dataset=dataset, num_generations=2)
如果需要进一步过滤和整理数据集,可以将数据集推送到Argilla:
python rg_dataset = ds.to_argilla()
rg_dataset.push_to_argilla(name="your_dataset_name", workspace="your_workspace_name")
后处理以添加有用信息
交换拒绝和选定,并添加选定分数和状态:
python def add_status(r): status = "unchanged" highest_rated_idx = np.argmax(r[rating])
比较选定响应的索引
if r[rating]== None or r[rating][0] == r[rating][1]: status = "tie" elif r[order][highest_rated_idx] != chosen: status = "swapped" return {"status": status}
def swap(r): chosen = r["chosen"] rejected = r["rejected"] if r[rating] is not None: chosen_score = r[rating][np.argmax(r[rating])] else: chosen_score = None if r[status] == "swapped": chosen = r["rejected"] rejected = r["chosen"] return { "chosen": chosen, "rejected": rejected, "original_chosen": r["chosen"], "original_rejected": r["rejected"], "chosen_score": chosen_score }
updated = ds.map(add_status).map(swap)
gsm8k "去污染"
基本方法用于查找重复示例。我们没有发现来自测试集的任何示例。我们尝试了较低的阈值,但低于0.8时引入了假阳性:
python import pandas as pd
import nltk from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity
from datasets import load_dataset
nltk.download(punkt)
加载数据集
source_dataset = load_dataset("gsm8k", "main", split="train") source_dataset_socratic = load_dataset("gsm8k", "socratic", split="train") target_dataset = load_dataset("argilla/distilabel-intel-orca-dpo-pairs", split="train")
从每个数据集中提取question列
source_questions = source_dataset[question] source_questions_socratic = source_dataset_socratic[question] target_questions = target_dataset[input]
预处理文本的函数
def preprocess(text): return nltk.word_tokenize(text.lower())
预处理问题
source_questions_processed = [preprocess(q) for q in source_questions] source_questions.extend([preprocess(q) for q in source_questions_socratic]) target_questions_processed = [preprocess(q) for q in target_questions]
向量化问题
vectorizer = TfidfVectorizer() source_vec = vectorizer.fit_transform([ .join(q) for q in source_questions_processed]) target_vec = vectorizer.transform([ .join(q) for q in target_questions_processed])
计算余弦相似度
similarity_matrix = cosine_similarity(source_vec, target_vec)
根据阈值确定匹配项:
手动检查,低于0.8时只有假阳性
threshold = 0.8 matching_pairs = [] for i, row in enumerate(similarity_matrix): for j, similarity in enumerate(row): if similarity >= threshold: matching_pairs.append((source_questions[i], target_questions[j], similarity))
从匹配对创建DataFrame
df = pd.DataFrame(matching_pairs, columns=[Source Question, Target Question, Similarity Score])
创建匹配目标问题的集合
matching_target_questions = list(df[Target Question])
添加一个列到目标数据集,指示每个问题是否匹配
target_dataset = target_dataset.map(lambda example: {"in_gsm8k_train": example[input] in matching_target_questions})
结果:
False 12780 True 79 Name: in_gsm8k_train



