吉游网提供最新游戏下载和手游攻略!

深度学习:ORPO 微调 Llama 3 的应用与优势

发布时间:2024-10-05浏览:26

原文地址:https://mlabonne.github.io/blog/posts/2024-04-19_Fine_tune_Llama_3_with_ORPO.html

ORPO 是一种令人兴奋的新型微调技术,它将传统的监督微调和偏好调整阶段结合到一个过程中。这减少了训练所需的计算资源和时间。此外,实证结果表明,ORPO 在各种模型大小和基准上优于其他对齐方法。

️ ORPO

指令调整和偏好对齐是使大型语言模型 (LLM) 适应特定任务的基本技术。传统上,这涉及一个多阶段过程: 1/根据指令进行监督微调(Supervised Fine-Tuning:SFT),以使模型适应目标域,然后是 2/偏好对齐方法(preference alignment methods),例如人类反馈强化学习 (RLHF) 或直接偏好优化(DPO) 以增加生成首选响应而非拒绝响应的可能性。

然而,研究人员发现了这种方法的局限性。虽然 SFT 有效地使模型适应所需的领域,但它无意中增加了在首选答案的同时生成不需要的答案的可能性。这就是为什么偏好调整阶段对于扩大首选输出和拒绝输出的可能性之间的差距是必要的。

请注意在监督微调期间拒绝响应的概率如何增加(来自 ORPO 论文)。

由Hong 和 Lee (2024)提出的ORPO 通过将指令调整和偏好对齐结合到一个单一的整体训练过程中,为这个问题提供了一个优雅的解决方案。ORPO 修改了标准语言建模目标,将负对数似然损失与优势比 (OR) 项相结合。这种 OR 损失对被拒绝的响应进行弱惩罚,同时对首选响应进行强烈奖励,从而使模型能够同时学习目标任务并与人类偏好保持一致。

ORPO 已在主要微调库中实现,例如TRL、Axolotl和LLaMA-Factory。在下一节中,我们将了解如何与 TRL 一起使用。

使用 ORPO 微调 Llama 3

Llama 3是 Meta 开发的最新LLM系列。这些模型在包​含15 万亿个Token的广泛数据集上进行训练(相比之下 Llama 2 的Token为 2T)。已发布两种模型大小:700 亿参数模型和较小的 80 亿参数模型。70B 模型已经展示了令人印象深刻的性能,在 MMLU 基准测试中得分为 82,在 HumanEval 基准测试中得分为 81.7。

Llama 3 模型还将上下文长度增加到 8,192 个令牌(Llama 2 为 4,096 个令牌),并可能通过 RoPE 扩展到 32k。此外,这些模型使用具有 128K Token词汇量的新Token生成器,将文本编码所需的令牌数量减少了 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 gcimport osimport torchimport wandbfrom datasets import load_datasetfrom google.colab import userdatafrom peft import LoraConfig, PeftModel, prepare_model_for_kbit_trainingfrom transformers import ( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, pipeline,)from trl import ORPOConfig, ORPOTrainer, setup_chat_formatwb_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.bfloat16else: attn_implementation = "eager" torch_dtype = torch.float16

接下来,我们将以 4 位精度加载 Llama 3 8B 模型,这要归功于bitsandbytes。然后,我们使用 QLoRA 的PEFT设置 LoRA 配置。我还使用方便的setup_chat_format()函数来修改模型和标记生成器以支持ChatML。它会自动应用此聊天模板,添加特殊标记,并调整模型嵌入层的大小以匹配新的词汇量。

请注意,您需要提交访问meta-llama/Meta-Llama-3-8B 的请求并登录您的 Hugging Face 帐户。或者,您可以加载模型的非控制副本,例如NousResearch/Meta–Llama-3-8B。

# Modelbase_model = "meta-llama/Meta-Llama-3-8B"new_model = "OrpoLlama-3-8B"# QLoRA configbnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch_dtype, bnb_4bit_use_double_quant=True,)# LoRA configpeft_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 tokenizertokenizer = AutoTokenizer.from_pretrained(base_model)# Load modelmodel = 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()函数将“选择”和“拒绝”列转换为 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 rowdataset = 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这个值来自原始论文,大致对应于SFT学习率1e-5和DPO学习率5e-6。我建议将其增加到 1e-6 左右以进行真正的微调。* beta: 它是我我论文中的参数,默认值为0.1。原始论文的附录显示了如何通过消融研究选择它。* 其他参数(如max_length批量大小)设置为使用尽可能多的可用 VRAM(此配置中约为 20 GB)。理想情况下,我们会训练模型 3-5 个 epoch,但这里我们将坚持 1 个。

最后,我们可以使用 ORPOTrainer 来训练模型,它充当wrapper。

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)

在 L4 GPU 上对这 1,000 个样本进行模型训练大约需要 2 小时。让我们检查一下 W&B 图:

虽然损失下降,但所选答案和拒绝答案之间的差异并不明显:平均裕度和准确率分别仅略高于零和 0.5。

