Zephyr-7B论文解析及全量训练、Lora训练

2024-02-12 03:10

本文主要是介绍Zephyr-7B论文解析及全量训练、Lora训练,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、Zephyr:Direct Distillation of LM Alignment
      • 1.1 开发经过
        • 1.1.1 Zephyr-7B-alpha
        • 1.1.2 Zephyr-7B-beta
      • 1.2 摘要
      • 1.3 相关工作
      • 1.4 算法
        • 1.4.1 蒸馏监督微调(dSFT)
        • 1.4.2 基于偏好的AI反馈 (AIF)
        • 1.4.3 直接蒸馏偏好优化(dDPO)
        • 1.4.4 训练细节
      • 1.5 实验
    • 二、alignment-handbook:低成本训练Zephyr
      • 2.1 项目简介
      • 2.2 全量训练
        • 2.2.1 环境配置
        • 2.2.2 SFT训练
        • 2.2.3 DPO训练
      • 2.3 Lora训练
      • 2.4 测试

一、Zephyr:Direct Distillation of LM Alignment

1.1 开发经过

  • 全文参参考: 《Thomas Wolf: Mistral + OpenBMB + HuggingFace 跨越三大洲的大模型开源合作故事》、《最好7B模型再易主!打败700亿LLaMA2,苹果电脑就能跑,还开源免费》
  • 资源:UltraFeedback HuggingFace、UltraFeedback Github 地址 、UltraChat HuggingFace、UltraChat Github 地址
  • 推荐:OpenBMB官网、OpenBMB GitHub、清华NLP GitHub、HuggingFaceH4
1.1.1 Zephyr-7B-alpha

  几个月前,巴黎的一个新团队发布了他们首个模型:Mistral 7B,这个模型体积小巧但性能强劲,在基准测试中的表现超过了所有同类模型,并且还是一个开源项目。

  Hugging Face H4 团队的两名成员在一次小聚中,讨论了用斯坦福大学新发表的 DPO 方法对 Mistral 7B 这个模型进行微调的可能性。随后,他们在 HF hub 上找到了一些公开的数据集,包括由面壁智能和清华大学 NLP 共同支持的 OpenBMB 开源的两个大规模、高质量的微调数据集:UltraFeedback 和 UltraChat。

  1. UltraFeedback:一个大规模、多样化、细粒度 的偏好数据集,构建过程如下:
    • 从UltraChat、ShareGPT、Evol-Instruct、TruthfulQA、FalseQA 和 FLAN等多个资源收集了约64k提示
    • 为了防止奖励模型过度拟合某些文本样式或捕获文本样式和奖励之间的虚假相关性,我们选择具有不同大小、架构和训练数据的各个级别的17个基础模型构建一个模型池,包括LLaMA、Falcon、StarChat、MPT、GPT 和 Bard等。
    • 定义了Helpfulness, Truthfulness, Honesty, Verbalized Calibration , Harmless5项原则,以从不同方面调整模型行为
    • 每条指令,随机采样 4 个模型来完成,并对每个完成的指示,我们随机采样一个原则并将其添加到系统提示中,以调整模型的行为。
    • 最终数据集包括 64k指令、256k 条对话数据以及相应的偏好标注数据、308k高质量反馈,在非社区标注的偏好数据集中,这一数据规模排在首位。对话数据中每条偏好标注均包含 instruction-following, truthfulness, honesty and helpfulness四个方面的细粒度得分与 GPT-4 的注释说明。整个数据集详细技术原理可参考其论文。
      在这里插入图片描述

基于 UltraFeedback,面壁团队还训练了奖励模型UltraRM和批评模型UltraCM来进一步辅助模型评测和模型反馈学习,更多介绍,详见《面壁智能对齐技术UltraFeedback如何让7B模型打败70B LLaMA2》

  • UltraChat: 高质量的对话数据集,包含了 150 余万条多轮指令数据。调用多个 ChatGPT API 相互对话,从而生成多轮对话数据。

  经过几轮实验证明,使用 OpenBMB 两个数据集训练出来的新模型非常强大,是 H4 团队 在伯克利和斯坦福的基准测试中见过的最强模型,并在之后被名名为 Zephyr模型。Zephyr-7B-alpha 的MT-Bench平均得分7.09 ,超越Llama2-70B-Chat。
