作业二:奖励建模与直接偏好对齐
助教会在服务器ready左右,将这份作业对应的qwen系列代码更新至仓库中。想要在自己机器上预先尝试的同学,可以先运行opt-125m的相关代码。
本次作业重点关注基于偏好数据集的对齐方法。具体包括 奖励建模(Reward Modeling) 和 直接偏好对齐微调(Direct Preference Optimization, DPO)。
提交内容包括完整代码和实验报告。注意,如果在作业中遇到问题,先尝试自己解决或和同学讨论。环境配置可以参考代码库中README的介绍。自己实在无法解决,请在align-anything仓库中提issue/disscussion询问(详细流程会在后文介绍)。
本次作业有一定工作量,建议尽早开始做。
0. align-anything部署(20%)
预估时间:1小时。
实验材料一览
模型:PKU-Alignment/Beaver-0.5B-Instruct
数据:PKU-Alignment/Align-Anything
代码:PKU-Alignment/Align-Anything
PS: 以上材料已在课程服务器上提供,如果你不想在课程服务器上完成作业,请自行将以上材料下载至你的计算设备上。
0.0 服务器登录指南
- 在你熟悉的编译器软件,如VS Code中,配置ssh远程连接。
- 在 VS Code 中,安装 Remote - SSH 和 Jupyter 插件。
- 点击 VS Code 左侧的 Remote Explorer 选项卡,点击配置或添加按钮,效果基本相同。
配置实例:
Host homework-2
HostName www.example.com # 请将www.example.com替换为你的服务器地址
User coder # 请将coder替换为你的用户名
Port 30316 # 请将30316替换为你的端口号
IdentityFile ~/.ssh/id_rsa # 请将id_rsa替换为你的公钥文件名
- 随后点击远程资源管理器,点击homework-2建立连接,操作平台选择Linux,在确保公钥正确的情况下,即可连接远程服务器。
参考教程:https://server.51cto.com/article/684146.html
- 除VS Code外,你也可以使用命令行终端连接服务器,示例:
ssh -i ~/.ssh/id_rsa [email protected] -p 30316
0.1 代码部署指南
- 使用你的个人邮箱创建github账号,github地址为:https://github.com
- 点击PKU-Alignment/align-anything进入项目主页
- 点击网页右上角的Fork按钮
- 点击Create fork
将你fork完成的仓库克隆到服务器,随后,根据PKU-Alignment/align-anything主页中提供的安装教程完成安装。
具体的,在本课程提供的华为云服务器上,执行如下操作:
- 创建虚拟环境
conda create -n align-anything python==3.11
conda activate align-anything
- 设定环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh
- 安装依赖
pip3 install -e .[ascend]
到这一步,若中间过程没有报错,则说明环境配置成功。
助教已在服务器上下载好模型和数据集,以下内容仅供参考。
0.2 模型下载指南
Huggig Face是目前最被广泛使用的大模型开源社区。本次作业涉及的模型与数据集均已被上传至该平台。在完成后续操作前,请注册一个Hugging Face账号,并在个人设置页面获取hf_token,形如:hf_xxxxxxxxx。
注意,Hugging Face只会显示一次hf_token,请在生成hf_token后及时保存。
- huggingface-cli登陆
完成代码部署后,在虚拟环境激活的前提下,在命令行执行:
huggingface-cli login
随后终端会提示你输入hf_token,请将先前保存的内容粘贴至终端。
- huggingface-cli下载模型
在命令行执行:
huggingface-cli download --resume-download PKU-Alignment/Beaver-0.5B-Instruct --local-dir LOCAL_DIR
请在LOCAL_DIR参数处指定你希望模型保存的路径,例如/home/user/Beaver-0.5B-Instruct
0.3 数据集下载指南
与下载模型类似,下载数据集的命令为:
huggingface-cli download --repo-type dataset --resume-download PKU-Alignment/PKU-SafeRLHF-single-dimension --local-dir LOCAL_DIR --local-dir-use-symlinks False
关于网络问题,没办法使用HuggingFace,可以参考HF-Mirror设置。
1. 奖励模型实现(40%)
- 预估时间:5小时。
- 训练所需时间:2小时
- 显存占用:不超过20GB
作业目的
- 熟悉大模型微调框架的部署;
- 熟悉大语言模型奖励建模的作用,原理;
- 使用给定偏好数据集完成奖励模型的训练;
- 在提供的验证集上进行评测,并基于验证集表现进行参数调优;
算力要求
- 该部分作业需要在GPU上运行。
学习资料
以下是一些可以参考的资料:
- Align Anything: Training All-Modality Models to Follow Instructions with Language Feedback
- Training language models to follow instructions with human feedback
- Scaling Laws for Reward Model Overoptimization
- PKU-SafeRLHF: Towards Multi-Level Safety Alignment for LLMs with Human Preference
1.1 部署align-anything,训练奖励模型(30%)
1.1.1 偏好数据集键值转换(10%)
大语言模型对齐研究往往需要研究不同偏好数据集,而不同的偏好数据集往往包含不同的键值名称,因此需要完成偏好数据集的键值转换。例如,PKU-SafeRLHF偏好数据集的键值名称为:
{
"prompt": "...",
"reponse_0": "...",
"reponse_1": "...",
"better_response_id": "..."
}
而align-anything在进行奖励建模时,需要的键值名称为:
{
"better_text": "...",
"worse_text": "...",
}
align-anything提供了一套名为template的机制,位于align-anything/configs/template.py,可以完成偏好数据集的键值转换。
例如,对于PKU-SafeRLHF偏好数据集,对应的template为:
@register_template('PKUSafeRLHF')
class PKUSafeRLHF(BaseFormatter):
system_prompt: str = ''
def format_preference_sample(
self, raw_sample: dict[str, Any]
) -> tuple[list[dict[str, Any]], list[dict[str, Any]], str]:
metrics = raw_sample['better_response_id']
better_response = raw_sample[f'response_{int(metrics)}']
worse_response = raw_sample[f'response_{1-int(metrics)}']
prompt = raw_sample['prompt']
better_conversation = [
{'role': 'user', 'content': prompt},
{'role': 'assistant', 'content': better_response},
]
worse_conversation = [
{'role': 'user', 'content': prompt},
{'role': 'assistant', 'content': worse_response},
]
meta_info = {
'better_response': better_response,
'worse_response': worse_response,
}
return better_conversation, worse_conversation, meta_info
而本作业中使用的偏好数据集为Align-Anything,对应数据集的原始键值名称为:
{
"question": "...",
"response_1": "...",
"response_2": "...",
"overall_response": "...",
}
你需要实现一个名为HOMEWORK的template,并基于该template完成偏好数据集的键值转换。
1.1.2 训练奖励模型(10%)
基于上述实现好的template,使用align-anything完成奖励模型训练。
训练的脚本位于align-anything/scripts/qwen/rm.sh,而奖励模型训练的超参数位于align-anything/configs/train/text_to_text/rm.yaml。你需要在脚本中指定好初始模型路径、数据集路径以及输出路径参数。
随后,运行如下命令完成奖励模型训练:
cd align-anything/scripts
bash qwen/rm.sh
1.1.3 评测奖励模型(10%)
运行脚本以下即可完成奖励模型评测:
cd align-anything/scripts
bash qwen/rm_eval.sh
通过评测奖励模型在验证集上的表现,结合训练过程曲线,即可观察奖励模型是否存在过拟合等现象,从而完成参数调优。
1.1.4 使用奖励模型可视化偏好数据集(10%)
偏好数据集中包含chosen和rejected的response,它们对应了人类的高维偏好。请你使用一些可视化方法直观地呈现它们的差异性。例如,可以使用训练好的奖励模型进行评分后,可视化问答对的评分频率分布。
cd align-anything/scripts
bash qwen/rm_score.sh
1.2 回答问题(10%)
在你的实验报告中回答下列问题:
- 奖励建模有哪些应用?
- 奖励建模训练可能存在哪些鲁棒性问题?
- 如何缓解奖励建模的长度偏差?
- 有哪些拟合多元人类偏好的奖励建模方法?
每个问题的得分上限为5%,你可以参考以下的case决定如何在报告中回答问题:
满分case
- case_1: 高质量地回答了2个问题(回答的内容正确而丰富,有文献支撑)
- case_2: 认真地回答了3-4个问题(尽管有一些错误,但看得到你的思考)
低分case
- case_3: 使用GPT等模型生成不相关的4个答案
- case_4: 答案与其他同学存在雷同
2. DPO微调(40%)
- 预估时间:10小时。
- 训练时间:2.5小时
- 显存占用:不超过40GB
作业目的
- 理解DPO的原理,熟悉使用DPO进行微调的流程,并基于给定的偏好数据集完成模型的微调;
- 评测DPO微调模型的效果,与初始模型进行对比,理解对齐算法的作用;
- 分析DPO的局限性,并理解其局限性背后的原因;
算力要求
该部分作业需要在GPU上运行。
2.1 使用DPO微调模型(30%)
2.1.1 运行DPO微调(15%)
基于先前实现好的template,使用align-anything完成DPO模型的训练。
训练的脚本位于align-anything/scripts/qwen/dpo.sh,而DPO模型训练的超参数位于align-anything/configs/train/text_to_text/dpo.yaml。你需要在脚本中指定好初始模型路径、数据集路径以及输出路径参数。
随后,运行如下命令完成DPO模型训练:
cd align-anything/scripts
bash qwen/dpo.sh
2.1.2 评测DPO微调模型(15%)
大语言模型的训练效果评测往往是面向结果的评测。你需要实现以下操作:
- 自行完成大模型的生成脚本,以下是一个例子:
from transformers import AutoModelForCausalLM, AutoTokenizer
device = "cuda" # the device to load the model onto
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2-7B-Instruct",
torch_dtype="auto",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-7B-Instruct")
prompt = "Give me a short introduction to large language model."
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512
)
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
基于PKU-Alignment/Align-Anything数据集中的测试集,令模型在测试集上生成回复。
观察一些case,分析DPO改变了模型的何种行为,这种改变是否与偏好数据集一致。
尝试作出一些分析与可视化,例如:
- 使用奖励模型为DPO微调模型和初始模型生成的回答分别打分,并统计二者的得分差异性(脚本位于align-anything/scripts/qwen/rm_score.sh)。
- 如果DPO微调模型在测试集上的表现优于初始模型,请具体观察那些得分更高的case,并分析DPO微调模型在哪些方面做出了改进。
- 如果DPO微调模型在测试集上的表现不如初始模型,请分析原因,是DPO微调不准确,还是奖励建模不准确。
2.2 回答问题(10%)
- 从强化学习的角度,DPO是on-policy还是off-policy的,是online的还是offline的,为什么?
- DPO主要针对传统RLHF的哪个方面进行了优化,关键见解是什么?
- DPO和传统RLHF相比有哪些局限性,具体体现在哪些方面?
- 现有的研究(KTO,SimPO,ORPO等)主要从哪些方面对DPO进行优化?
每个问题的得分上限为5%,你可以参考以下的case决定如何在报告中回答问题:
满分case
- case_1: 高质量地回答了2个问题(回答的内容正确而丰富,有文献支撑)
- case_2: 认真地回答了3-4个问题(尽管有一些错误,但看得到你的思考)
低分case
- case_3: 使用GPT等模型生成不相关的4个答案
- case_4: 答案与其他同学存在雷同
2.3 学习资料
以下是一些可以参考的资料:
- Direct Preference Optimization: Your Language Model is Secretly a Reward Model
- KTO: Model Alignment as Prospect Theoretic Optimization
- A General Theoretical Paradigm to Understand Learning from Human Preferences
- SimPO: Simple Preference Optimization with a Reference-Free Reward
- Is DPO Superior to PPO for LLM Alignment? A Comprehensive Study
2.4 作业提交
需要提交的材料包括PDF发送到指定邮箱,具体要求如下:
- 以PDF为格式的实验报告(中英文形式都可,编写方式自由,可以根据个人偏好使用word或latex),PDF文件需要发送至[email protected]。
- 训练和评估过程中的可视化分析、case、以及模型生成的结果(不超过10MB),放于results文件夹中。
- 注意最后你需要提交的内容为:实验报告(pdf格式),支撑材料(文件夹),打包为压缩文件后发送至邮箱中即可。