为了结束本教程,让我们将 QLoRA 适配器与基础模型合并并将其推送到 Hugging Face Hub。

# Flush memorydel trainer, modelgc.collect()torch.cuda.empty_cache()# Reload tokenizer and modeltokenizer = 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 modelmodel = 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 基准套件进行了一些评估.

Model

Average

AGIEval

GPT4All

TruthfulQA

Bigbench

teknium/OpenHermes-2.5-Mistral-7B

52.42

42.75

72.99

52.99

40.94

meta-llama/Meta-Llama-3-8B-Instruct

51.34

41.22

69.86

51.65

42.64

mistralai/Mistral-7B-Instruct-v0.1

49.15

33.36

67.87

55.89

39.48

mlabonne/OrpoLlama-3-8B

46.76

31.56

70.19

48.11

37.17

meta-llama/Meta-Llama-3-8B

45.42

31.1

69.95

43.91

36.7

我们的 ORPO 微调实际上相当不错,并且提高了基本模型在每个基准测试中的性能。这是令人鼓舞的,并且可能意味着对整个 40k 样本进行微调将产生很好的结果。

对于开源社区来说,这是一个激动人心的时刻,越来越多的高质量开放权重模型被发布。闭源模型和开放权重模型之间的差距正在慢慢缩小,微调是为您的用例获得最佳性能的重要工具。

用户评论

秘密

我之前一直想试试微调 Llama 3,现在看到这个教程真是太棒了!ORPO 这个方法听起来很轻量级,而且效果也好。我马上就开刷!

    有8位网友表示赞同!

南初

哇塞!这篇博文简直太赞了!我一直对 ORPO 微调感兴趣,但是一直没找到合适的入门教程。终于找到啦!感谢作者的分享!

    有5位网友表示赞同!

强辩

使用 Llama 3 的微调确实能提升模型的效果,不过我担心这个方法会不会过于复杂?毕竟我是个新手玩家...

    有18位网友表示赞同!

她的风骚姿势我学不来

Llama 3 本身就很强大,配合 ORPO 微调感觉更可以定制化了!这篇文章写的真的很详细,甚至包括了如何评估模型的结果。受益匪浅啊!

    有12位网友表示赞同!

夜晟洛

这个 ORPO 微调方法听起来很新颖,看起来确实比传统的微调方法更加高效。我会在空闲时尝试一下看看效果怎么样。

    有17位网友表示赞同!

醉枫染墨

这篇博文写的真好啊,用图示和代码都讲解得很清晰,很容易理解,而且能够详细地介绍 Llama 3 的模型结构和 ORPO 微调的过程。点赞!

    有9位网友表示赞同!

弃我者亡

我最近一直在学习自然语言处理,发现 Llama 3 的潜力真是巨大!这个 ORPO 微调方法让我对微调更加了解了,可以用来打造更个性化的模型!

    有6位网友表示赞同!

作业是老师的私生子

ORPO 微调的这种思路很有创新性,能够根据具体任务自定义微调参数。我期待看到更多关于 ORPO 应用的研究成果!

    有20位网友表示赞同!

我家的爱豆是怪比i

虽然 Llama 3 已经很厉害了,但我觉得即使用了 ORPO 微调,要想达到完美的效果可能还是需要更多的训练数据和更精细的调参呢。

    有14位网友表示赞同!

笑叹尘世美

这个教程太适合我了!之前想尝试微调 Llama 3 但没有找到合适的资源。这篇文章详细讲解了步骤,还有代码示例,我迫不及待想要试试看!

    有15位网友表示赞同!

君临臣

我对 ORPO 微调方法印象很深刻,它的高效性和灵活性非常吸引人。希望以后这种方法能够应用到更多领域!

    有13位网友表示赞同!

爱到伤肺i

这篇博文写的太棒啦!终于不用再看那些枯燥乏味的论文了,直接上手操作,这简直是自然语言处理学者的福音啊!

    有11位网友表示赞同!

青楼买醉

微调 Llama 3 需要一定的技术功底吧?我刚学习过一些基础的深度学习知识,感觉这篇博文还不太能理解...

    有20位网友表示赞同!

微信名字

对于新手来说,ORPO 微调的方法的确有点复杂。我希望有更多针对初学者的教程可以帮助我们更好地入门!

    有9位网友表示赞同!

蝶恋花╮

看了这篇文章后,我对微调 Llama 3 的信心更加增强了!感谢作者的详细讲解和实用的代码示例!我迫不及待去尝试这个 amazing 的方法啦!

    有6位网友表示赞同!

玩味

Llama 3 在文本生成方面已经表现出色,我想看看 ORPO 微调能否进一步提升它的效果,例如在问答、翻译等任务上达到更好的精度!

    有8位网友表示赞同!

淡抹丶悲伤

我对这种轻量级的微调方法非常感兴趣!希望未来会有更多关于 ORPO 的研究成果和应用案例分享出来,让我们更好地了解这个新兴的技术!

    有15位网友表示赞同!

热点资讯