在这里插入图片描述

  一个基于高质量数据集的 7B 模型就打败了参数十倍之大的 LLaMA2-70B-Chat,这说明底层的数据工作 才是最稀缺的和有时间价值的,这或许是各家各派大模型在 百模大战中的突破口之一。

  另外,Zephyr的效果优于 LLaMA2-70B-Chat,另外一个主要原因是使用了斯坦福大学和CZ Biohub不久前合作提出DPO方法。与传统的PPO强化学习方法不同,DPO方法舍弃了强化学习,要比PPO稳定得多。

  DPO简单解释:要想使模型的输出更加符合人类偏好,一直以来传统方法是用一个奖励模型来微调目标模型。输出得好给奖励,输出不好不给奖励。而DPO的方法绕过了建模奖励函数,相当于直接在偏好数据上优化模型,它解决了人类反馈的强化学习训练难、训练成本高的问题。

1.1.2 Zephyr-7B-beta

  开发二代模型时,他们思考了大模型所用的蒸馏监督微调(dSFT),但用这种方法模型是不对齐的,不能很好地生成符合用户意图的输出。

在这里插入图片描述
  所以团队尝试使用来自AI反馈(AI Feedback,AIF)的偏好数据,用一个“教师模型”对输出进行排名,形成一个数据集,然后应用蒸馏直接偏好优化(dDPO)来训练一个与用户意图对齐的模型,且在微调期间不需要任何额外的抽样。研究人员还测试了不用SFT的效果,结果性能大大降低,说明dSFT步骤至关重要。
在这里插入图片描述

  二代Zephyr-7B-beta,探索了从GPT-4、Claude 2中提取对齐性,然后将其注入小模型中的想法,开发出了将蒸馏直接偏好优化(dDPO)用于小模型的方法,MT-Bench平均得分升高至7.34

在这里插入图片描述
在AlpacaEval上,Zephyr胜率为90.6%,优于ChatGPT(3.5):
在这里插入图片描述

1.2 摘要

  • DPO论文《Direct Preference Optimization: Your Language Model is Secretly a Reward Model》
  • Zephyr论文《Zephyr: Direct Distillation of LM Alignment》

  本文旨在创建一个较小的语言模型,该模型能够更好地对用户意图进行对齐。

  先前的研究表明,对较大模型进行蒸馏监督微调(dSFT)可以显著提高任务准确性。然而,这些模型在自然提示下的响应不够理想。为了改善这一性质,研究者尝试使用来自AI Feedback(AIF)的偏好数据,通过使用由教师模型排名的输出数据集,应用蒸馏直接偏好优化(dDPO)来学习一个具有显著改进的意图对齐的聊天模型。

  这种方法只需要几个小时的训练,而且在微调过程中无需进行额外的采样。最终得到的Zephyr-7B在7B参数模型的聊天基准( chat benchmarks)上取得了新的最先进水平,并且无需人工标注。MT-Bench结果显示,Zephyr-7B超过了LLaMA2-70B-Chat。该系统的代码、模型、数据和教程可在alignment-handbook上找到。

1.3 相关工作

  近年来开源的大规模语言模型不断涌现,如ChatGPT之后出现的LLaMA、RedPajama-INCITE、Falcon、Llama 2、Mistral等模型,为研究社区提供了研究和应用的基础模型。随着开源模型的发展,研究人员研究从大模型中迁移知识来提升小模型性能的方法,这一趋势开始于self-instruct和Alpaca,蒸馏策略如SFT和偏好优化是其中的研究重点。

  为了跟上生成式AI的创新步伐,基准测试和评估LLM的工具也取得了长足发展,比如:

  • 使用强大的LLM(GPT-4、Claude)作为评估器,对模型输出打分或成对排名回复来判断模型的响应。
  • LMSYS chatbot arena:使用众包的方式,通过匿名随机对战来基准测试LLM。模型根据排行榜上的Elo评分进行排名。
  • AlpacaEval:类似LMSYS这种排行榜的方式,成对比较模型,但使用GPT-4和Claude等更大的LLM来替代人类进行评估
  • MTBench:使用GPT-4对不同任务类别的多轮对话进行评分(1-10分),任务类别包括推理、角色扮演、数学、编码、写作、人文、STEM和信息提取等。
  • 其它评测工具:HuggingFace Open LLM leaderbaord、Chain-of-Thought Hub、ChatEvalFastEval等。

  本文最终通过在MTBench、AlpacaEval和HuggingFace OpenLLM排行榜上的评测结果来展示Zephyr模型的效果。

Model performance on MT-Bench

1.4 算法

参考:《Zephyr-7B: Fine-Tuning and Inference with W&B》、《HuggingFace 新作:70亿打败700亿Llama 2,开源模型Zephyr-7B!MAC可跑》

论文旨在使开源大型语言模型与用户意图保持一致,如下图所示整个训练过程分为三步:

