微信扫码
与创始人交个朋友
我要投稿
ORPO 是一种令人兴奋的全新微调技术,它将传统的监督式微调和偏好对齐阶段合并为一个单一的过程。这显著减少了训练所需的计算资源和时间。此外,实证结果表明,ORPO 在各种模型大小和基准测试中都优于其他对齐方法。
在本文中,我们将使用 TRL 库和 ORPO 对新的 Llama 3 8B 模型进行微调。代码可在 Google Colab 和 GitHub 上的 LLM 课程中找到。
ORPO 简介
指令调整和偏好对齐是使大型语言模型 (LLM) 适应特定任务的基本技术。传统上,这涉及一个多阶段过程:1)对指令进行监督式微调 (SFT),以使模型适应目标领域,然后 2)使用偏好对齐方法,如带有人类反馈的强化学习 (RLHF) 或直接偏好优化 (DPO),以增加生成偏好响应而不是拒绝响应的可能性。
然而,研究人员发现这种方法存在局限性。虽然 SFT 可以有效地使模型适应所需的领域,但它也无意中增加了生成不希望的答案以及偏好答案的可能性。这就是为什么需要偏好对齐阶段来扩大偏好输出和拒绝输出之间的可能性差距。
ORPO 由 Hong 和 Lee(2024)提出,它通过将指令调整和偏好对齐组合成一个单一的、整体的训练过程,为这个问题提供了一个优雅的解决方案。ORPO 修改了标准的语言建模目标,将负对数似然损失与优势比 (OR) 项相结合。这种 OR 损失会轻微惩罚拒绝响应,同时强烈奖励偏好响应,从而使模型能够同时学习目标任务并与人类偏好保持一致。
ORPO 已在主要的微调库中实现,如 TRL、Axolotl 和 LLaMA-Factory。在下一节中,我们将看到如何将其与 TRL 一起使用。
使用 ORPO 微调 Llama 3
Llama 3 是 Meta 开发的最新 LLM 系列。这些模型在一个包含 15 万亿个标记的庞大数据集上进行了训练(而 Llama 2 为 2 万亿个标记)。已发布两种模型大小:700 亿参数模型和较小的 80 亿参数模型。70B 模型已经展示了令人印象深刻的性能,在 MMLU 基准测试中得分 82,在 HumanEval 基准测试中得分 81.7。
Llama 3 模型还将上下文长度增加到 8,192 个标记(Llama 2 为 4,096 个标记),并有可能使用 RoPE 扩展到 32k。此外,这些模型使用了一个新的标记器,其词汇量为 128K 个标记,将编码文本所需的标记数量减少了 15%。这个词汇量也解释了参数从 7B 增加到 8B 的原因。
ORPO-DPO-mix-40k 的样本
ORPO 需要一个偏好数据集,包括一个提示、一个选择的答案和一个拒绝的答案。在这个例子中,我们将使用 mlabonne/orpo-dpo-mix-40k,它是以下高质量 DPO 数据集的组合:
argilla/distilabel-capybara-dpo-7k-binarized:高分选择的答案 >=5(2,882 个样本)
argilla/distilabel-intel-orca-dpo-pairs:高分选择的答案 >=9,不在 GSM8K 中(2,299 个样本)
argilla/ultrafeedback-binarized-preferences-cleaned:高分选择的答案 >=5(22,799 个样本)
argilla/distilabel-math-preference-dpo:高分选择的答案 >=9(2,181 个样本)
unalignment/toxic-dpo-v0.2(541 个样本)
M4-ai/prm_dpo_pairs_cleaned(7,958 个样本)
jondurbin/truthy-dpo-v0.1(1,016 个样本)
感谢 argilla、unalignment、M4-ai 和 jondurbin 提供源数据集。
像往常一样,让我们首先安装所需的库:
pip install -U transformers datasets accelerate peft trl bitsandbytes wandb
一旦安装完成,我们就可以导入必要的库并登录到 W&B(可选):
import gc
import os
import torch
import wandb
from datasets import load_dataset
from google.colab import userdata
from peft import LoraConfig, PeftModel, prepare_model_for_kbit_training
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
BitsAndBytesConfig,
TrainingArguments,
pipeline,
)
from trl import ORPOConfig, ORPOTrainer, setup_chat_format
wb_token = userdata.get('wandb')
wandb.login(key=wb_token)
如果你有一个最近的 GPU,你也可以使用 Flash Attention 库来用更有效的库替换默认的 eager attention 实现。
if torch.cuda.get_device_capability()[0] >= 8:
!pip install -qqq flash-attn
attn_implementation = "flash_attention_2"
torch_dtype = torch.bfloat16
else:
attn_implementation = "eager"
torch_dtype = torch.float16
在下面的内容中,我们将借助 bitsandbytes 以 4 位精度加载 Llama 3 8B 模型。然后,我们使用 PEFT 为 QLoRA 设置 LoRA 配置。我还使用了方便的 setup_chat_format() 函数来修改模型和标记器以支持 ChatML。它会自动应用此聊天模板,添加特殊标记,并调整模型的嵌入层大小以匹配新的词汇量大小。
请注意,您需要提交请求才能访问 meta-llama/Meta-Llama-3-8B 并登录到您的 Hugging Face 帐户。或者,您可以加载模型的非门控副本,如 NousResearch/Meta–Llama-3-8B。
# Model
base_model = "meta-llama/Meta-Llama-3-8B"
new_model = "OrpoLlama-3-8B"
# QLoRA config
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch_dtype,
bnb_4bit_use_double_quant=True,
)
# LoRA config
peft_config = LoraConfig(
r=16,
lora_alpha=32,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=['up_proj', 'down_proj', 'gate_proj', 'k_proj', 'q_proj', 'v_proj', 'o_proj']
)
# Load tokenizer
tokenizer = AutoTokenizer.from_pretrained(base_model)
# Load model
model = AutoModelForCausalLM.from_pretrained(
base_model,
quantization_config=bnb_config,
device_map="auto",
attn_implementation=attn_implementation
)
model, tokenizer = setup_chat_format(model, tokenizer)
model = prepare_model_for_kbit_training(model)
现在模型已经准备好进行训练,我们可以处理数据集了。我们加载 mlabonne/orpo-dpo-mix-40k 并使用 apply_chat_template() 函数将“chosen”和“rejected”列转换为 ChatML 格式。请注意,我仅使用 1,000 个样本,而不是整个数据集,因为运行时间太长。
dataset_name = "mlabonne/orpo-dpo-mix-40k"
dataset = load_dataset(dataset_name, split="all")
dataset = dataset.shuffle(seed=42).select(range(100))
def format_chat_template(row):
row["chosen"] = tokenizer.apply_chat_template(row["chosen"], tokenize=False)
row["rejected"] = tokenizer.apply_chat_template(row["rejected"], tokenize=False)
return row
dataset = dataset.map(
format_chat_template,
num_proc= os.cpu_count(),
)
dataset = dataset.train_test_split(test_size=0.01)
首先,我们需要设置一些超参数:
learning_rate:与传统的 SFT 甚至 DPO 相比,ORPO 使用非常低的学习率。这个 8e-6 的值来自原始论文,大致对应于 1e-5 的 SFT 学习率和 5e-6 的 DPO 学习率。我建议将其提高到 1e-6 左右进行真正的微调。
beta:它是论文中的 ? 参数,默认值为 0.1。原始论文的附录展示了如何通过消融研究来选择它。
其他参数,如 max_length 和 batch size,设置为使用尽可能多的 VRAM(在此配置中约为 20 GB)。理想情况下,我们将训练模型 3-5 个 epoch,但在这里我们将坚持 1 个。
最后,我们可以使用 ORPOTrainer 训练模型,它充当一个包装器。
rpo_args = ORPOConfig(
learning_rate=8e-6,
beta=0.1,
lr_scheduler_type="linear",
max_length=1024,
max_prompt_length=512,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=4,
optim="paged_adamw_8bit",
num_train_epochs=1,
evaluation_strategy="steps",
eval_steps=0.2,
logging_steps=1,
warmup_steps=10,
report_to="wandb",
output_dir="./results/",
)
trainer = ORPOTrainer(
model=model,
args=orpo_args,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
peft_config=peft_config,
tokenizer=tokenizer,
)
trainer.train()
trainer.save_model(new_model)
在 L4 GPU 上训练这 1,000 个样本的模型大约需要 2 个小时。让我们检查一下 W&B 图:
虽然损失下降了,但选择答案和拒绝答案之间的差异并不明显:平均边际和准确率分别略高于零和 0.5。
在原始论文中,作者在 Anthropic/hh-rlhf 数据集(161k 个样本)上训练模型 10 个 epoch,这比我们的快速运行长得多。他们还试验了 Llama 3,并 kindly 与我分享了他们的日志。
为了结束本教程,让我们将 QLoRA 适配器与基础模型合并,并将其推送到 Hugging Face Hub。
# Flush memory
del trainer, model
gc.collect()
torch.cuda.empty_cache()
# Reload tokenizer and model
tokenizer = AutoTokenizer.from_pretrained(base_model)
model = AutoModelForCausalLM.from_pretrained(
base_model,
low_cpu_mem_usage=True,
return_dict=True,
torch_dtype=torch.float16,
device_map="auto",
)
model, tokenizer = setup_chat_format(model, tokenizer)
# Merge adapter with base model
model = PeftModel.from_pretrained(model, new_model)
model = model.merge_and_unload()
model.push_to_hub(new_model, use_temp_dir=False)
tokenizer.push_to_hub(new_model, use_temp_dir=False)
恭喜,我们完成了对 Llama 3 的快速微调:mlabonne/OrpoLlama-3-8B。你可以使用这个 Hugging Face Space 来玩它(这里有一个笔记本可以让你自己制作)。虽然模型训练不足,正如 W&B 曲线所强调的那样,但我使用 LLM AutoEval 在 Nous 的基准套件上进行了一些评估。
我们的 ORPO 微调实际上相当不错,并且在每个基准测试中都提高了基础模型的性能。这是令人鼓舞的,并且可能意味着对整个 40k 样本的微调会产生很好的结果。
对于开源社区来说,这是一个激动人心的时刻,越来越多的高质量开源权重模型正在发布。闭源模型和开源权重模型之间的差距正在慢慢缩小,而微调是为您的用例获得最佳性能的基本工具。
结论
在本文中,我们介绍了 ORPO 算法,并解释了它如何将 SFT 和偏好对齐阶段统一为一个单一的过程。然后,我们使用 TRL 在自定义偏好数据集上微调 Llama 3 8B 模型。最终模型显示了令人鼓舞的结果,并突出了 ORPO 作为一种新的微调范例的潜力。
我希望这篇文章对您有所帮助,我建议您运行 Colab 笔记本来微调您自己的 Llama 3 模型。在以后的文章中,我们将看到如何创建高质量的数据集——这一点经常被忽视。
原文:
https://mlabonne.github.io/blog/posts/2024-04-19_Fine_tune_Llama_3_with_ORPO.html
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-05-14
2024-04-26
2024-03-30
2024-04-12
2024-05-10
2024-07-18
2024-05-28
2024-05-22
2024-04-25
2024-04-26
2024-11-22
2024-11-22
2024-11-21
2024-11-20
2024-11-19
2024-11-18
2024-11-18
2024-11-16