重新格式化对齐
这是重新格式化对齐的官方仓库。
范润泽、李学锋、邹浩洋、李俊龙、何帅、陈毅涵、胡洁雯、刘鹏飞
新闻
- 2024年2月:我们在Arxiv上发布了预印本论文,ReAlign数据集,以及开发过程中的其他有用资源(任务描述、手写格式、任务分类器、训练数据和用于事实性评估的NQ数据集)。
目录
简介
我们探索了提升现有指令数据质量以更好地与人类价值观对齐的方法,提出了一种简单有效的方法,名为ReAlign(重新格式化对齐),它将指令数据的响应重新格式化为更符合预先建立的标准和收集的证据的格式。 这种方法最大限度地减少了人工标注、幻觉和扩展难度,与现有的对齐技术保持正交。 实验表明,ReAlign显著提升了大语言模型的通用对齐能力、数学推理、事实性和可读性。
令人鼓舞的是,仅仅通过重新格式化响应,而不引入任何额外数据或先进的训练技术,LLaMA-2-13B在GSM8K上的数学推理能力就可以从46.77%提高到56.63%的准确率。 此外,仅5%的ReAlign数据就可以使Alpaca数据集测量的通用对齐能力提高67%。 这项工作强调了需要进一步研究大语言模型的科学和机制可解释性。
ReAlign的基本理念是在对齐过程中重新协调人类和大语言模型的角色,利用它们的互补优势——人类表达他们的偏好,而大语言模型则根据其生成能力(例如,遵循指令的能力)重建指令,而不直接使用提炼的大语言模型知识。 通过这种协作协同,我们期望生成的指令数据不仅在上下文上更加精确,而且更贴近人类偏好。
ReAlign过程分为三个主要步骤。
第一步是标准定义,人类以自然语言的形式定义他们在各种场景中的偏好(例如,响应的首选格式)。 在本文中,我们精心定义了46种不同场景的标准。
第二步是检索增强,通过纳入额外信息扩大知识密集型任务(如开放域问答和事实验证)的知识库,从而提高响应的事实性和信息量。
最后一步是重新格式化,旨在将响应与预先建立的标准和收集的证据重新对齐,确保输出既有结构又有依据。
快速开始
设置
我们在此项目中使用python 3.10
。建议通过conda
创建虚拟环境。
然后,我们需要安装requirements.txt
中列出的所有库。请注意,你可以根据你的CUDA版本选择合适的torch
版本(我们在这个文件中写的是torch>=2.0.1+cu118
)。
pip install -r requirements.txt
流程
第1步:任务分类
从huggingface hub下载任务分类器:
模型名称 | HF检查点 | 大小 | 许可 |
---|---|---|---|
任务分类器 | 🤗 GAIR/ReAlign-Task-Classifier | 13B | Llama 2 |
然后,使用以下提示,任务分类器可以识别查询属于哪个任务:
PROMPT_INPUT_FOR_TASK_CLS: str = '''
你将收到一个用户的查询。此外,你还得到了以下一些预定义的任务:
[现有任务开始]
问题生成
故事生成
诗歌生成
电子邮件生成
数据生成
建议给予
推荐
如何生成
规划
指令重写
语言润色
释义
文本纠正
代码纠正
代码简化
信息提取
关键词提取
表格提取
标题生成
文本摘要
笔记摘要
解释代码
解释答案
文本到文本翻译
文本到代码翻译
代码到代码翻译
代码到文本翻译
开放式问答
封闭式问答
填空
事实验证
数学谜题
语言学习问题
自然语言学习导师
考试解题导师
机器学习/人工智能/语言模型导师
通用分类
排序
情感分析
代码语言分类
语言分类
主题分类
价值判断
拒绝
角色扮演
默认
[现有任务结束]
你的目标是选择最能反映这个查询的高层次意图的任务。你应该首先明确给出你的选择。你的选择应该与上面提供的任务名称之一完全匹配,不做任何修改。不要在你的选择中包含任务描述。
你的输出应该只是任务名称。
用户的查询如下:
[用户查询开始]
{input}
[用户查询结束]
任务名称:
'''
这里有一个例子:
from vllm import LLM, SamplingParams
import torch
num_gpus = torch.cuda.device_count()
model_name_or_dir = "GAIR/ReAlign-Task-Classifier" # 或存储下载模型的本地目录
llm = LLM(model=model_name_or_dir, tensor_parallel_size=num_gpus)
query = "给出三个保持健康的建议。"
input_ = PROMPT_INPUT_FOR_TASK_CLS.format(input=query)
sampling_params = SamplingParams(temperature=0.0, top_p=1.0, max_tokens=50)
outputs = llm.generate(input_, sampling_params)
task = output[0].outputs[0].text
print(task) # 应该是 `建议给予`。
# 如果分类结果不在任务列表中,将其设置为 `默认`。
第2步:准备你的数据集
将你的数据集转换为以下json格式,与ReAlign数据集相同。
这里有一个例子:
[
{
"id": 0,
"items": [
{
# 问题
"from": "human",
"value": "给出三个保持健康的建议。",
"category": "建议给予"
},
{
# 回答
"from": "gpt",
"value": "1.保持均衡饮食,确保摄入充足的水果和蔬菜。\n2. 定期锻炼,保持身体活跃和强壮。\n3. 保证充足的睡眠,并保持一致的睡眠时间表。"
}
]
}
]
第3步:使用Google搜索进行检索
设置你的Serper API密钥:
export SERPER_API_KEY=...
运行以下脚本:
python retrieval.py \
--input_data_path dataset.json \
--output_path dataset_retrieval.json \
--batch_size 10
输出文件:
dataset_retrieval.json
添加了原始检索结果。
dataset_retrieval_clean_evidence.json
添加了清理后的检索结果。
这用于ReAlign。
第4步:重新格式化
设置你的OpenAI API密钥:
export OPENAI_API_KEY=...
运行以下脚本:
python reformat.py \
--input_data_path dataset_retrieval_clean_evidence.json \
--output_directory reformat_results \
--tokenizer_path meta-llama/Llama-2-7b-chat-hf \ # 或存储下载的分词器的本地目录
--dataset_batch_id 0 \ # 十个文件中的第一个文件(从0到9)
--dataset_batch_num 10 \ # 文件总数
--openai_key <OPENAI_API_KEY> \
--top_k 2 \ # 为每个响应输出2个重新格式化的回答
--model gpt-3.5-turbo-1106 \
--temperature 0.3 \
--top_p 1 \
--target_length 4096
请注意,我们正在使用并行处理来加速,这意味着我们将同时运行dataset_batch_num
个进程进行重新格式化,每个进程需要手动指定dataset_batch_id
。
例如:
如果你将dataset_batch_num
设置为10,意味着数据集将被分成10个子数据集(10倍加速)。你应该同时运行脚本10次,每次指定dataset_batch_id
从0到9。
然后,你可以在output_directory
目录中得到dataset_batch_num
个文件。
运行以下脚本将这些文件合并成一个最终数据集:
python parallel_data_merge.py \
--input_data_path dataset_retrieval_clean_evidence.json \ # 重新格式化脚本中的<input_data_path>
--output_directory reformat_results \ # 重新格式化脚本中的<output_directory>
--final_output_path dataset_reformat.json
最后,你可以得到最终重新格式化的数据集。
步骤5:后期过滤
你可以在rewrite_data_selection.py
中组合过滤规则或自定义过滤规则。
运行以下脚本对重新格式化的数据集进行过滤:
python rewrite_data_selection.py \
--input_original_data_path dataset_retrieval_clean_evidence.json \ # 重新格式化前的数据集路径
--input_rewrite_data_path dataset_reformat.json \ # 重新格式化后的数据集路径
--output_path realign_dataset.json # 过滤后的最终数据集路径
现在,你可以得到最终的重新对齐数据集realign_dataset.json
。
ReAlign数据集
我们基于Open-Platypus、Alpaca、No Robots、GSM8K和MATH这五个数据集进行了重新格式化:
ReAlign Open-Platypus:datasets/realign_OpenPlatypus.json
ReAlign Alpaca:datasets/realign_alpaca.json
ReAlign No Robots:datasets/realign_no_robots.json
ReAlign GSM8K:datasets/realign_gsm8k.json
ReAlign MATH:datasets/realign_math.json
这些数据集也可以在🤗Hugging Face上加载:
数据集名称 | Hugging Face链接 | 大小 |
---|---|---|
ReAlign Open-Platypus | 🤗 GAIR/ReAlign-Open-Platypus | 25K |
ReAlign Alpaca | 🤗 GAIR/ReAlign-Alpaca | 52K |
ReAlign No Robots | 🤗 GAIR/ReAlign-No-Robots | 10K |
ReAlign GSM8K | 🤗 GAIR/ReAlign-GSM8K | 7.4K |
ReAlign MATH | 🤗 GAIR/ReAlign-MATH | 6.5K |
其他资源
任务描述和格式
任务描述和预定义格式可以在code/constant.py
中找到。
任务分类器的数据
任务分类器的训练数据在datasets/classification/task_classifier_train_dataset.json
中。
测试数据在datasets/classification/task_classifier_test_dataset.json
中。
格式如下:
{
"instruction": "创建一个关于狗发现魔法传送门的故事。",
"category": "story_generation"
}
事实性评估
我们从NQ数据集中随机抽样了100个案例进行事实性评估,可以在datasets/nq
中找到。
真实答案在datasets/nq/nq_factuality_100.json
中。
格式如下:
{
"items": [
{
"from": "human",
"value": "民主党什么时候改变了它的名字?"
},
{
"from": "gpt",
"value": "19世纪30年代"
}
],
"id": 0
}
引用
如果本仓库中的资源或论文对你有帮助,请引用该论文。
@article{fan2024reformatted,
title={Reformatted Alignment},
author={Fan, Run-Ze and Li, Xuefeng and Zou, Haoyang and Li, Junlong and He, Shwai and Chern, Ethan and Hu, Jiewen and Liu, Pengfei},
year={2024},
journal={arXiv preprint arXiv:2402.12219},
url={https://arxiv.org/abs/2402.12219}
}
致谢
我们感谢GAIR成员审阅我们的论文并给予宝贵的反馈。我们感谢OpenChat的作者提供训练代码库和帮助。