1.4.1 蒸馏监督微调(dSFT)

  dSFT(Distilled Supervised Fine-Tuning)通过高质量的指令-响应数据集来教会我们的模型对指令和提示进行响应。Zephyr没有采用传统的在指令-响应数据集上进行监督微调(SFT),而是利用教师模型来生成这些高质量的响应,从而“蒸馏”教师模型的某些能力到我们的模型中,你也可以将其看作一种伪标签法。

  假设你有一个种子提示集合 { x 1 , . . . , x j } \{x_1, ..., x_j\} {x1,...,xj},对于每个种子提示 x i  x_i xi,使用教师模型(GPT-4)对指令做出响应得到 y i y_i yi,同时基于其响应进一步提炼这个指令得到 x ^ i \hat{x}_i x^i,最终得到数据集: C = { ( x ^ i , y i ) , . . . , ( x ^ j , y j ) } C = \{(\hat{x}_i, y_i), ..., (\hat{x}_j, y_j)\} C={(x^i,yi),...,(x^j,yj)}

然后对模型进行指令调优,以优化以下方程:

π d S F T = m a x π E ( x , y ) ∼ C l o g π ( y ∣ x ) \pi_{dSFT} = \underset{\pi}{max} ~ \underset{(x, y) \sim C}{\mathbb{E}} log \pi(y|x) πdSFT=πmax (x,y)CElogπ(yx)

  • π \pi π:要优化的参数,即学生模型
  • C:教师模型生成的训练数据集,包含提炼后的提示 x ^ i \hat{x}_i x^i和响应 y i y_i yi
  • E ( x , y ) ∼ C ~ \underset{(x, y) \sim C}{\mathbb{E}}  (x,y)CE:表示从数据集C中采样 x x x y y y

  这个方程的目标是最大化学生模型生成教师模型响应的对数似然概率,即通过使学生模型模仿教师模型的响应,实现知识迁移。

1.4.2 基于偏好的AI反馈 (AIF)

  人类反馈(HF,Human feedback)可以为对齐大语言模型(LLM)提供额外的指导信号,是调整LLM的常见方法。本文使用了蒸馏,所以改为使用教师模型对其他模型生成的输出给出指导,即基于偏好的AI反馈(AIF,AI Feedback through Preferences )。说白了就是用AI反馈(教师模型)代替人类反馈。

  具体来说,参考UltraFeedback中的方法,对于每个提示 x 1 , . . . , x j x_1, ..., x_j x1,...,xj,使用4个模型(Claude、LLaMA、Falcon等)生成响应 ( y i 1 , y i 2 , y i 3 , y i 4 ) (y^1_i, y^2_i, y^3_i, y^4_i) (yi1,yi2,yi3,yi4),然后使用GPT-4作为教师模型对其给出分数 s { 1 , 2 , 3 , 4 } = π T ( ⋅ ∣ x i , y i { 1 , 2 , 3 , 4 } )  s^{\{1, 2, 3, 4\}} = \pi_{T}(\cdot|x_i, y_i^{\{1, 2, 3, 4\}}) s{1,2,3,4}=πT(xi,yi{1,2,3,4}),4 个响应中的最高分的响应称为 y w  y_w yw ,随机一个较低分数的响应称为 y l y_l yl 。这样,我们就从提示列表 { x 1 , . . . , x j } \{x_1, ..., x_j\} {x1,...,xj}中派生出AI反馈数据集 D = { ( x 1 , y 1 w , y 1 l ) , . . . , ( x j , y j w , y j l ) }  D = \{(x_1, y_1^w, y_1^l), ..., (x_j, y_j^w, y_j^l)\} D={(x1,y1w,y1l),...,(xj,yjw,yjl)},这是一个具有较强响应和较弱响应的三元组。

1.4.3 直接蒸馏偏好优化(dDPO)

  直接蒸馏偏好优化 (dDPO,Distilled direct preference optimization)的目标,是通过最大化偏好模型中响应 y w y_w yw对响应 y l y_l yl的优先排列概率,来优化经过dSFT的模型πdSFT。奖励函数由学生语言模型确定

  过去使用人工智能反馈(AI feedback)的工作主要集中在使用强化学习(RL)的方法,比如PPO(Proximal Policy Optimization),通过先训练奖励函数然后从当前策略中抽样来计算更新以优化 θ θ θ。而在DPO中,偏好模型是由奖励函数 r θ ( x , y ) r_θ(x, y) rθ(x,y) 确定的,该函数利用了学生语言模型 π θ π_θ πθ

  DPO的关键观察是用最优语言模型策略π和原始语言模型策略πdSFT,来导出最优的奖励函数。在适当选择偏好模型的情况下,他们证明对于常数β和配分函数Z,有:
