微信扫码
与创始人交个朋友
我要投稿
ORPO是一种令人兴奋的新型微调技术,它将传统的监督微调与偏好对齐阶段结合成一个单一的过程。这样可以减少训练所需的计算资源和时间。此外,实证结果表明,ORPO在不同的模型大小和基准测试中都优于其他对齐方法。
在这篇文章中,我们将使用ORPO技术对新的Llama 3 8B模型进行微调,使用TRL库。代码可以在Google Colab上找到,也可以在GitHub上的LLM课程中找到。
⚖️ ORPO 指令微调和偏好对齐是适应大型语言模型(LLMs)到特定任务的关键技术。传统上,这涉及到一个多阶段过程:1/ 通过监督微调(SFT)来适应目标领域的模型,然后2/ 通过强化学习与人反馈(RLHF)或直接偏好优化(DPO)等偏好对齐方法来增加生成首选响应而非被拒绝响应的可能性。
然而,研究人员已经发现了这种方法的一个局限性。虽然监督微调(SFT)有效地使模型适应了期望的领域,但它无意中增加了生成不良答案以及首选答案的概率。这就是为什么偏好对齐阶段是必要的,它用于扩大首选输出和被拒绝输出之间的可能性差距。
由Hong和Lee于2024年提出的ORPO,通过将指令微调和偏好对齐结合到一个单一的、整体的训练过程中,为这个问题提供了一个优雅的解决方案。ORPO修改了标准的 language modeling 目标,将负对数似然损失与一个赔率比(OR)项结合起来。这个OR损失轻微地惩罚被拒绝的响应,同时强烈地奖励首选的响应,允许模型同时学习目标任务并与人类偏好对齐。
ORPO已经在主要的微调库中实现,如TRL、Axolotl和LLaMA-Factory。在下一节中,我们将看到如何使用TRL。
? 使用ORPO微调Llama 3 Llama 3是Meta开发的最新大型语言模型(LLMs)系列。这些模型是在包含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需要一个偏好数据集,包括一个提示、一个被选择的答案和一个被拒绝的答案。在这个例子中,我们将使用mlabonne/orpo-dpo-mix-40k,这是以下高质量DPO数据集的组合:
argilla/distilabel-capybara-dpo-7k-binarized:高分被选答案 >=5(2882个样本)
argilla/distilabel-intel-orca-dpo-pairs:高分被选答案 >=9,不在GSM8K中(2299个样本)
argilla/ultrafeedback-binarized-preferences-cleaned:高分被选答案 >=5(22799个样本)
argilla/distilabel-math-preference-dpo:高分被选答案 >=9(2181个样本)
unalignment/toxic-dpo-v0.2(541个样本)
M4-ai/prm_dpo_pairs_cleaned(7958个样本)
jondurbin/truthy-dpo-v0.1(1016个样本)
感谢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-attnattn_implementation = "flash_attention_2"torch_dtype = torch.bfloat16else:attn_implementation = "eager"torch_dtype = torch.float16
在以下内容中,我们将加载Llama 3 8B模型,并利用bitsandbytes以4位精度进行设置。然后我们使用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格式。请注意,我只使用了1000个样本,而不是整个数据集,因为运行整个数据集会花费太长时间。
dataset_name = "mlabonne/orpo-dpo-mix-40k"
dataset = load_dataset(dataset_name, split="all")
dataset = dataset.shuffle(seed=42).select(range(1000))
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)
首先,我们需要设置一些超参数:
学习率:与传统的监督微调(SFT)甚至直接偏好优化(DPO)相比,ORPO使用非常低的学习率。这个值8e-6来自原始论文,大致对应于SFT的学习率为1e-5和DPO的学习率为5e-6。对于真正的微调,我建议将其增加到大约1e-6。
beta:它是论文中的λ参数,默认值为0.1。原始论文的一个附录展示了如何通过消融研究选择它。
其他参数,如max_length和batch size,设置为尽可能多地使用VRAM(在这个配置中约为20 GB)。理想情况下,我们会训练模型3-5个时代,但我们这里只坚持1个。
最后,我们可以使用ORPOTrainer来训练模型,它充当一个包装器。
orpo_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)
在这些1000个样本上训练模型大约在L4 GPU上花费了2个小时。让我们检查一下W&B的图表:
虽然损失在下降,但被选择的答案和被拒绝的答案之间的差异并不明显:平均边距和准确率仅略高于零和0.5。
在原始论文中,作者们在Anthropic/hh-rlhf数据集(161k样本)上训练了模型10个时代,这比我们的快速运行要长得多。他们还尝试了Llama 3,并慷慨地与我分享了他们的日志(感谢Jiwoo Hong)。
为了结束这个教程,让我们将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曲线所突显的那样,我还是在Nous的基准测试套件上进行了一些评估,使用了LLM AutoEval。
我们的ORPO微调实际上相当不错,并在每个基准测试中提高了基础模型的性能。这是令人鼓舞的,很可能意味着在整个40k样本上进行微调会产生很好的结果。
对于开源社区来说,这是一个激动人心的时刻,越来越多高质量的开源权重模型正在发布。闭源和开源代码之间的差距正在慢慢缩小,微调是获得最佳性能以适应你的用例的关键工具。
结论 在本文中,我们介绍了ORPO算法,并解释了它如何将SFT和偏好对齐阶段统一到一个单一的过程中。然后,我们使用TRL对Llama 3 8B模型进行了微调,以适应自定义的偏好数据集。最终模型显示出鼓舞人心的结果,并突出了ORPO作为一种新的微调范式的潜力。
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2024-05-14
2024-04-26
2024-03-30
2024-04-12
2024-05-10
2024-07-18
2024-05-22
2024-05-28
2024-04-25
2024-04-26
2024-11-14
2024-11-13
2024-11-13
2024-11-13
2024-11-12
2024-11-11
2024-11-08
2024-11-07