r ∗ ( x , y ) = β π * ( y ∣ x ) π dSFT ( y ∣ x ) + β log ⁡ Z ( x ) r^*(x,y) = \beta \frac{\pi_{\text{*}}(y | x)} {\pi_{\text{dSFT}}(y | x)} + \beta\log Z(x) r(x,y)=βπdSFT(yx)π*(yx)+βlogZ(x)

将奖励函数插入偏好模型中,得到的目标函数如下:
π θ = m a x π E ( x , y w , y l ) ∼ D l o g σ ( β l o g π ( y w ∣ x ) π d S F T ( y w ∣ x ) − β l o g π ( y l ∣ x ) π d S F T ( y l ∣ x ) ) \pi_\theta = \underset{\pi}{max} \underset{(x, y_w, y_l)\sim D}{\mathbb{E}} log \sigma (\beta log \frac{\pi(y_w|x)}{\pi_{dSFT} (y_w|x)} - \beta log \frac{\pi(y_l|x)}{\pi_{dSFT} (y_l|x)}) πθ=πmax(x,yw,yl)DElogσ(βlogπdSFT(ywx)π(ywx)βlogπdSFT(ylx)π(ylx))

  与 RLHF 相比,DPO直接从静态偏好数据优化模型,而不需要经过训练的奖励模型。据作者称,DPO 是轻量级的并且更稳定。文中使用的方法称为 dDPO,因为数据集是从早期步骤中提取(distilled)的,利用 AI 提供的偏好标签。

  总结整个训练过程:

  1. 对LLM进行dSFT指令调整,得到模型 π d S F T \pi_{dSFT} πdSFT
  2. 参考UltraFeedback中的方法,从提示列表 { x 1 , . . . , x j } \{x_1, ..., x_j\} {x1,...,xj}中构建AI反馈数据集 D = { ( x 1 , y 1 w , y 1 l ) , . . . , ( x j , y j w , y j l ) }  D = \{(x_1, y_1^w, y_1^l), ..., (x_j, y_j^w, y_j^l)\} D={(x1,y1w,y1l),...,(xj,yjw,yjl)}
  3. 遍历每个AIF三元组 ( x i , y i w , y i l ) } (x_i, y_i^w, y_i^l)\} (xi,yiw,yil)},以实现模型的优化。
    • 计算dSFT 模型的 ( x , y w ) (x, y_w) (x,yw) ( x , y l ) (x, y_l) (x,yl) 概率(仅进行前向计算)。
    • 计算dDPO模型的 ( x , y w ) (x, y_w) (x,yw) ( x , y l ) (x, y_l) (x,yl)的概率
    • 根据目标函数计算损失,反向传播以更新参数,然后重复此过程。
1.4.4 训练细节
  • π d S F T \pi_{dSFT} πdSFT模型训练蚕食为:cosine LR scheduler,最大学习率为2e-5, warmup steps=10%,epoch=1,sequence length=2048,batch size =512。
  • DPO 模型训练蚕食为:linear LR scheduler,最大学习率为5e-7, warmup steps=10%。batch size =32,β=0.1,epoch=3。

  最终的Zephyr-7B模型是在SFT模型(训练1个epcoh)上进行权重初始化,然后进行3个epoch的DPO训练。

1.5 实验

  1. dDPO提升了在对话数据集MT-Bench 和 AlpacaEval 上的效果
    在这里插入图片描述
  2. dDPO提升了在传统任务(Academic Task)上的效果
    在这里插入图片描述
  3. 偏好优化是否必要?
    在表格3中,我们通过以四种不同方式对 Mistral 7B 进行微调,来考察对齐过程中不同步骤的影响:
    在这里插入图片描述
    • dDPO - dSFT:直接在base model上进行1个epoch的DPO训练,数据集为UltraFeedback。可以看到没有第一步SFT训练,模型无法从反馈中学习,表现糟糕。
    • dSFT1:在base model上进行1个epoch的SFT训练,数据集为UltraChat,这一步显著提高模型在两个聊天基准上的得分。
    • dSFT2:先进行dSFT1,然后在UltraFeedback数据集上接着进行1个epoch的SFT训练,模型过拟合
    • dDPO+dSFT:本文的训练策略,dSFT1之后在接着在ltraFeedback数据集上接着进行1个epoch的DPO训练,两个基准上均有显著提升。
  4. 过拟合是否会损失在下游任务上的性能
    • 一轮 DPO 训练后,模型会出现强烈的过拟合,如下图中训练集准确率的完美表现所示。但这并没有损害在 MT-Bench 和 AlpacaEval 上的下游性能。随着训练时间增加,过拟合后,效果居然更好了。研究人员认为这类似于SFT中的过拟合。
    • 如果 SFT 训练超过1 epoch,那么DPO 步骤会引起性能的退化。
    • 最佳模型经过了一轮 SFT训练,三轮DPO 的训练。
      在这里插入图片描述

二、alignment-handbook:低成本训练Zephyr

参考:《如何低成本训练一个可以超越 70B Llama2 的模型 Zephyr-7B》、项目地址《alignment-handbook》

  整个Zephyr的完整训练过程,发布在《alignment-handbook》,环境安装见项目首页。下面对训练过程进行简单介绍。

2.1 项目简介

整个训练过程分两步:

  1. SFT训练:使用 UltraChat 数据集对 Mistral 7B 模型进行SFT训练。
    对于 SFT 训练,我们使用了 UltraChat 数据集,它包含了约 1.6M个 由 GPT3.5 生成的对话。我们最初是在所有数据上进行训练的,但后来发现训练出来的模型性格有点让人讨厌 。因此,我们筛选出了大约 200K 个更有帮助的例子进行训练,筛选后的数据集为ultrachat_200k。
  2. DPO微调:使用UltraFeedback 数据集的预处理版本,对SFT模型进行DPO(直接偏好优化)微调,将其与AI反馈(AI feedback)对齐。
    UltraFeedback 数据集涵盖了各种模型范围。每个回答都由 GPT-4 根据有益性等标准进行了评分,以此来推导 AI 的偏好。一个有趣的发现是,在用DPO的方法时,随着训练时间增加,过拟合后,效果居然更好了。研究人员认为这类似于SFT中的过拟合。

  另外,在所有实验中都使用了 TRL 和 DeepSpeed ZeRO-3:SFTTrainer、DPOTrainer,总计算成本:$500 或在16 x A100 上运行 8 小时,体验demo:zephyr-chat。

  评估方法:我们使用了 LMSYS 提供的优秀工具 MT Bench。这个多轮的基准测试可以评估聊天机器人在创意写作、编码和数学等各个领域的能力。相比其他排行榜,它能提供更准确的关于聊天机器人性能的信息。

最终,项目提供了两种训练方式:

  • Zephyr-7B完整训练:因为是全量训练,所以开启了deepspeed ZERO stage3,环境配置见recipes/accelerate_configs/deepspeed_zero3.yaml。

    # Step 1 - SFT
    ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/deepspeed_zero3.yaml scripts/run_sft.py recipes/zephyr-7b-beta/sft/config_full.yaml# Step 2 - DPO
    ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/deepspeed_zero3.yaml scripts/run_dpo.py recipes/zephyr-7b-beta/dpo/config_full.yaml
    
  • Zephyr-7B LoRA训练:微调不需要开启deepspeed,环境配置见recipes/accelerate_configs/multi_gpu.yaml。

    # Step 1 - SFT
    ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/multi_gpu.yaml --num_processes=1 scripts/run_sft.py recipes/zephyr-7b-beta/sft/config_lora.yaml# Step 2 - DPO
    ACCELERATE_LOG_LEVEL=info accelerate launch --config_file recipes/accelerate_configs/multi_gpu.yaml --num_processes=1 scripts/run_dpo.py recipes/zephyr-7b-beta/dpo/config_lora.yaml
    

下面给出训练代码,今天写笔记太累了,还没有跑,有空再补吧。

2.2 全量训练

2.2.1 环境配置

配置文件为recipes/accelerate_configs/deepspeed_zero3.yaml

compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:deepspeed_multinode_launcher: standardoffload_optimizer_device: noneoffload_param_device: nonezero3_init_flag: truezero3_save_16bit_model: truezero_stage: 3
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_training_function: main
mixed_precision: bf16
num_machines: 1
num_processes: 8
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
2.2.2 SFT训练
  1. 模型配置文件为 recipes/zephyr-7b-beta/sft/config_full.yaml
# Model arguments
model_name_or_path: mistralai/Mistral-7B-v0.1
model_revision: main
torch_dtype: bfloat16
use_flash_attention_2: true# Data training arguments
dataset_mixer:HuggingFaceH4/ultrachat_200k: 1.0
dataset_splits:
- train_sft
- test_sft
preprocessing_num_workers: 12# SFT trainer config
bf16: true
do_eval: true
evaluation_strategy: epoch
gradient_accumulation_steps: 2
gradient_checkpointing: true
hub_model_id: zephyr-7b-sft-full
hub_strategy: every_save
learning_rate: 2.0e-05
log_level: info
logging_steps: 5  
logging_strategy: steps
lr_scheduler_type: cosine
max_seq_length: 2048
max_steps: -1
num_train_epochs: 1
output_dir: data/zephyr-7b-sft-full
overwrite_output_dir: true
per_device_eval_batch_size: 16
per_device_train_batch_size: 32
push_to_hub: true
remove_unused_columns: true
report_to:
- tensorboard
save_strategy: "no"
save_total_limit: null
seed: 42
tf32: true
  1. SFT训练代码见scripts/run_sft.py
#!/usr/bin/env python
# coding=utf-8
# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Supervised fine-tuning script for decoder language models.
"""import logging
import random
import sysimport datasets
import torch
import transformers
from transformers import set_seedfrom accelerate import Accelerator
from alignment import (DataArguments,H4ArgumentParser,ModelArguments,SFTConfig,apply_chat_template,get_datasets,get_kbit_device_map,get_peft_config,get_quantization_config,get_tokenizer,
)
from trl import SFTTrainerlogger = logging.getLogger(__name__)def main():parser = H4ArgumentParser((ModelArguments, DataArguments, SFTConfig))model_args, data_args, training_args = parser.parse()# Set seed for reproducibilityset_seed(training_args.seed)accelerator = Accelerator()################ Setup logging###############logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%Y-%m-%d %H:%M:%S",handlers=[logging.StreamHandler(sys.stdout)],)log_level = training_args.get_process_log_level()logger.setLevel(log_level)datasets.utils.logging.set_verbosity(log_level)transformers.utils.logging.set_verbosity(log_level)transformers.utils.logging.enable_default_handler()transformers.utils.logging.enable_explicit_format()# Log on each process a small summarylogger.warning(f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"+ f" distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}")logger.info(f"Model parameters {model_args}")logger.info(f"Data parameters {data_args}")logger.info(f"Training/evaluation parameters {training_args}")################ Load datasets###############raw_datasets = get_datasets(data_args, splits=data_args.dataset_splits)logger.info(f"Training on the following datasets and their proportions: {[split + ' : ' + str(dset.num_rows) for split, dset in raw_datasets.items()]}")################# Load tokenizer################tokenizer = get_tokenizer(model_args, data_args)###################### Apply chat template#####################raw_datasets = raw_datasets.map(apply_chat_template, fn_kwargs={"tokenizer": tokenizer, "task": "sft"})train_dataset = raw_datasets["train"]eval_dataset = raw_datasets["test"]with training_args.main_process_first(desc="Log a few random samples from the processed training set"):for index in random.sample(range(len(raw_datasets["train"])), 3):logger.info(f"Sample {index} of the processed training set:\n\n{raw_datasets['train'][index]['text']}")######################## Load pretrained model#######################logger.info("*** Load pretrained model ***")torch_dtype = (model_args.torch_dtype if model_args.torch_dtype in ["auto", None] else getattr(torch, model_args.torch_dtype))model_kwargs = dict(revision=model_args.model_revision,trust_remote_code=model_args.trust_remote_code,use_flash_attention_2=model_args.use_flash_attention_2,torch_dtype=torch_dtype,use_cache=False if training_args.gradient_checkpointing else True,device_map=get_kbit_device_map(),quantization_config=get_quantization_config(model_args),)logger.info("*** Model loaded! ***")######################### Initialize the Trainer########################trainer = SFTTrainer(model=model_args.model_name_or_path,model_init_kwargs=model_kwargs,args=training_args,train_dataset=train_dataset,eval_dataset=eval_dataset,dataset_text_field="text",max_seq_length=training_args.max_seq_length,tokenizer=tokenizer,packing=True,peft_config=get_peft_config(model_args),)################ Training loop###############logger.info("*** Train ***")train_result = trainer.train()metrics = train_result.metricsmax_train_samples = data_args.max_train_samples if data_args.max_train_samples is not None else len(train_dataset)metrics["train_samples"] = min(max_train_samples, len(train_dataset))trainer.log_metrics("train", metrics)trainer.save_metrics("train", metrics)trainer.save_state()########### Evaluate##########if training_args.do_eval:logger.info("*** Evaluate ***")metrics = trainer.evaluate()max_eval_samples = data_args.max_eval_samples if data_args.max_eval_samples is not None else len(eval_dataset)metrics["eval_samples"] = min(max_eval_samples, len(eval_dataset))trainer.log_metrics("eval", metrics)trainer.save_metrics("eval", metrics)################################### Save model and create model card##################################logger.info("*** Save model ***")trainer.save_model(training_args.output_dir)logger.info(f"Model saved to {training_args.output_dir}")# Save everything else on main processif accelerator.is_main_process:kwargs = {"finetuned_from": model_args.model_name_or_path,"dataset": list(data_args.dataset_mixer.keys()),"dataset_tags": list(data_args.dataset_mixer.keys()),"tags": ["alignment-handbook"],}trainer.create_model_card(**kwargs)# Restore k,v cache for fast inferencetrainer.model.config.use_cache = Truetrainer.model.config.save_pretrained(training_args.output_dir)if training_args.push_to_hub is True:logger.info("Pushing to hub...")trainer.push_to_hub()accelerator.wait_for_everyone()if __name__ == "__main__":main()
2.2.3 DPO训练
  1. 环境配置文件相同
  2. 模型配置文件见recipes/zephyr-7b-beta/dpo/config_full.yaml
# Model arguments
model_name_or_path: alignment-handbook/zephyr-7b-sft-full# Data training arguments
# For definitions, see: src/h4/training/config.py
dataset_mixer:HuggingFaceH4/ultrafeedback_binarized: 1.0
dataset_splits:
- train_prefs
- test_prefs
preprocessing_num_workers: 12# DPOTrainer arguments
bf16: true
beta: 0.1
do_eval: true
evaluation_strategy: steps
eval_steps: 100
gradient_accumulation_steps: 1
gradient_checkpointing: true
hub_model_id: zephyr-7b-dpo-full
learning_rate: 5.0e-7
log_level: info
logging_steps: 10
lr_scheduler_type: linear
max_length: 1024
max_prompt_length: 512
num_train_epochs: 3
optim: rmsprop
output_dir: data/zephyr-7b-dpo-full
per_device_train_batch_size: 8
per_device_eval_batch_size: 4
push_to_hub: true
save_strategy: "no"
save_total_limit: null
seed: 42
warmup_ratio: 0.1
  1. DPO训练代码见scripts/run_dpo.py
#!/usr/bin/env python
# coding=utf-8
# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import sysimport torch
import transformers
from transformers import AutoModelForCausalLM, set_seedfrom accelerate import Accelerator
from alignment import (DataArguments,DPOConfig,H4ArgumentParser,ModelArguments,apply_chat_template,get_datasets,get_kbit_device_map,get_peft_config,get_quantization_config,get_tokenizer,is_adapter_model,
)
from peft import PeftConfig, PeftModel
from trl import DPOTrainerlogger = logging.getLogger(__name__)def main():parser = H4ArgumentParser((ModelArguments, DataArguments, DPOConfig))model_args, data_args, training_args = parser.parse()######## Setup#######logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%Y-%m-%d %H:%M:%S",handlers=[logging.StreamHandler(sys.stdout)],)log_level = training_args.get_process_log_level()logger.setLevel(log_level)transformers.utils.logging.set_verbosity(log_level)transformers.utils.logging.enable_default_handler()transformers.utils.logging.enable_explicit_format()# Log on each process the small summary:logger.info(f"Model parameters {model_args}")logger.info(f"Data parameters {data_args}")logger.info(f"Training/evaluation parameters {training_args}")# Set seed for reproducibilityset_seed(training_args.seed)# Increase distributed timeout to 3h to enable push to Hub to completeaccelerator = Accelerator()################ Load datasets###############raw_datasets = get_datasets(data_args, splits=data_args.dataset_splits)logger.info(f"Training on the following splits: {[split + ' : ' + str(dset.num_rows) for split, dset in raw_datasets.items()]}")column_names = list(raw_datasets["train"].features)###################################### Load tokenizer and process datasets#####################################data_args.truncation_side = "left"  # Truncate from left to ensure we don't lose labels in final turntokenizer = get_tokenizer(model_args, data_args)###################### Apply chat template#####################raw_datasets = raw_datasets.map(apply_chat_template,fn_kwargs={"tokenizer": tokenizer, "task": "dpo"},num_proc=data_args.preprocessing_num_workers,remove_columns=column_names,desc="Formatting comparisons with prompt template",)# Replace column names with what TRL needs, text_chosen -> chosen and text_rejected -> rejectedfor split in ["train", "test"]:raw_datasets[split] = raw_datasets[split].rename_columns({"text_prompt": "prompt", "text_chosen": "chosen", "text_rejected": "rejected"})torch_dtype = (model_args.torch_dtype if model_args.torch_dtype in ["auto", None] else getattr(torch, model_args.torch_dtype))model_kwargs = dict(revision=model_args.model_revision,trust_remote_code=model_args.trust_remote_code,use_flash_attention_2=model_args.use_flash_attention_2,torch_dtype=torch_dtype,use_cache=False if training_args.gradient_checkpointing else True,device_map=get_kbit_device_map(),quantization_config=get_quantization_config(model_args),)model = model_args.model_name_or_pathif is_adapter_model(model, model_args.model_revision):# load the model, merge the adapter weights and unload the adapter# Note: to run QLora, you will need to merge the based model separately as the merged model in 16bitlogger.info(f"Merging peft adapters for {model_args.model_name_or_path=}")peft_config = PeftConfig.from_pretrained(model_args.model_name_or_path, revision=model_args.model_revision)model_kwargs = dict(revision=model_args.base_model_revision,trust_remote_code=model_args.trust_remote_code,use_flash_attention_2=model_args.use_flash_attention_2,torch_dtype=torch_dtype,use_cache=False if training_args.gradient_checkpointing else True,)base_model = AutoModelForCausalLM.from_pretrained(peft_config.base_model_name_or_path,**model_kwargs,)model = PeftModel.from_pretrained(base_model, model_args.model_name_or_path, revision=model_args.model_revision)model.eval()model = model.merge_and_unload()model_kwargs = Noneref_model = modelref_model_kwargs = model_kwargsif model_args.use_peft is True:ref_model = Noneref_model_kwargs = None########################## Instantiate DPO trainer#########################dpo_trainer = DPOTrainer(model,ref_model,model_init_kwargs=model_kwargs,ref_model_init_kwargs=ref_model_kwargs,args=training_args,beta=training_args.beta,train_dataset=raw_datasets["train"],eval_dataset=raw_datasets["test"],tokenizer=tokenizer,max_length=training_args.max_length,max_prompt_length=training_args.max_prompt_length,peft_config=get_peft_config(model_args),)################ Training loop###############train_result = dpo_trainer.train()metrics = train_result.metricsmax_train_samples = (data_args.max_train_samples if data_args.max_train_samples is not None else len(raw_datasets["train"]))metrics["train_samples"] = min(max_train_samples, len(raw_datasets["train"]))dpo_trainer.log_metrics("train", metrics)dpo_trainer.save_metrics("train", metrics)dpo_trainer.save_state()logger.info("*** Training complete ***")########### Evaluate##########if training_args.do_eval:logger.info("*** Evaluate ***")metrics = dpo_trainer.evaluate()max_eval_samples = (data_args.max_eval_samples if data_args.max_eval_samples is not None else len(raw_datasets["test"]))metrics["eval_samples"] = min(max_eval_samples, len(raw_datasets["test"]))dpo_trainer.log_metrics("eval", metrics)dpo_trainer.save_metrics("eval", metrics)################################### Save model and create model card##################################dpo_trainer.save_model(training_args.output_dir)# Save everything else on main processif accelerator.is_main_process:kwargs = {"finetuned_from": model_args.model_name_or_path,"dataset": list(data_args.dataset_mixer.keys()),"dataset_tags": list(data_args.dataset_mixer.keys()),"tags": ["alignment-handbook"],}dpo_trainer.create_model_card(**kwargs)# Restore k,v cache for fast inferencedpo_trainer.model.config.use_cache = Truedpo_trainer.model.config.save_pretrained(training_args.output_dir)if training_args.push_to_hub is True:dpo_trainer.push_to_hub()# Ensure we don't timeout on model save / push to Hublogger.info("*** Waiting for all processes to finish ***")accelerator.wait_for_everyone()logger.info("*** Run complete! ***")if __name__ == "__main__":main()

2.3 Lora训练

  Lora训练时的训练代码和模型配置文件与全量训练时完全相同,只是环境配置不一样。因为只是微调,不需要开启ZERO stage3,所以环境配置为recipes/accelerate_configs/multi_gpu.yaml

compute_environment: LOCAL_MACHINE
debug: false
distributed_type: MULTI_GPU
downcast_bf16: 'no'
gpu_ids: all
machine_rank: 0
main_training_function: main
mixed_precision: bf16
num_machines: 1
num_processes: 8
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false

2.4 测试

  测试部分见alignment-handbook项目下的test文件夹,作者还没有上传相关说明文件,大家可以继续跟踪相关进度。

这篇关于Zephyr-7B论文解析及全量训练、Lora训练的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/701534

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

AI hospital 论文Idea

一、Benchmarking Large Language Models on Communicative Medical Coaching: A Dataset and a Novel System论文地址含代码 大多数现有模型和工具主要迎合以患者为中心的服务。这项工作深入探讨了LLMs在提高医疗专业人员的沟通能力。目标是构建一个模拟实践环境,人类医生(即医学学习者)可以在其中与患者代理进行医学

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX